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);
}
}