As part of exploring MCPWM duty cycles, I had to make decisions on ESP32 pin assignments. This is how my ESP32 DevKit will communicate with my DC motor driver and steering servos. Three DRV8833 motor driver IC breakout boards for Micro Sawppy rover’s six TT gear motors driving wheels, plus four corner steering servos. Together they require sixteen PWM pins which is within an ESP32’s capability.
I’m very thankful for this compilation of ESP32 pinout from Random Nerd Tutorials, which served as a starting point and immediately crossed off many off-limit pins like those tied to ESP32 flash memory access. I also eliminated the primary serial transmit & receive pins from consideration as I wanted to keep them available for serial monitoring.
The next pins I wanted to keep clear were the two hardware I2C pins. I want to be build a baseline ESP32-controlled rover with as few external support chips as possible. But if I can leave the I2C pins free, that leaves the door open for add-ons and expansions. Additional PWM pins can be added with something like the popular PCA9685 chip. (*) And additional digital input/output pins can be added via PCF8574 (*) or similar chips. In fact, if I get to a point where I desire specific ESP32 peripherals (capacitive touch?) I can offload all wheel driving and steering duties to an external PWM chip.
I wanted to leave hardware SPI pins open for the same reason, but SPI was a luxury I could not afford. That would mean leaving four more pins unused and that’s more than I can spare for my baseline design. If SPI becomes important, I’ll need to offload some wheel control to external PWM chips. Another luxury I had to leave behind are the JTAG debug pins, which also demanded four pins I could not spare unless I offload PWM to external components.
But even though I could use those JTAG pins for general output, some care had to be taken because there will be some spurious signals on those pins. Upon power-up, before my code can run to configure those pins for PWM output, these pins will have signals corresponding to JTAG or other system use. In practice I expect this to mean my rover will twitch a little bit at startup, so I assigned those pins to steering servo signal duty. I rather that my rover steering servo twitch on powerup instead of a drive wheel. I don’t want the rover to drive itself forward or back uncontrolled, no matter how briefly.
After all of the above concerns are factored in, the final one is the physical relationship of pins. I wanted to keep related pins close together, such as the A and B lines for motor control. This is a little tricky to do on the Random Nerd Tutorials chart, because it is sorted by GPIO number instead of their physical position. I used Excel to create a chart that maps the physical location of those pins. Then I assigned their use so they roughly correlate to their positions on the rover, with the DevKit USB port pointing towards back. In reality the wiring won’t be that straightforward because the motor control lines will have to go through a DRV8833 first, but it might help me during debugging.
The assignments are listed on the outer-most columns of the chart. The first letter is one of (F)ront, (M)id, or (B)ack. The second letter is (L)eft or (R)ight. The third letter is (A) and (B) for DRV8833 motor control, or (S) for steering servo. This particular set of assignments leaves the I2C SDA & SCL pins free. Unencumbered GPIO23 is left free and clear for anything. The four input-only pins 34, 35, 36, and 39 are still available. And as a last resort, we still have the restricted-use GPIO0 pin. With this plan for pin assignments in hand, I proceed to turn the plan into reality.
(*) Disclosure: As an Amazon Associate I earn from qualifying purchases.