Motor example for ML-R Motor Driver 1x50A reverse protection (mrm-mot1x50r)


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).


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/DIR controller.


Starting from basic connection, enhance the setup with ML-R Motor Driver 1x50A reverse protection (mrm-mot1x50r): In the picture there is no motor, but you may want to attach it to the green output connector of the motor board.


The program will drive a motor, first gradually to maximum rotation, then gradually to maximum opposite rotation, and in the end towards stop.

#define GPIO_SLP 32
#define GPIO_PWM 33
#define GPIO_PH 25

#define CHANNEL 0
#define FREQUENCY_HZ 500

#define RESOLUTION_BITS 7 // 1 - 16

void setSpeed(int8_t speed){
    ledcWrite(CHANNEL, abs(speed));
    digitalWrite(GPIO_PH, speed < 0 ? LOW : HIGH);

void setup() {
    ledcAttachPin(GPIO_PWM, CHANNEL);
    pinMode(GPIO_SLP, OUTPUT);
    pinMode(GPIO_PH, OUTPUT);
    digitalWrite(GPIO_SLP, HIGH);

void loop() {  
  int8_t step = 1;
  for (int8_t speed = 1; !(speed == 0 && step == 1); speed += step){
    if (abs(speed) == MAXIMUM_DUTY_CYCLE)
      step = -step;

First section defines GPIO pins as in the picture. GPIO_SLP is a sleep-mode pin, GPIO_PWM a PWM input signal, and GPIO_PH (phase) selects rotation direction. CHANNEL can be any whole number between 0 and 9 and chooses ESP32 PWM channel. 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.

Function setSpeed(speed) sets speed speed. speed must be in range -127 to 127. 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/EN motor drivers usually accept digital 0 or 1 on one pin (selects spin direction) and a variable PWM signal width on the other. setSpeed() implements this behaviour.

setup() sets PWM configuration, according to our selected constant, in the first command. It uses ledcSetup() function, which accepts channel number as first argument. The channels will have to be different as every pin will use its own PWM signal, if we use more than one motor controller. The second instruction uses ledcAttachPin() function to attach PWM signal to selected pin.

2 instructions follow to set digital mode as output and the last one wakes up the controller from sleep mode.

loop() is a standard C code so there are no new things to learn about the hardware here. A loop that sets motor's speed.


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

Alternative implementation, Teensy 3.2

Na Teensy pin 3 je spojen PWM ulaz kontrolera. Širinom pulsa se kontrolira brzina vrtnje. Arduino naredba je analogWrite().

Na pin 5 je spojen DIR ulaz, za smjer vrtnje. Koristi se Arduino naredba digitalWrite().

Ako na kontroler spajate Pololu 20D motore, možete koristiti npr. ML-R 20D Motor Connector (mrm-20d), koji zalemite na motor. Tako je moguće koristiti standardne ML-R Cable KK396-KK254 10 cm (mrm-kk3.96-2.54-10) kablove i izbjeći situaciju da pukne lemni spoj na motoru u zao čas. Isto vrijedi za N20 (ML-R N20 Motor Connector (mrm-n20)) i Pololu 25D motore (ML-R 25D Motor Connector (mrm-25d)). Spajate li druge motore, morat ćete sami raditi kablove jer dio na motor morate lemiti ili prilagođavati na neki drugi način motoru. Za spoj prema kontroleru koristite elemente kablova. Treće je rješenje koristiti polugotove kablove: ML-R Cable KK396 - bare (mrm-kk3.96-no-20).

U primjeru lijevo se koristi regulator MRMS Power Supply 3x B (mrm-ps3xb). Na ulaz se spoji baterija, vrlo preporučljivo bar 3 članka LiPo. Napon baterije ide dalje direktno do kontrolera motora, mimo prekidača. Regulator ima snažan FET prekidač pa bi se mogao koristiti napon baterije iza njega (prekidač ga isključuje - crni konektor do označenog), ali napajanje ne bi bilo tako čisto. Premda je nespretno imati napon baterije stalno na kontroleru motora, to je preporučljiva kombinacija. Kontroler motora troši malu struju u stanju hibernacije.

Iz regulatora se spoji 5V na ML-R Teen, board for Teensy 3.1/3.2 (mrm-tee) pločicu.

Na slici je ulaz kontrolera SLP spojen na digitalni pin 1 Teensy-ja 3.2. Na taj način se Arduino naredbom digitalWrite() kontroler može uključivati ili isključivati. Ako ova funkcionalnost nije potrebna, SLP se može spojiti diretno na 3.3 V.