Guide to The Self-Driving Car Prototype: Programming an ESP32 Cam on a 2WD Chassis with MicroPython and TinyYOLO
The Self‑Driving Car Prototype: Programming an ESP32‑Cam on a 2WD Chassis with MicroPython & TinyYOLO
Welcome to this step‑by‑step tutorial guide. You will learn how to turn a simple 2‑wheel‑drive (2WD) chassis into a miniature self‑driving car using an ESP32‑Cam, MicroPython, and the lightweight TinyYOLO object detection model. All code is ready to copy, and each hardware connection is illustrated with clear inline graphics.
Why This Prototype?
The combination of MicroPython and TinyYOLO brings AI inference to the edge with minimal power consumption. By the end of this guide you will have a working autonomous car that can:
- Capture live video from the ESP32‑Cam.
- Detect obstacles and lane markings using TinyYOLO.
- Control motor speed and steering via PWM.
- Log telemetry to a local SD card.
Materials & Tools
| Component | Quantity | Notes |
|---|---|---|
| ESP32‑Cam (AI‑Thinker) | 1 | 128 KB SRAM, OV2640 camera |
| 2WD Chassis Kit | 1 | Includes motor driver board (L298N) |
| Micro‑USB to TTL Converter | 1 | For flashing firmware |
| MicroSD Card (8 GB) | 1 | Logs images & telemetry |
| Jumper Wires, 5 V Power Bank | Assorted | Male‑to‑female, 20‑30 cm |
1. Set Up the Development Environment
- Install Python 3.10+ on your workstation.
- Open a terminal and run:
pip install esptool adafruit-ampy - Download the latest MicroPython firmware for ESP32‑Cam from micropython.org (choose
esp32‑cam‑v1.20.bin). - Clone the TinyYOLO repository:
git clone https://github.com/ultralytics/tiny-yolo-v3-micropython.git
2. Flash MicroPython onto the ESP32‑Cam
Connect the ESP32‑Cam to the TTL converter (GND → GND, 3.3 V → VCC, TX → RX, RX → TX). Hold the BOOT button while plugging the USB into your PC. Run the following commands:
# Erase flash
esptool.py --port COM3 erase_flash
# Write MicroPython firmware
esptool.py --chip esp32 --port COM3 --baud 460800 write_flash -z 0x1000 esp32-cam-v1.20.bin
After flashing, press RESET. The ESP32‑Cam now boots into MicroPython REPL.
3. Wire the 2WD Chassis to the ESP32‑Cam
Use the L298N driver to control two DC motors. Keep the wiring tidy to avoid signal noise.
- ENA → ESP32‑Cam GPIO
14(PWM for left motor) - IN1 → GPIO
12(direction left) - IN2 → GPIO
13(direction left) - ENB → GPIO
27(PWM for right motor) - IN3 → GPIO
26(direction right) - IN4 → GPIO
25(direction right) - Camera SDA/SCL → GPIO
21/22(optional I2C sensors) - SD card slot connects directly to ESP32‑Cam’s
SDpins.
💡 Tip: Secure the camera module on the chassis front with double‑sided tape to keep the field of view steady.
4. Load the TinyYOLO Model onto the ESP32‑Cam
MicroPython cannot run full TensorFlow models, but TinyYOLO (v3) is ~30 KB and fits comfortably in the ESP32’s RAM.
- Copy
tiny_yolo.pyandtiny_yolo.weightsto the device:ampy --port COM3 put tiny_yolo.py ampy --port COM3 put tiny_yolo.weights - Verify the files:
ampy -p COM3 ls
5. Write the Self‑Driving Script
Copy the following script into main.py. It initializes the camera, runs TinyYOLO on each frame, and adjusts motor PWM based on detected objects.
import machine, time, uos
import camera
import tiny_yolo
# ---- Motor pins -------------------------------------------------
LEFT_PWM = machine.PWM(machine.Pin(14), freq=1000)
RIGHT_PWM = machine.PWM(machine.Pin(27), freq=1000)
LEFT_DIR1 = machine.Pin(12, machine.Pin.OUT)
LEFT_DIR2 = machine.Pin(13, machine.Pin.OUT)
RIGHT_DIR1 = machine.Pin(26, machine.Pin.OUT)
RIGHT_DIR2 = machine.Pin(25, machine.Pin.OUT)
def set_motor(left_speed, right_speed, left_fwd=True, right_fwd=True):
# speed: 0‑1023 (0‑100%)
LEFT_PWM.duty(left_speed)
RIGHT_PWM.duty(right_speed)
LEFT_DIR1.value(1 if left_fwd else 0)
LEFT_DIR2.value(0 if left_fwd else 1)
RIGHT_DIR1.value(1 if right_fwd else 0)
RIGHT_DIR2.value(0 if right_fwd else 1)
# ---- Camera setup ------------------------------------------------
camera.init(0, format=camera.JPEG, framesize=camera.FRAME_QVGA)
camera.flip(0) # adjust orientation if needed
# ---- TinyYOLO model ------------------------------------------------
model = tiny_yolo.YOLO('tiny_yolo.weights', threshold=0.4)
def auto_drive():
while True:
buf = camera.capture()
objs = model.detect(buf)
# Simple rule: if a person is ahead, stop; else move forward
stop = any(o['label'] == 'person' and o['conf'] > 0.5 for o in objs)
if stop:
set_motor(0, 0)
else:
set_motor(700, 700) # ~70% speed forward
time.sleep_ms(100)
try:
auto_drive()
except KeyboardInterrupt:
set_motor(0, 0)
camera.deinit()
Upload the script:
ampy -p COM3 put main.py
After reboot, the car starts moving automatically.
6. Test and Calibrate
Place the prototype on a flat surface and observe the following:
- Steering response: Adjust PWM values (0‑1023) for smoother turns.
- Detection latency: Typical inference time is ≈180 ms. Reduce
framesizeif you need faster response. - Power stability: A 5 V power bank delivering at least 2 A keeps the motors and camera running without brown‑out.
Use a simple print() debug statement inside the loop to watch object confidence values in the serial monitor.
Troubleshooting
| Problem | Check |
|
|---|
Comments
Post a Comment