One-sentence summary
A line-following robot uses two infrared sensors to see the line on the floor and stays on it by adjusting the speed of two motors; in this lesson we build that logic all the way from an algorithm to a working sketch.
Why does it matter?
In factories, hospitals and warehouses, robots follow strips painted on the floor. They carry a load from one point to another with nobody steering them. All of them rely on one simple idea: the robot measures where it is relative to the line and keeps correcting its path.
In this project we learn something new: the robot no longer just says "stop" or "go." It steers by running its two motors at different speeds. If one motor slows down, the robot turns toward that side. This is how real robots steer.
We also use a motor driver for the first time. Motors draw far more current than LEDs. That is why connecting them directly to the Arduino is wrong. This lesson's safety note is all about exactly that.
How does the robot "see" the line?
The infrared line sensor
An infrared line sensor (IR line sensor) sends out invisible infrared light and measures how much bounces back from the floor. A white surface reflects the light well; a black line absorbs it.
The sensor gives us a single digital answer:
- One value when it sees the white surface (we treat this as
LOWin this lesson). - The other value when it sees the black line (
HIGH).
Note: Some sensor modules report this the other way around. If the robot behaves in reverse, swap the sensor logic (LOW/HIGH).
Two sensors, like two eyes
We place two sensors at the front, lined up a little to the left and a little to the right of the line. When the robot is right on the line, both sensors see white and the line runs between them.
If the robot drifts left, the black line moves under the right sensor. If it drifts right, the line moves under the left sensor. So whichever sensor sees the line tells us the robot has drifted the other way and needs to turn toward that side.
Everyday example
Your eyes are closed, there is a curb under your foot, and you are trying to follow it. As soon as your foot slips off the edge, you correct at once. The robot does exactly this, except instead of a foot it has two sensors and two motors.
Steering with two motors
Different speed = a turn
The robot has two wheels and two motors. If both spin at the same speed, the robot goes straight. If we slow the left motor, the left side falls behind and the robot turns left. If we slow the right motor, it turns right.
| Left sensor | Right sensor | Meaning | Action |
|---|---|---|---|
| White | White | Line in the centre | Go straight |
| On line | White | Drifted left | Turn left |
| White | On line | Drifted right | Turn right |
| On line | On line | Junction / thick line | Go straight |
Everyday example
In a car, if you start drifting out of your lane you turn the wheel back a little. The robot does the same: it makes small, constant corrections. Thousands of tiny corrections, rather than one big move, keep it on the line.
From algorithm to sketch
First, the pseudocode
Start
Repeat forever:
left = read left sensor
right = read right sensor
If left is white and right is white
run both motors forward (go straight)
Else if only the left is on the line
slow the left motor (turn left)
Else if only the right is on the line
slow the right motor (turn right)
Else
go straight
Wiring list
- A motor driver (for example an L298N module) with two DC motors.
- A separate battery pack for the motors (for example 6 x AA). Not from the Arduino!
ENA→ D5 (PWM, left speed),IN1→ D7,IN2→ D8.ENB→ D6 (PWM, right speed),IN3→ D12,IN4→ D13.- Left sensor OUT → D2, right sensor OUT → D3.
- The driver's GND and the Arduino's GND must be shared.
Pin definitions and setup
// Motor driver pins
const int ENA = 5; // Left motor speed (PWM)
const int IN1 = 7;
const int IN2 = 8;
const int ENB = 6; // Right motor speed (PWM)
const int IN3 = 12;
const int IN4 = 13;
// Line sensors
const int LEFT_SENSOR = 2;
const int RIGHT_SENSOR = 3;
const int SPEED = 150; // Base speed, 0-255
void setup() {
pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
pinMode(ENB, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT);
pinMode(LEFT_SENSOR, INPUT);
pinMode(RIGHT_SENSOR, INPUT);
// Set both motors to the forward direction
digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW);
Serial.begin(9600);
}
The main loop
void setMotors(int leftSpeed, int rightSpeed) {
analogWrite(ENA, leftSpeed);
analogWrite(ENB, rightSpeed);
}
void loop() {
int left = digitalRead(LEFT_SENSOR);
int right = digitalRead(RIGHT_SENSOR);
if (left == LOW && right == LOW) {
setMotors(SPEED, SPEED); // Go straight
} else if (left == HIGH && right == LOW) {
setMotors(0, SPEED); // Turn left
} else if (left == LOW && right == HIGH) {
setMotors(SPEED, 0); // Turn right
} else {
setMotors(SPEED, SPEED); // Junction: go straight
}
}
We set motor speed between 0 and 255 with analogWrite. 0 stops it, 255 is full speed. The speed goes through the driver, not straight from the pin.
Mini practice
Build a test track
On a white piece of cardboard, lay a gently curving closed loop of thick black tape (about 2 cm wide). Use soft curves instead of sharp corners; the robot loses the line on tight turns.
- Place the robot on the line so both sensors see white.
- First test the sensors without the motor battery connected: print the values with
Serial.printlnand move your hand in front of the sensors. - Then connect the motor battery and release the robot on the track at a low
SPEED(120–150). - If the robot loses the line, lower
SPEEDor move the sensors closer to the line.
Non-blocking status printing (enhancement)
If we use delay, the robot goes "blind" during that time. It is better to print a status now and then using millis:
unsigned long lastPrint = 0;
void printStatus(int left, int right) {
if (millis() - lastPrint >= 300) {
lastPrint = millis();
Serial.print("Left: "); Serial.print(left);
Serial.print(" Right: "); Serial.println(right);
}
}
If you call this function inside loop, the motors keep running without ever pausing.
Common mistakes
The robot won't go straight, it keeps drifting to one side
This is the most common problem. Two DC motors are never exactly the same; one spins a little faster than the other. The fix is to give the slower motor a bit more power (trim):
const int LEFT_SPEED = 150;
const int RIGHT_SPEED = 165; // If the right motor is slow, raise it a little
// setMotors(LEFT_SPEED, RIGHT_SPEED);
Adjust the values by trial until the robot drives straight.
Wiring the sensor logic backwards
If the robot runs away from the line, the sensor's white/black answer is the opposite of what you expected. Swap HIGH and LOW in the code.
Forgetting the shared GND
If the motor battery and the Arduino do not share a GND, the driver won't understand the commands. Always tie the GND line together.
Starting at too high a speed
At high speed the robot misses the line before it can take a curve. Always start slow and speed up as it stays on the line.
Safety note
- Never connect motors directly to the Arduino pins. Motors draw high current and can burn the pin. Always use a motor driver (for example an L298N).
- Give the motors a separate power source (a battery pack). Power the Arduino from USB or its own battery; connect the motor battery to the driver's motor input.
- Use only low-voltage battery packs. Do not use mains (wall) electricity.
- The motor driver can get warm; do not touch its metal part while it runs.
- Do your first test with the robot held up in the air, wheels off the ground. That way an unexpected move won't knock anyone over.
- This project should be built and tested with an adult supervising. Check the wiring twice before applying power.
Lesson summary
- A line-following robot uses two infrared sensors to measure where the line is.
- It steers by running its two motors at different speeds: slow one motor and it turns that way.
- The logic rests on four cases: straight, turn left, turn right, junction.
- Motors need a motor driver and a separate power source; never drive them from an Arduino pin.
- The common cause of "it won't go straight" is a speed difference between the motors, fixed with trim.
Check questions
- What should the robot do when both sensors see white?
- If the black line is under the left sensor, which way has the robot drifted and what should it do?
- What does
analogWrite(ENA, 0)mean? - Why don't we connect the motors directly to an Arduino pin?
- If the robot keeps drifting right (even when it is not on the line), what is the likely cause and fix?
Answers
- It should go straight; the line is centred, so both motors run forward at equal speed.
- The robot has drifted right (the line became visible on the left) and should turn left; it slows the left motor.
- It sets the left motor speed to 0, that is, it stops the left motor.
- Motors draw high current; the pin cannot supply it and gets damaged. That is why a motor driver and a separate power source are needed.
- The left motor is probably faster than the right. The fix is to balance the motor speeds with trim (give the slower motor a bit more power).
Source and verification note
For “Project: Line-Following Robot Logic”, verification focuses on whether the relationship between How does the robot "see" the line? and Two sensors, like two eyes remains consistent across examples. Pin, voltage and current limits can differ between Arduino-compatible boards. Compiling code does not guarantee a safe circuit; loads such as motors and servos require a suitable driver and external power where appropriate.
Next lesson
Project: Mini Automatic Watering Prototype