HIDE NAV

Microcontroller Unit Lab 2

H-Bridge Motor Controller Code Library

with Hardware Pulse Width Modulation Speed Control



Summary

The h_motor.h and h_motor.c files descibed below provide reusable access to multiple h-bridge motors with easy setup.


h_motor.h


/** 
 * h-bridge driven motor library for hardware pwm 
 * throttled h-bridge motors
 * 
 * .h file (header) contains
 *    -library dependandcy includes
 *    -constants used by library
 *    -data structures
 *    -data type definitions
 *    -function prototypes
*/
#include "pico/stdlib.h"
#include "hardware/pwm.h"

#define PWM_WRAP_COUNT 6000

struct H_Motor{
    uint fwd_pin;
    uint rev_pin;
    float current_throttle;
    int mode;   //-1 = rev.  0 = stop, 1 = fwd
};

typedef struct H_Motor H_Motor;

void H_Motor_setup(H_Motor *m, uint forward_pin, uint reverse_pin);

void H_Motor_stop(H_Motor *m);

void H_Motor_fwd(H_Motor *m, float duty);

void H_Motor_rev(H_Motor *m, float duty);


h_motor.c


/** 
 * h-bridge driven motor library for hardware pwm 
 * throttled h-bridge motors
 * 
 * .c file (source) contains
 *    -include its own header
 *    -assign values of global vars (externs)
 *    -function implementations
*/
#include "h_motor.h"

void H_Motor_setup(H_Motor *m, uint forward_pin, uint reverse_pin){
    m->fwd_pin = forward_pin;
    m->rev_pin = reverse_pin;
    m->current_throttle = 0;
    m->mode = 0;

    //pin setup for forward for THIS motor, m
    gpio_set_function(m->fwd_pin, GPIO_FUNC_PWM);
    uint f_slice_no = pwm_gpio_to_slice_num(m->fwd_pin);
    pwm_set_enabled(f_slice_no, true);
	pwm_set_wrap(f_slice_no, PWM_WRAP_COUNT);

    //pin setup for forward for THIS motor, m
    gpio_set_function(m->rev_pin, GPIO_FUNC_PWM);
    uint r_slice_no = pwm_gpio_to_slice_num(m->rev_pin);
    pwm_set_enabled(r_slice_no, true);
	pwm_set_wrap(r_slice_no, PWM_WRAP_COUNT);
}

void H_Motor_stop(H_Motor *m){
    pwm_set_gpio_level(m->fwd_pin, 0);
    pwm_set_gpio_level(m->rev_pin, 0);
    m->mode = 0;
    m->current_throttle = 0;
}

void H_Motor_fwd(H_Motor *m, float duty){
    if(duty > 1.0f) duty = 1.0f;
    if(duty < 0) duty = 0;
    uint level = PWM_WRAP_COUNT * duty;
    pwm_set_gpio_level(m->rev_pin, 0);
    pwm_set_gpio_level(m->fwd_pin, level);
    m->mode = 1;
    m->current_throttle = duty;
}

void H_Motor_rev(H_Motor *m, float duty){
    if(duty > 1.0f) duty = 1.0f;
    if(duty < 0) duty = 0;
    uint level = PWM_WRAP_COUNT * duty;
    pwm_set_gpio_level(m->fwd_pin, 0);
    pwm_set_gpio_level(m->rev_pin, level);
    m->mode = -1;
    m->current_throttle = duty;
}

main.c


#include "pico/stdlib.h"
#include "h_motor.h"

#define delay_ms 1000

int main() {
        // setup &  initialize
        H_Motor motor_1;
        H_Motor_setup(&motor_1, 14, 15);


        // primary loop
	while (true) {
		//stopping a motor
		H_Motor_stop(&motor_1);
		sleep_ms(delay_ms);
		//set fwd on a motor 75%
		H_Motor_fwd(&motor_1, .75);
		sleep_ms(delay_ms);
		//set fwd on a motor 100%
		H_Motor_fwd(&motor_1, 1.0);
		sleep_ms(delay_ms);
		//stopping a motor
		H_Motor_stop(&motor_1);
		sleep_ms(delay_ms);
		//reverse it at 90%
		H_Motor_rev(&motor_1, .90);
		sleep_ms(delay_ms);
	}
}