It was time well spent to study my batch of commodity breakout boards for the DRV8833 DC motor driver IC. It reinforced that I should not take random instructions downloaded online at face value, even though in this case the errors wouldn’t have been relevant to my planned usage. Armed with confidence I understand how to use the board I have on hand, I proceed to the next step: verify I could write code to control one with an ESP32 and its MCPWM peripheral.
My self-education FreeRTOS project was created with this future in mind when I started by controlling a L298 DC motor driver IC. The first exercise used the control scheme utilizing three pins per motor (two digital for state, one PWM pin for magnitude) which is compatible with the TB6612 but not DRV8833. The beauty of FreeRTOS was that I was able to isolate code specific to this control scheme in its own FreeRTOS task. In theory, all I would need to do is to write another task with DRV8833’s control scheme (a pair of PWM pins per motor) and swap out the motor driver control task. The remainder of my test program, from the joystick ADC to the heartbeat status LED, would remain untouched and blissfully unaware I’ve switched my motor control task.
I’m happy to report theory matched practice this time! The problem I encountered was unrelated to FreeRTOS. It was really easy to get one motor up and running but I was tripped up by my misinterpretation of Espressif documentation when trying to run two motors simultaneously at different speeds. Each MCPWM unit on a ESP32 can control three motors, and each MCPWM unit had three timers. The quote from Espressif documentation that I misunderstood was:
Each A/B pair may be clocked by any one of the three timers Timer 0, 1 and 2. The same timer may be used to clock more than one pair of PWM outputs.
I tried to run two pairs of PWM outputs (one pair per motor) with the same timer, which is explicitly allowed by the documentation and generated no compiler or runtime errors. However, the fact that it is possible and allowed doesn’t mean it actually does what I want. By using the same timer, I had also locked those motors to the same speed. Different speeds require separate timers. Which is why MCPWM offers up to three timers so we can run each motor at a different speed. Once I realized my mistake and understood what was going on, it was an easy fix to get both motors up and running each with their own timer. With both motors running on my existing cardboard testbed, I thought it was time to upgrade to a fancier (but still cardboard) testbed.
This coding practice project is publicly available on GitHub.