0

PWM example for ML-R Motor Driver 4x3.6A (mrm-mot4x3.6)

Prerequisites

If not already done so already, install Arduino software and make basic connections, as described in page for MRMS ESP32: Arduino, IMU, eFuse, BT, WiFi, CAN Bus (mrm-esp32).

Task

PWM control is a native method for almost any motor driver. It is implemented by using a (full) H bridge, which accepts PWM signal. Some local logic is needed in order to avoid problems, such as shoot through, when low- and high-side FETs are open. So, the simplest motor controller boards accept PWM signals. Either 2 PWM (PWM/PWM), or a PWM and one digital (PWM/DIR). ML-R offers controllers of the both types. PWM/PWM is a little more flexible but it demands 2 times more PWM pins which may be scarce. In most aspects they are similar. Here we will make a program which uses such a simple PWM/PWM controller.

Connections

Starting from basic connection, enhance the setup with ML-R Motor Driver 4x3.6A (mrm-mot4x3.6): In the picture there are no motors, but you may want to attach some to the green output connectors of the motor board.

Program

#define GPIO_A1 25
#define GPIO_A2 33
#define GPIO_B1 32
#define GPIO_B2 26
#define GPIO_C1 12
#define GPIO_C2 14
#define GPIO_D1 27
#define GPIO_D2 13

#define FREQUENCY_HZ 500

#define RESOLUTION_BITS 7 // 1 - 16
#define MAXIMUM_DUTY_CYCLE ((1 << RESOLUTION_BITS) - 1)

uint8_t pins[][2] = {{GPIO_A1, GPIO_A2}, {GPIO_B1, GPIO_B2}, {GPIO_C1, GPIO_C2}, {GPIO_D1, GPIO_D2}};

void setSpeed(uint8_t motor, int8_t speed){
    ledcWrite(2 * motor, speed > 0 ? speed : 0);
    ledcWrite(2 * motor + 1, speed < 0 ? -speed : 0);
}

void setup() {
  for (uint8_t motor = 0; motor < 4; motor++){
    ledcSetup(2 * motor, FREQUENCY_HZ, RESOLUTION_BITS);
    ledcSetup(2 * motor + 1, FREQUENCY_HZ, RESOLUTION_BITS);
    ledcAttachPin(pins[motor][0], 2 * motor);
    ledcAttachPin(pins[motor][1], 2 * motor + 1);
  }
}

void loop() {
  for (uint16_t motor = 0; motor < 4; motor++){    
    int8_t step = 1;
    for (int8_t speed = 1; !(speed == 0 && step == 1); speed += step){
      setSpeed(motor, speed);
      delay(30);
      if (abs(speed) == MAXIMUM_DUTY_CYCLE)
        step = -step;
    }
  }
}
The program will drive all the 4 motors, one by one, first gradually to maximum rotation, then gradually to maximum opposite rotation, and in the end towards stop.

First section defines GPIO pins as in the picture. A1 and A2 are 2 pins for the first motor, B2 and B2 for the second, etc. Frequency, FREQUENCY_HZ, will be 500 Hz. Original Arduino boards use frequencies from around 500 till 1000 Hz. 500 is more than enough because the motor has a high rotational inertia and it is not possible to change speed more than 500 times per second. RESOLUTION_BITS 7 defines speed range between -127 (=27-1) and 127. It defines MAXIMUM_DUTY_CYCLE as 127. Bit shifting 1 will do the math for us.

Next is defined an array consisting of GPIOs defined above. It is easier to use an array then a list of constants because we can iterate the array.

Function setSpeed(motor, speed) sets speed speed for motor number motor. speed must be in range -127 to 127, motor 0 - 3. No input values validation is done anywhere in our examples to keep them verbatim. Doing no input parameter checking is a big no-no for a production code. PWM/PWM motor drivers usually accept 0 V on pin 1 and pin 2 expects a variable PWM signal width in order to spin the motor in one direction. To spin it in the other direction, pin 1 accepts variable signal and pin 2 is at 0 V.

setup() iterates 4 motors, 2 pins each, and sets PWM's configuration, according to our selected constants, in the first 2 loop's commands. They use ledcSetup() functions, which accept channel number as first argument. Here we just choose increasing integers, from 0 up. They have to be different as every pin will use its own PWM signal. The last 2 use ledcAttachPin() function to attach PWM signal to selected pins.

loop() is a standard C code so there are no new things to learn about the hardware here. 2 nested loops and the inner one sets motor's speed.

Limitations

Some pins are not available for PWM output. Check this list.