🔍
57 lessons

Capstone: Build the Line Follower

Chassis, two motors, two eyes, one PID — a robot that chases black tape across your floor, tuned by you, understood by you.

lesson 4 of 4 in this unit

Builds on: 19.3 Encoders: Knowing Where You Are19.1 DC Motors & the H-Bridge14.2 PID Control12.1 Program the Night-Light

The mission

Build the classic first robot: two driven wheels, two downward-looking reflectance sensors, and firmware that steers so the black line stays between them. It is Lesson 14.2’s PID with wheels bolted on — and the moment it takes its first corner on its own, you will understand why people never stop building robots.

Shopping list (beyond Pico + breadboard kit)

PartNotes≈ Cost
2WD robot chassis kittwo yellow “TT” gear motors, wheels, caster, plate — the universal starter chassis$12–18
DRV8833 driver moduledual H-bridge with interlocks; happier at 3.3 V logic than the old L298N$3
2× TCRT5000 reflectance modulesIR LED + phototransistor — a divider output per sensor (2.2 again)$3
4×AA battery holdermotor power — separate from the Pico’s USB/5V supply$3
Black electrical tapethe racetrack. Light floor, wide gentle curves to start$2

The wiring

#FromToNotes
1Battery pack + / −DRV8833 VM / GNDmotor power stays off the Pico’s rail
2Pico GNDDRV8833 GND & sensor GNDscommon ground — the scope capstone’s oldest law
3GP2, GP3DRV8833 AIN1, AIN2left motor (PWM both for fwd/rev)
4GP4, GP5DRV8833 BIN1, BIN2right motor
5DRV8833 AOUT/BOUTthe two motorsswap a motor’s two wires if it runs backwards
6Sensor AO (left / right)GP26 / GP27the night-light’s ADC pins, now looking at the floor
7Sensor VCCPico 3V3sensors sip; motors must not touch this rail
8Sensors, mounted~15 mm apart, 3–8 mm above floor, ahead of the axleheight matters more than you think

The firmware

from machine import Pin, PWM, ADC
from time import sleep_ms

# DRV8833: two PWM pins per motor (fwd / rev)
m_l_f, m_l_r = PWM(Pin(2)), PWM(Pin(3))
m_r_f, m_r_r = PWM(Pin(4)), PWM(Pin(5))
for m in (m_l_f, m_l_r, m_r_f, m_r_r):
    m.freq(1000)

sens_l = ADC(26)   # left line sensor
sens_r = ADC(27)   # right line sensor

KP, KD = 28000, 900
BASE = 28000       # of 65535
last_err = 0

def drive(m_f, m_r, v):
    v = max(-65535, min(65535, int(v)))
    m_f.duty_u16(v if v > 0 else 0)
    m_r.duty_u16(-v if v < 0 else 0)

while True:
    l = sens_l.read_u16() / 65535
    r = sens_r.read_u16() / 65535
    err = r - l                    # +: line is to the right
    steer = KP * err + KD * (err - last_err)
    last_err = err
    drive(m_l_f, m_l_r, BASE + steer)   # line right -> left wheel faster
    drive(m_r_f, m_r_r, BASE - steer)   # -> robot turns right, toward the line
    sleep_ms(10)                   # 100 decisions per second

Thirty lines. The loop is the night-light’s superloop; the sensors are dividers into ADCs; the steering is 14.2’s PD law; the motors are Unit 8’s PWM through 19.1’s H-bridge. Tune KP exactly as the simulator taught you: too low corners wide, too high snakes down the straights, KD calms the snake. Then raise BASE until bravery fails.

If it misbehaves

SymptomLikely causeFix
Turns away from the linesensors or steering sign swappedswap GP26/GP27, or negate err — one change (15.2!)
One motor runs backwardsmotor leads reversedswap that motor’s two wires at the driver
Pico resets when motors kickmotor noise sagging the supplyseparate battery pack for VM, common grounds, 100 µF across VM (15.1’s decoupling!)
Blind to the linesensor height / ambient IR3–8 mm off the floor, shade from sunlight, check readings over tape vs floor in Thonny
Snakes violentlyyour Kp is shoutinghalve KP, add KD — you rehearsed this exact tuning in the twin

Where this road leads

Add encoders (19.3) and it knows its speed. Add an IMU and it can balance. Swap the tape for walls and a distance sensor: a maze solver. Everything else in robotics — SLAM, manipulators, autonomy — is more sensors, more loops, more math on the same skeleton you just built: sense → decide → act, at loop rates you now know how to choose, filter (13.3) and tune (14.2). Welcome to robotics. You came the long way, and it shows.

⚡ Lab — Digital Twin — Tune Before You Build

The exact robot, the exact control law, on a track that punishes bad tuning.

  • Default tune: watch a clean lap. Now double the base speed and watch the corners bite.
  • Set Kd to zero and find the speed where the straights start snaking.
  • Find your fastest never-lost settings — then dial the same ratios into the real firmware.
90
60
25
This is Lesson 14.2 on wheels
error = right sensor − left sensor · steering = Kp·e + Kd·de/dt · left wheel = base + steering, right = base − steering
The game
crank base speed and retune: too little Kp corners wide, too much snakes, Kd calms the snake. Find your fastest clean lap.

Build checklist — 0 / 10