Home · Academy · Robotics & Coding · Robotic Systems · Project: Line-Following Robot

Project: Line-Following Robot

Build a robot that follows a line using two line sensors, two motors and a driver.

PROJECT COMPASS

What will you use this page for?

Core idea

In this project I build a real robot that follows a line on the floor by itself, using two line sensors, two motors, and a motor driver, adjusting the motor speeds based on the left–right sensor readings.

Evidence to produce

Complete the page task with your own input, test conditions and reasoning.

Control trap

Forgetting the common ground If you do not connect the GND terminals of the Arduino and the motor battery together, the driver cannot read the signals. The robot either does not move at all or behaves randomly. Common ground is the most often skipped step in this project. Connecting a motor straight to the Arduino If…

Next connection

Introduction to Data and Artificial Intelligence module: We begin to explore how to gather the sensor data robots collect, make sense of it, and how a computer starts to "learn" from that data.

Module sources: Python Tutorial · Arduino Learn

LevelBeginner
Age10–16
Duration45–75 min
PrerequisiteProject: Obstacle-Avoiding Robot
ContentProject guide · 2,168 words
Last updated

One-sentence summary

In this project I build a real robot that follows a line on the floor by itself, using two line sensors, two motors, and a motor driver, adjusting the motor speeds based on the left–right sensor readings.

Why it matters

In the previous project the robot spotted an obstacle and fled from it. Now we flip the task: the robot will not run away from something, it will follow a drawn path. This is another face of the same "sense–decide–act" loop.

Line following is the most classic project in robotics. And not only in competitions: transport vehicles that roam between warehouse shelves and factory conveyor lines follow floor markings with similar logic. The idea that works on a small robot works in large systems too.

This project brings the heart of the whole module together in one device. The sensors detect the line, the program decides with a condition, and the motors turn that decision into motion. Electronics, code, and mechanics all work at once. When I first built mine, the robot drifted right even on a straight line; finding and fixing the reason was the most instructive part.

Materials, wiring, and power

Materials list

What a simple line-following robot needs:

Why a separate battery and a motor driver?

Motors draw far more current than an Arduino pin can supply. Connect a motor straight to a pin and the pin is damaged, maybe the whole board. So we place a motor driver in between: the Arduino sends a small "spin at this speed" signal, and the driver pulls the power from a separate battery.

Think of a doorbell: your finger presses a small button, but the power that makes the sound comes from the wiring in the wall. A motor driver is that kind of go-between.

Two rules matter a lot:

Never use mains (wall socket) electricity. This project uses only low-voltage batteries.

Calibrate the sensors

Before writing code, we must measure what the sensors actually report. Calibration answers the question, "In which case does the sensor read 1, and in which case 0?"

Read with Serial

Print the sensor values to the screen with a small test program:

const int LEFT_SENSOR = 2;
const int RIGHT_SENSOR = 3;

void setup() {
  Serial.begin(9600);
  pinMode(LEFT_SENSOR, INPUT);
  pinMode(RIGHT_SENSOR, INPUT);
}

void loop() {
  Serial.print(digitalRead(LEFT_SENSOR));
  Serial.print("  ");
  Serial.println(digitalRead(RIGHT_SENSOR));
  delay(200);
}

Hold the sensor over the black line, then over the white surface. Note how the values change. On some modules the line reads 1, on others 0. In this project we assume "line = 1"; if your module is the opposite, you just flip the comparisons in the code.

Sensor height and position

The sensors are mounted very close to the floor (about 3–8 mm) so they look at either side of the line. Too high and they cannot tell the line apart; too low and they scrape the ground. If your module has a small adjustment screw, tune the threshold until black and white are clearly separated.

Program the robot

The robot's two wheels turn with separate motors. There is no steering wheel; to turn, you drive the two wheels at different speeds. This is called differential drive.

Pseudocode

