Line follower robot with Arduino: parts and code

How to build a line follower with Arduino: choosing sensors, placing them, a proportional-steering starter sketch and a step-by-step test plan.

Reference
RE-3794
Published
Read
6 min

About the author · Sources, testing and AI policy

A line follower is the best first robot to build because it fails in ways you can see: it wobbles, overshoots or loses the line, and each symptom points at one fix. This guide covers the parts to choose, how to place the sensors, a complete first sketch, and a test plan that finds the problem before you start changing numbers.

If you want the simplest possible first build with two sensors and no PID, start with the two-sensor line follower project, then come back here for the step up to five sensors and proportional steering.

Status: this guide is written from datasheets and manufacturer documents. The code has not been run on a robot here, so treat it as a starting point and test it on your own hardware. Nothing in it claims a build result or a measured lap time.

What a line follower needs

  • Two driven wheels and a caster for a differential-drive chassis. See the chassis buying guide if you have not picked one.
  • A motor driver that can handle your motors. The L298N versus TB6612FNG comparison explains the voltage drop that makes the L298N a poor choice on a small battery.
  • Reflectance sensors, from three to eight in a row, facing the floor.
  • A microcontroller with enough analog inputs. An Arduino Uno has six.
  • A battery sized for the motors, and a regulator for the logic. See the robot battery guide.

Choosing and placing the sensors

Most hobby line sensors pair an infrared LED with a phototransistor and measure how much light bounces back from the floor. A black line reflects less than a white floor, so the reading drops over the line. The common TCRT5000 is a reflective sensor of this kind with a maximum range of about 15 mm according to Vishay’s listing, but its useful distance for a line is much shorter, so mount it close to the floor and test it at your actual height.

Pololu’s QTR-8RC array gives a useful benchmark for spacing: its documentation lists an optimal sensing distance of 3 mm and a maximum recommended distance of 9.5 mm for the RC version, and 6 mm for the analog QTR-8A. Whatever sensor you use, the height matters as much as the model, because a sensor held too high sees the floor and the line as the same grey.

Space the sensors so that the line, which is commonly about 2 cm wide on a student track, covers one or two of them at a time. Wider spacing sees corners earlier but gives a coarser position. Put the sensor bar ahead of the wheel axle, because a bar placed over the axle gives the controller no time to react.

A first sketch: proportional steering

Start with proportional control only. It is the smallest controller that follows a line, and it shows you the real behaviour of your robot before you add a derivative term. The PID explainer shows how the error number is built from the sensor weights, and the tuning guide covers adding the D term.

// Untested starting point: five analog sensors on A0 to A4.
const int pins[5] = {A0, A1, A2, A3, A4};
const int weights[5] = {-2, -1, 0, 1, 2};
const int baseSpeed = 120;   // 0 to 255, keep it low for the first test
float kp = 20;               // tune this first
int lastError = 0;

void setup() {
  // set the motor driver pins as outputs here
}

void loop() {
  long sum = 0, total = 0;
  for (int i = 0; i < 5; i++) {
    int v = analogRead(pins[i]);     // higher = darker on most modules
    sum += (long)weights[i] * v;
    total += v;
  }
  if (total < 100) {                 // line lost: keep the last direction
    setMotors(lastError < 0 ? -baseSpeed : baseSpeed, lastError < 0 ? baseSpeed : -baseSpeed);
    return;
  }
  int error = (sum * 100) / total;   // about -200 to +200
  lastError = error;
  int correction = (int)(kp * error / 100.0);
  setMotors(baseSpeed + correction, baseSpeed - correction);
}

void setMotors(int left, int right) {
  left = constrain(left, -255, 255);
  right = constrain(right, -255, 255);
  // write PWM and direction to your motor driver here
}

The direction of the sensor reading depends on your module, so check it first: print the five values with the sensors over white and then over black. If the numbers fall over the line instead of rising, invert the reading before using it. If the robot steers away from the line instead of towards it, swap the sign of the correction.

A test plan that finds the problem fast

  • Wheels off the ground. Hold a black strip under the sensors and confirm the left motor speeds up when the line is on the right, and the reverse.
  • Print the readings. Check the values over white, over black and at the edge, and note the gap between them. A small gap means the sensors are too high or the floor is too glossy.
  • Straight line, low speed. Set a low base speed and raise kp until the robot starts to wobble, then lower it by about a third.
  • Curves. If it wobbles on straights, the gain is too high; if it runs wide on curves, it is too low or the speed is too high.
  • Change one thing at a time and write down each change and its result in a notebook. This is the habit that makes your own report credible.

Common faults and what they mean

What you seeLikely cause
Zig-zags on straightskp too high, or base speed too high
Runs off at sharp cornersSensor bar too close to the axle, speed too high, or no lost-line recovery
Behaves differently in a bright roomSunlight contains infrared that confuses the sensors; shade the bar
Drives straight and ignores the lineSensor height wrong, or the reading direction is inverted
Resets when the motors startPower dip; see the fix page

Where to go next

Once the proportional version follows a plain track, add the derivative term, then try a track with sharp turns and gaps. A maze-solving robot reuses the same sensors with different logic. For a build that goes beyond this guide, keep a log of your own tests, with photos of your track and your measured settings. That record is what turns a template guide into a project report that is yours.

Sources: Vishay TCRT5000 product information; Pololu QTR-8RC documentation. Last reviewed November 2026. Written, checked and maintained by Jignesh Panchal.

Pass it onWhatsAppLinkedIn

Keep reading

Continue learning

Tutorials

Arduino serial command parsing for robots

Why Bluetooth robots lag, how the Arduino serial timeout works, and a non-blocking command parser with a simple format and a link-loss…

  • Published4 Nov 2026
  • Read4 min

Free: the final-year project pack

A shortlist with BOMs, a report outline that matches the usual chapter scheme, a costing sheet and 40 viva questions. Built for the February–April submission season.

The Build Note

One short email when something is worth your bench time.

A new build sheet, a part price that moved, or a mistake worth avoiding. No daily drip, no recycled news.

One short email when a build or a price is worth your time. Unsubscribe in one click.