Example Code for Arduino-PWM mode drives the motor
The article explains how to use PWM mode to drive motors with Arduino, detailing hardware and software preparation, a truth table for PWM control, and sample code for implementation. It covers initializing pins, configuring mcpwm, and controlling motor speed, making it an invaluable resource for enthusiasts seeking to optimize motor functions.
Hardware Preparation
Software Preparation
- Download Arduino IDE: Click to download Arduino IDE
- Add ESP32 board to Arduino IDE
PWM mode drives the motor
Truth table of PWM control mode
| IN1 | IN2 | OUT1 | OUT2 | explain |
|---|---|---|---|---|
| 0 | 0 | Hi-Z | Hi-Z | Taxiing (H-bridge high impedance) |
| 0 | 1 | L | H | retreat (OUT2 → OUT1) |
| 1 | 0 | H | L | advance (OUT1 → OUT2) |
| 1 | 1 | L | L | Braking (low side slow attenuation) |
Sample Code
/**
*@brief motorSpeeddetectionbyPWM.ino
*@ Motor driver in PWM mode
*/
#include "driver/mcpwm.h"
#include "soc/mcpwm_struct.h"
#include "soc/mcpwm_reg.h"
//IO12->M1_IN1
//IO13->M1_IN2
#define MOTOR_PWM_IN1 12
#define MOTOR_PWM_IN2 13
//Initialize the pins needed to generate the PWM signal
void mcpwm_init(void)
{
// Binding needs to output the PWM pin to the PWM channel
mcpwm_gpio_init(MCPWM_UNIT_0,MCPWM0A,MOTOR_PWM_IN1);
mcpwm_gpio_init(MCPWM_UNIT_0,MCPWM0B,MOTOR_PWM_IN2);
//Configure mcpwm information
mcpwm_config_t pwm_config;
pwm_config.frequency = 1000;/*!<Set frequency of MCPWM in Hz*/
pwm_config.cmpr_a = 0;/*!<Set % duty cycle for operator a(MCPWMXA), i.e for 62.3% duty cycle, duty_a = 62.3*/
pwm_config.cmpr_b = 0;/*!<Set % duty cycle for operator b(MCPWMXB), i.e for 48% duty cycle, duty_b = 48.0*/
pwm_config.counter_mode/*!<Set type of MCPWM counter*/ = MCPWM_UP_COUNTER/*!<For asymmetric MCPWM*/;
pwm_config.duty_mode/*!<Set type of duty cycle*/ = MCPWM_DUTY_MODE_0/*!<Active high duty, i.e. duty cycle proportional to high time for asymmetric MCPWM*/;
//Initialize a unit of mcpwm and bind the clock
mcpwm_init(MCPWM_UNIT_0,MCPWM_TIMER_0,&pwm_config);
}
void advance(/*range:0~100*/uint8_t speed)
{
mcpwm_set_duty_type(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_A,MCPWM_DUTY_MODE_0);
mcpwm_set_signal_low(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_B);
mcpwm_set_duty(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_A,speed);
}
void retreat(/*range:0~100*/uint8_t speed)
{
//Give MOTOR_DIRECTION_PIN a continuous low level
mcpwm_set_signal_low(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_A);
/*
* Call function mcpwm_set_duty_type() every time after mcpwm_set_signal_high()
* or mcpwm_set_signal_low() to resume with previously set duty cycle.
*/
mcpwm_set_duty_type(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_B,MCPWM_DUTY_MODE_0);
//The MOTOR_STEP_PIN pin outputs a PWM wave with a duty cycle of "speed"
mcpwm_set_duty(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_B,speed);
}
void stop(void)
{
mcpwm_set_signal_low(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_A);
mcpwm_set_signal_low(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_B);
}
void breake(void)
{
mcpwm_set_signal_high(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_A);
mcpwm_set_signal_high(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_B);
}
void setup() {
mcpwm_init();
}
void loop() {
advance(30);
delay(2000);
retreat(60);
delay(2000);
stop();
delay(2000);
advance(30);
delay(2000);
retreat(60);
delay(2000);
breake();
delay(2000);
}
Was this article helpful?