Repeat forever
  left = read left sensor
  right = read right sensor

  If left is white and right is white
    drive both motors fast          (go straight)
  Else if left is line and right is white
    slow the left motor             (turn left)
  Else if left is white and right is line
    slow the right motor            (turn right)
  Else
    handle the junction or lost case

The logic may seem backwards at first: if the left sensor sees the line, we turn left. That is because if the left sensor touched the line, the robot has drifted right; to recentre, we must pull left.

Example 1: Pins and setup

const int LEFT_SENSOR = 2;   // left IR sensor
const int RIGHT_SENSOR = 3;  // right IR sensor
const int LEFT_ENA = 5;      // left motor speed (PWM)
const int LEFT_IN1 = 7;      // left motor direction
const int LEFT_IN2 = 8;
const int RIGHT_ENB = 6;     // right motor speed (PWM)
const int RIGHT_IN3 = 9;     // right motor direction
const int RIGHT_IN4 = 10;

const int FAST = 160;        // 0–255
const int SLOW = 70;

void setup() {
  pinMode(LEFT_SENSOR, INPUT);
  pinMode(RIGHT_SENSOR, INPUT);
  pinMode(LEFT_ENA, OUTPUT); pinMode(LEFT_IN1, OUTPUT); pinMode(LEFT_IN2, OUTPUT);
  pinMode(RIGHT_ENB, OUTPUT); pinMode(RIGHT_IN3, OUTPUT); pinMode(RIGHT_IN4, OUTPUT);
  digitalWrite(LEFT_IN1, HIGH); digitalWrite(LEFT_IN2, LOW);    // left forward
  digitalWrite(RIGHT_IN3, HIGH); digitalWrite(RIGHT_IN4, LOW);  // right forward
}

We set the direction to forward once in setup(). In the loop we will only change the speed.

Example 2: Main loop and a motor helper

void driveMotors(int leftSpeed, int rightSpeed) {
  analogWrite(LEFT_ENA, leftSpeed);
  analogWrite(RIGHT_ENB, rightSpeed);
}

void loop() {
  int left = digitalRead(LEFT_SENSOR);    // 1 = line seen
  int right = digitalRead(RIGHT_SENSOR);

  if (left == 0 && right == 0) {          // both white
    driveMotors(FAST, FAST);              // go straight
  } else if (left == 1 && right == 0) {   // line on the left
    driveMotors(SLOW, FAST);              // turn left
  } else if (left == 0 && right == 1) {   // line on the right
    driveMotors(FAST, SLOW);              // turn right
  } else {                                // both on the line
    driveMotors(FAST, FAST);              // junction: keep straight
  }
}

driveMotors is a small helper function; it sets the left and right speed in one line. This keeps the loop easy to read.

Junction and lost cases

On a real track, two special cases confuse the robot.

If both sensors see the line, this is usually a junction or a thick marking. On a simple robot the decision is easy: keep going straight. The final else in the code above does exactly this.

If both sensors see white for a long time, the robot may have lost the line completely. If you only say "go straight," the robot drives off the track. A smarter solution is to remember the last direction it saw:

If both are white for a long time
  search for the line by turning toward the last turn direction

So if the robot last saw the line on its left, then when it loses the line it turns left to try to find it again.

Test course and fixing one bug

First test the robot with the wheels in the air, holding it in your hand. Then draw a simple course on white paper with black tape or a thick marker: a straight line, then a gentle curve.

Test course and fixing one bug table
#TestExpected result
1Place it on a straight lineThe robot moves straight
2Nudge the robot slightly rightLeft sensor sees the line, it corrects left
3Drive through the gentle curveThe robot turns while following the line

One bug and its fix: the robot won't go straight

On my first try, the robot kept drifting right even while both sensors saw white. What I expected: go dead straight. What actually happened: it veered right.

Goal: The robot goes straight when both sensors see white
Problem: The robot drifts right on a straight line
Check: The two motors don't spin at the same speed at the same PWM
Fix: Add a small balance offset to the slower motor

