2017年4月15日 星期六

nrf52: Use PWM to control DC motor rotate speed.

DC motor rotate speed is directly proportional  to supply voltage and current. But it is very difficult to use software to control supply voltage and current . So use on/off time to control the DC motor is a better solution.

In my project I use TI DRV8837  to driver. DRV8837  has H-bridge structure to control motor forward/reverse rotate. So just simply add pwm input to DRV8837 then we can control the DC motor rotate speed.

1.Connect three gpio to DRV8837 nSleep , IN1 , IN2 .
#define MOTOR_nSLEEP (5)
#define MOTOR_IN1 (6)
#define MOTOR_IN2 (7)
void motor_init()
{
nrf_gpio_cfg_output(MOTOR_nSLEEP);
nrf_gpio_cfg_output(MOTOR_IN1);
nrf_gpio_cfg_output(MOTOR_IN2);
nrf_gpio_pin_set(MOTOR_nSLEEP);
}/*motor_init*/
view raw gistfile1.txt hosted with ❤ by GitHub


2.Config PWM module and connect to IN1,IN2.   
#define MOTOR_UP (1)
#define MOTOR_DOWN (0)
uint32_t motor_pwm_power_rate_spin(uint8_t direction, uint8_t power_rate)
{
uint32_t err_code;
if(MOTOR_DOWN == direction)
{
app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(5000L, MOTOR_IN1);
pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
nrf_gpio_cfg_output(MOTOR_IN2);
nrf_gpio_pin_clear(MOTOR_IN2);
err_code = app_pwm_init(&PWM1, &pwm1_cfg, NULL);
if(NRF_SUCCESS != err_code)
return err_code;
}
else if(MOTOR_UP == direction)
{
app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(5000L, MOTOR_IN2);
pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
nrf_gpio_cfg_output(MOTOR_IN1);
nrf_gpio_pin_clear(MOTOR_IN1);
err_code = app_pwm_init(&PWM1, &pwm1_cfg, NULL);
if(NRF_SUCCESS != err_code)
return err_code;
}/*if*/
app_pwm_enable(&PWM1);
nrf_gpio_cfg_output(MOTOR_nSLEEP);
nrf_gpio_pin_set(MOTOR_nSLEEP);
while(NRF_ERROR_BUSY == app_pwm_channel_duty_set(&PWM1, 0, power_rate));
return NRF_SUCCESS;
}/*motor_pwm_power_rate_spin*/
view raw gistfile1.txt hosted with ❤ by GitHub


3.Now we can control DC motor rotate speed from 0 to 100% and rotate forward/reverse.
#define DUTY (50)
uint32_t err_code;
err_code = motor_power_rate_spin(MOTOR_DOWN, DUTY);
view raw gistfile1.txt hosted with ❤ by GitHub




NOTICE!: It very danger when motor change rotate direction because it will shortly to turn both side H-bridge ON.It will need a short dead zone to prevent this situation.Luckily DRV8837 has build- in protection function when both IN1 IN2 are high the output will be low to stop the motor.

Ref:
     1. DRV883x datasheet 
     2. H-bridge
        

沒有留言:

張貼留言

Linux driver: How to enable dynamic debug at booting time for built-in driver.

 Dynamic debug is useful for debug driver, and can be enable by: 1. Mount debug fs #>mount -t debugfs none /sys/kernel/debug 2. Enable dy...