Tutorial
💡 Tip: Disable headers/footers in your print dialog for a clean PDF.
RoboRider Labs – Classroom Lesson
RoboRider Labs — Lesson 4: Line Following with IR Array
Lesson 4 — Line Following with IR Sensor Array 🏁
🧠 Concept
Read a 3-sensor IR array and steer a robot left/right to keep a line centered.
🌈 How IR sensors detect lines
Black tape absorbs IR → sensor reads LOW. White surface reflects IR → sensor reads HIGH (module dependent).
🧭 Wiring + Logic table

- IR_L → D4 (Arduino) / BCM 17 (Pi) / GPIO 27 (ESP32)
- IR_C → D5 / BCM 27 / GPIO 26
- IR_R → D6 / BCM 22 / GPIO 25
- Motor driver IN1/IN2 (Left), IN3/IN4 (Right) to PWM-capable pins
| L | C | R | Action |
|---|---|---|---|
| 0 | 1 | 0 | Forward |
| 1 | 1 | 0 | Drift Right → steer Right |
| 0 | 1 | 1 | Drift Left → steer Left |
| 1 | 0 | 0 | Hard Right |
| 0 | 0 | 1 | Hard Left |
| 0 | 0 | 0 | Lost! Stop |
💡 Some arrays output opposite logic. If behaviour is inverted, flip 0/1 in code.
💻 Code (Arduino C/C++)
// 3-IR line follow (basic) with L298N driver
const int L = 4, C = 5, R = 6;
const int ENA = 9, IN1 = 8, IN2 = 7;
const int ENB = 3, IN3 = 2, IN4 = 10;
void motors(int l, int r){ analogWrite(ENA, abs(l)); analogWrite(ENB, abs(r));
digitalWrite(IN1, l>=0); digitalWrite(IN2, l<0);
digitalWrite(IN3, r>=0); digitalWrite(IN4, r<0); }
void setup(){
pinMode(L,INPUT_PULLUP); pinMode(C,INPUT_PULLUP); pinMode(R,INPUT_PULLUP);
pinMode(ENA,OUTPUT); pinMode(IN1,OUTPUT); pinMode(IN2,OUTPUT);
pinMode(ENB,OUTPUT); pinMode(IN3,OUTPUT); pinMode(IN4,OUTPUT);
}
void loop(){
int l = !digitalRead(L); // invert if needed
int c = !digitalRead(C);
int r = !digitalRead(R);
int base=120, turn=80;
if(c && !l && !r) motors(base,base);
else if(l && c && !r) motors(base-turn, base+turn);
else if(!l && c && r) motors(base+turn, base-turn);
else if(l && !c && !r) motors(0, base); // hard right
else if(!l && !c && r) motors(base, 0); // hard left
else motors(0,0); // lost
}
🐍 Code (Raspberry Pi – Python, gpiozero)
# Line following with gpiozero
from gpiozero import DigitalInputDevice, Motor
from time import sleep
L = DigitalInputDevice(17) # BCM
C = DigitalInputDevice(27)
R = DigitalInputDevice(22)
left = Motor(forward=5, backward=6) # PWM pins via motor HAT/driver mapping
right = Motor(forward=13, backward=19)
def drive(l, r): # values -1..1
left.forward(l) if l >=0 else left.backward(-l)
right.forward(r) if r >=0 else right.backward(-r)
while True:
l = not L.value; c = not C.value; r = not R.value # invert if needed
base, t = 0.6, 0.4
if c and not l and not r: drive(base, base)
elif l and c and not r: drive(base-t, base+t)
elif not l and c and r: drive(base+t, base-t)
elif l and not c and not r: drive(0, base)
elif not l and not c and r: drive(base, 0)
else: drive(0,0)
sleep(0.02)
⚡ Code (ESP32 – MicroPython)
# Line following on ESP32 (MicroPython)
from machine import Pin, PWM
from time import sleep
L = Pin(27, Pin.IN, Pin.PULL_UP)
C = Pin(26, Pin.IN, Pin.PULL_UP)
R = Pin(25, Pin.IN, Pin.PULL_UP)
ENA = PWM(Pin(14), freq=1000); IN1 = Pin(12, Pin.OUT); IN2 = Pin(13, Pin.OUT)
ENB = PWM(Pin(27-13), freq=1000) # placeholder if using another pin; adjust!
IN3 = Pin(33, Pin.OUT); IN4 = Pin(32, Pin.OUT)
def motor_left(v): # v -1..1
d = int(abs(v)*1023)
ENA.duty(d); IN1.value(1 if v>=0 else 0); IN2.value(0 if v>=0 else 1)
def motor_right(v):
d = int(abs(v)*1023)
ENB.duty(d); IN3.value(1 if v>=0 else 0); IN4.value(0 if v>=0 else 1)
def drive(l,r): motor_left(l); motor_right(r)
while True:
l = not L.value(); c = not C.value(); r = not R.value()
base, t = 0.6, 0.4
if c and not l and not r: drive(base, base)
elif l and c and not r: drive(base-t, base+t)
elif not l and c and r: drive(base+t, base-t)
elif l and not c and not r: drive(0, base)
elif not l and not c and r: drive(base, 0)
else: drive(0,0)
sleep(0.02)
⚠️ Pin numbers & PWM channels vary by board and driver. Adjust to your motor shield.
🛠️ Tip: tune delay & threshold
Slow things down if it oscillates. Some arrays have analog outputs—use thresholds to smooth noise.
🖨️ Worksheet — Line Tracker Tuning Sheet
- [ ] Record base speed, turn gain
- [ ] Try three tape colours & note sensor readings
- [ ] What settings gave the smoothest lap?