The problem was not in the code, it was mechanical: at the same FAST value, the left motor spun a little faster than the right. Two motors are never exactly identical. When I applied a small reduction to the left motor while going straight (for example FAST - 15), the robot straightened out. This small adjustment is called trim, and it differs a little for every robot.

Mini practice

Improve the robot with your own idea. Try one of these:

  1. Change the FAST and SLOW values and watch whether the robot turns more smoothly or more sharply.
  2. Add the "lost case" logic above into real code: keep the last turn direction in a variable and search that way when the line disappears.
  3. Add a junction to the course and note what the robot does there; if you like, write a rule that slows it down at a junction.

Write your change in one sentence: what does the robot do now, and what does it do better?

Common mistakes

Forgetting the common ground

If you do not connect the GND terminals of the Arduino and the motor battery together, the driver cannot read the signals. The robot either does not move at all or behaves randomly. Common ground is the most often skipped step in this project.

Connecting a motor straight to the Arduino

If you plug a motor into an Arduino pin, the pin draws too much current and is damaged. Motors must always be powered from the driver board and a separate battery.

Assuming the sensor value

On some modules the line reads 1, on others 0. Do not trust the comparisons in the code before calibrating; measure with Serial first.

Ignoring the trim difference

Two motors never spin exactly the same at the same PWM. If the robot won't go straight, the code may not be wrong; a small trim adjustment usually fixes it.

Safety note

This robot moves, so a few rules matter. Test on a wide, empty floor and stay away from a table edge the robot could fall off. Keep fingers, hair, and cables away from the wheels and gears; spinning parts can pinch. Do your first tries at low speed and with the wheels in the air.

Always run the motors with a motor driver and a separate, low-voltage battery pack; connect the grounds of both sources together. Never use mains (wall socket) electricity. If a battery heats up, a wire smells burnt, or the robot behaves oddly, remove the battery right away. Do any step involving motors, batteries, or cutting tools together with an adult.

Lesson summary

Check questions

  1. In a line-following robot, why do we connect the motors to a motor driver rather than straight to the Arduino?
  2. When using two power sources, which connection must be common, and why?
  3. If the left sensor sees the line and the right sensor sees white, which way does the robot turn, and why?
  4. Why do we calibrate before writing code?
  5. If the robot keeps drifting to one side on a straight line, what is the first thing you should check?

Answers

  1. Motors draw more current than an Arduino pin can supply. Connected directly, the pin or board is damaged. The driver pulls power from a separate battery and feeds the motor; the Arduino only sends a small control signal.
  2. The negative terminals (GND / ground) of the two power sources must be connected together. Without a common ground, the driver cannot correctly read the level of the signal the Arduino sends, and the robot will not work properly.
  3. The robot turns left. If the left sensor touched the line, the robot has drifted right; slowing the left motor pulls it left and brings it back to the centre of the line.
  4. Because, depending on the sensor module, the line sometimes reads 1 and sometimes 0. If we compare in code without measuring, the robot may behave in reverse. Measuring with Serial shows the correct values.
  5. Motor balance. Two motors do not spin exactly the same at the same PWM; applying a small reduction (trim) to the faster motor while going straight usually solves it.

Source and verification note

For “Project: Line-Following Robot”, verification focuses on whether the relationship between Materials, wiring, and power and Why a separate battery and a motor driver? remains consistent across examples. Robot behaviour cannot be explained by code alone; mechanical structure, power system, sensor placement and surface conditions must be evaluated together. Test results should be recorded over several runs on the same course.

Next lesson

Introduction to Data and Artificial Intelligence module: We begin to explore how to gather the sensor data robots collect, make sense of it, and how a computer starts to "learn" from that data.

Start QuizBack to Robotic Systems
QUESTION POOL

Reinforce this lesson with 10 questions

This lesson has a pool of 20 questions. Each attempt selects 10 and reshuffles the choices.