Tutorial · Beginner · 20 min read

Build a Line Follower Robot: Sensors to PID Steering

How a line follower robot works: reflectance sensors, a weighted-position error, and a PID loop that steers a differential-drive chassis smoothly.

A line follower is the classic first autonomous robot: it reads a line under its sensors and steers to stay on it. Underneath, it is a small control problem—turn sensor readings into a steering correction—which makes it a perfect way to learn feedback control. Follow along in the Line Follower Simulator.

Sense the line

A reflectance sensor shines infrared light down and measures how much bounces back. A dark line reflects less than the bright surface around it, so each sensor reports whether it is over the line. A bar of several sensors across the front of the robot tells you not just whether you are on the line, but where the line sits relative to center.

Five sensors are a good starting point. Three work at low speed; competition robots often use eight for finer resolution.

Five line sensors in a row, each labelled with a weight from minus two on the left through zero in the middle to plus two on the right, and each showing a one or zero reading below it. The two sensors at weights zero and plus one read one and are highlighted; the rest read zero. The weighted average formula computes the sum of weights times readings divided by the sum of readings, giving zero plus one over two equals plus zero point five. A warning states that all zeros means the line is lost, which is a different case and not an error of zero.
Five on/off readings collapse into one signed number the steering loop can act on. Its sign is the direction, its size is how far off you are. Download SVG

Turn readings into one error number

Instead of reacting to individual sensors, combine them into a single weighted position. Give each sensor a position value (negative on the left, zero in the middle, positive on the right) and take the average weighted by how strongly each one sees the line:

// positions: {-2, -1, 0, 1, 2}; readings: reflectance per sensor
float weightedPosition = sum(position[i] * reading[i]) / sum(reading[i]);

The result is your error: zero means centered, negative means the line is to the left, positive to the right. A smooth, continuous error is exactly what a controller needs.

Steer with PID

Feed that error into a PID controller. The correction speeds one wheel and slows the other, turning the robot back toward the line:

float correction = kp * error + ki * integral + kd * derivative;
setMotorSpeeds(baseSpeed - correction, baseSpeed + correction);

Proportional gain drives most of the steering; derivative gain damps the wobble on curves; a small integral term removes any steady drift. If you are new to choosing gains, work through how to tune a PID controller first.

Fix the common failures

  • Oscillating around the line: proportional gain is too high or derivative too low. Reduce speed first, then re-tune. On real hardware, a long delay() in the loop adds dead time that defeats the derivative term.
  • Losing the line on sharp turns: the robot is outstripping its sensor update rate. Slow down, widen the bar, or reuse the last known line direction so the robot turns back instead of driving straight off.
  • Drifting to one side: calibrate the sensors. Sweep them over the line and the background, record each one’s min and max, and normalize live readings against that range.

Try it yourself

In the Line Follower Simulator you can draw a track, change the sensor count and speed, and tune the gains while watching the error and lap time. Everything you learn about the weighted error and the steering loop carries straight over to an Arduino robot.

Explore the graph

Part of these builds

Projects and learning paths that include this tutorial.

Further reading

References