Built-in project · ESP32-DevKitC V4

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.

MicroPython knob drives a motor both ways, L293D · ESP32-DevKitC V4live0.000 s 0.00x
Click to open it in the editor
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

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.

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 pinConnects to
Potentiometer pin 2ESP32-DevKitC V4 pin VP
Motor driver, L293D pin IN2ESP32-DevKitC V4 pin 14
Motor driver, L293D pin IN1ESP32-DevKitC V4 pin 12
Motor driver, L293D pin EN12ESP32-DevKitC V4 pin 13
Potentiometer pin 1Ground
Potentiometer pin 33.3 V
DC motor pin 1Motor driver, L293D pin OUT1
Motor driver, L293D pin GND1Ground
Motor driver, L293D pin GND2Ground
DC motor pin 2Motor driver, L293D pin OUT2
Motor driver, L293D pin VS5 V
Motor driver, L293D pin EN34Ground
Motor driver, L293D pin IN4Motor driver, L293D pin IN3
Motor driver, L293D pin OUT4Motor driver, L293D pin OUT3
Motor driver, L293D pin GND3Ground
Motor driver, L293D pin GND4Ground
Motor driver, L293D pin VSS5 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.

main.py · ESP32-DevKitC V4
# 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.