MicroPython knob drives a motor both ways, L293D, on an ESP32-DevKitC V4
MicroPython on an ESP32: a knob on GPIO 36 sets the speed and the direction of a DC motor on an L293D: enable on 13, inputs on 12 and 14. The whole build, an ESP32-DevKitC V4 and 3 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Advanced About 25 minutes to build and run. Runs in your browser. Free, and no account needed.
The parts retail for about $13. On Mokxi they're free.
What you'll learn
- Reversing a DC motor with an H-bridge driver
- Direction from two input pins, speed from PWM on enable
- Reading a knob with an ADC in MicroPython
- Turning a centered range into direction and speed
- Difficulty: Advanced
- Time: About 25 minutes
- Board: ESP32-DevKitC V4
- Parts: 7
How it works
A knob on GPIO 36 (the VP pin) is read as a number from 0 to 4095. The program subtracts 2048, so the middle of the knob is 0, which means stop. Turn one way for positive values and the other way for negative values.
The sign picks the direction. in1 on GPIO 12 goes high for positive values and in2 on GPIO 14 goes high for negative ones. The L293D then drives the motor one way or the other.
The distance from the middle sets the speed. It becomes a PWM duty on the enable pin, GPIO 13, at 10000 Hz. Each pass prints "forward", "reverse" or "stop" with the speed, then waits 200 ms.
Parts list
7 parts, plus the jumper wires. They retail for about $13; on Mokxi they're free.
- 1 × ESP32-DevKitC V4
- 1 × PotentiometerIn Halloween Prop Kit, Starter Projects Kit.
- 1 × Motor driver, L293DIn Claw Machine Kit.
- 1 × DC motor
- 1 × Power, 3.3 V
- 2 × Power, 5 V
Kits that can build it
These 2 starter kits have every part in the circuit. Each kit's page lists what else it can build.
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Part and pin | Connects to |
|---|---|
| Potentiometer pin 2 | ESP32-DevKitC V4 pin VP |
| Motor driver, L293D pin IN2 | ESP32-DevKitC V4 pin 14 |
| Motor driver, L293D pin IN1 | ESP32-DevKitC V4 pin 12 |
| Motor driver, L293D pin EN12 | ESP32-DevKitC V4 pin 13 |
| Potentiometer pin 1 | Ground |
| Potentiometer pin 3 | 3.3 V |
| DC motor pin 1 | Motor driver, L293D pin OUT1 |
| Motor driver, L293D pin GND1 | Ground |
| Motor driver, L293D pin GND2 | Ground |
| DC motor pin 2 | Motor driver, L293D pin OUT2 |
| Motor driver, L293D pin VS | 5 V |
| Motor driver, L293D pin EN34 | Ground |
| Motor driver, L293D pin IN4 | Motor driver, L293D pin IN3 |
| Motor driver, L293D pin OUT4 | Motor driver, L293D pin OUT3 |
| Motor driver, L293D pin GND3 | Ground |
| Motor driver, L293D pin GND4 | Ground |
| Motor driver, L293D pin VSS | 5 V |
The code
The MicroPython code exactly as the editor opens it. Change a line there and press Run: the board runs it on the official MicroPython firmware, with nothing to compile.
# A knob drives a motor both ways through an L293D. The middle of the
# knob is stop; turn it either way and the motor runs that way, faster
# the further you turn. Enable on GPIO 13 (PWM), inputs on 12 and 14.
from machine import ADC, Pin, PWM
import time
pot = ADC(Pin(36))
pot.atten(ADC.ATTN_11DB)
pot.width(ADC.WIDTH_12BIT)
in1 = Pin(12, Pin.OUT)
in2 = Pin(14, Pin.OUT)
enable = PWM(Pin(13), freq=10000, duty=0)
while True:
value = pot.read() - 2048 # -2048 to 2047
in1.value(1 if value > 0 else 0)
in2.value(1 if value < 0 else 0)
speed = min(abs(value) // 2, 1023)
enable.duty(speed)
print("forward" if value > 0 else "reverse" if value < 0 else "stop", speed)
time.sleep_ms(200)
Troubleshooting
The usual mistakes with this circuit, and the fix for each.
- The motor only turns one way. This project
Check that both GPIO 12 and GPIO 14 reach the L293D inputs IN1 and IN2. Both are needed for reverse. - The motor does not move at all. This project
Check that EN12 is wired to GPIO 13 and that VS and VSS are both on 5 V. - The knob reads nothing useful. This project
The knob's middle pin goes to VP (GPIO 36). The outer pins go to ground and 3.3 V. - The reading jumps around or only covers part of the range. Potentiometer
Wire the two outer legs to 5 V and ground and the middle leg (the wiper) to an analog pin. Using the wrong two legs gives a dead or partial range. - Turning the knob does nothing, or the value is stuck at 0 or 1023. Potentiometer
Check that the wiper goes to an analog input (A0 to A5 on an Uno), not a digital pin. Make sure both ends are connected, since a floating end gives noise. - The motor is weak or does not turn, and the chip gets hot. Motor driver
The L293D gives about 600 mA per channel and drops about 1.4 V per side. Use a motor that fits, and for bigger motors pick another driver. - Nothing moves even though the inputs are right. Motor driver
Power both supply pins: VCC1 (pin 16) at 5 V for logic and VCC2 (pin 8) for the motor. Tie the enable pin high, and join all grounds. - The motor does not spin, or the pin gets hot or the board resets when it is wired straight to a GPIO pin. DC motor
A pin gives about 20 mA and a motor needs far more. Drive it through a transistor or motor driver, with its own supply and a shared ground.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.