Build a Line Follower Robot with Arduino

Line following is the classic school-competition event, and the first project where your robot makes decisions faster than you can. This guide bolts two IR sensors onto the 2WD robot car, gets a simple bang-bang follower running, then shows the PID approach used by competition teams.

How IR line sensing works

Each sensor module (typically a TCRT5000) contains an infrared LED and a phototransistor side by side, facing the floor. White surfaces reflect the IR back strongly; matte black tape absorbs it. An on-board comparator turns that difference into a clean digital HIGH/LOW, with a small potentiometer to set the threshold. Mount them 3–8 mm above the floor — too high and everything looks black, touching the floor and they snag.

Extra parts needed

Additions to the robot car
PartNotesIndicative price (India)
IR line sensor modules ×2 (TCRT5000 type)Digital-output modules with trim pot₹40–80 each
Female–female jumper wires ×6Sensor to Arduino₹30–60
Black electrical tape / matte black chart tape, 19–25 mmFor the track₹30–80
White chart paper or a light plain floorTrack surface₹20–60
About prices

Prices shown are indicative online street prices in India as of mid-2026. They vary by seller and stock — treat them as a budgeting guide, not a quote.

Mounting and wiring

Mount both sensors at the front of the chassis, facing down, spaced slightly wider than the tape (about 30–40 mm apart for 19–25 mm tape). On the standard Hobby Robots pinout the motor driver uses D2, D4–D8, so the sensors go to the analog pins used as digital inputs:

Sensor wiring
Sensor pinLeft sensorRight sensor
VCCArduino 5VArduino 5V
GNDArduino GNDArduino GND
OUT / DOArduino A0Arduino A1

Verify the sensors first

Before touching the motor code, print the raw readings (Serial.println(digitalRead(A0)); in a loop) while holding the car over white paper and over the tape. Most modules read HIGH over black; some are inverted, and each module’s indicator LED tells you at a glance. If yours are inverted, just add a ! in front of both digitalRead calls in the follower sketch. Adjust each module’s trim pot until the output flips crisply right at the tape edge.

The bang-bang follower

The logic is four lines of common sense: both sensors on the line → drive straight; only the left sensor sees black → the car has drifted right, steer left; and vice versa; neither sees black → the line was lost, rotate until it is found again.

// Hobby Robots — 2-sensor line follower
// Assumes the drive() function and pinout from the robot car guide.
// Sensors: LOW over white floor, HIGH over black line (verify yours!).
const int ENA = 5, IN1 = 7, IN2 = 8;
const int ENB = 6, IN3 = 4, IN4 = 2;
const int SENSOR_L = A0;
const int SENSOR_R = A1;

const int BASE  = 160;   // cruising speed (0..255)
const int TURN  = 120;   // inner-wheel speed during a correction

void drive(int left, int right) {
  digitalWrite(IN1, left  >= 0 ? HIGH : LOW);
  digitalWrite(IN2, left  >= 0 ? LOW  : HIGH);
  analogWrite (ENA, min(abs(left), 255));
  digitalWrite(IN3, right >= 0 ? HIGH : LOW);
  digitalWrite(IN4, right >= 0 ? LOW  : HIGH);
  analogWrite (ENB, min(abs(right), 255));
}

void setup() {
  pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
  pinMode(ENB, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT);
  pinMode(SENSOR_L, INPUT);
  pinMode(SENSOR_R, INPUT);
  delay(2000);
}

void loop() {
  bool leftOnLine  = digitalRead(SENSOR_L);   // HIGH = sees black
  bool rightOnLine = digitalRead(SENSOR_R);

  if (leftOnLine && rightOnLine) {
    drive(BASE, BASE);          // line under both: straight ahead
  } else if (leftOnLine) {
    drive(TURN, BASE + 40);     // drifting right: steer left
  } else if (rightOnLine) {
    drive(BASE + 40, TURN);     // drifting left: steer right
  } else {
    drive(-140, 140);           // lost the line: rotate to search
  }
}

Tuning it

  • Wobbles violently: lower BASE; bang-bang control always oscillates, and speed amplifies it.
  • Overshoots corners: lower BASE further, or increase the steering difference (raise the +40, lower TURN).
  • Loses the line on gentle curves: sensors are too far apart or too high off the floor.
  • Random twitching: sunlight contains lots of IR — test away from direct sun, and re-set the trim pots in the room where you run.

The PID upgrade

Bang-bang control only knows three states, so it zig-zags. Competition robots use a 5- or 8-channel sensor array, compute a weighted position of the line under the array (e.g. −2000 to +2000), and feed that error into a proportional–derivative controller — steering hard when far off the line, gently when nearly centred, and damping the oscillation with the D term:

// Position from a 5-channel analog array: -2000..+2000 (0 = centred)
float Kp = 0.08, Kd = 0.6;     // start here, tune on your track
int lastError = 0;

void followPID(int position) {
  int error      = position;                  // target is 0
  int correction = Kp * error + Kd * (error - lastError);
  lastError      = error;
  drive(BASE - correction, BASE + correction);
}

Start with the P term only (Kd = 0), raise Kp until the robot just starts to oscillate, then add Kd until the oscillation dies. A 5-channel array costs ₹150–300 and is the single best upgrade for competition line events.

Building a good test track

  • Matte surface, matte tape. Glossy tape or polished floors bounce IR unpredictably.
  • Minimum curve radius about 3× the car’s wheelbase to start; tighten it as tuning improves.
  • Include one straight, one gentle S-curve, and one sharp corner — that trio exposes every tuning flaw.
  • Keep tape joins smooth; a wrinkle reads like a gap.

Next steps