Line Follower Robot using Arduino and IR Sensors
Line Follower Robot using Arduino and IR Sensors
Introduction
A Line Follower Robot is an autonomous robot that can follow a path (usually a
black line on a white surface) without human intervention. It detects the line
using infrared (IR) sensors and makes decisions to move forward, turn left, or
right based on sensor inputs. This type of robot is widely used in industrial
automation, warehouse management, and educational projects.
Block Diagram
+------------------------+
| |
| IR Sensors |
| (Left & Right Sensors) |
+-----------+------------
+-------+--------+
| |
| Arduino |
| (Controller) |
+-------+--------+
+-----------+------------+
| |
| Adafruit Motor Shield |
| (Motor Shield) |
+-----------+------------+
+----------+-----------+
| DC Motors (L & R) |
| (Left and Right) |
+----------------------+
The block diagram consists of the following basic blocks:
Arduino UNO: The main controller that reads the sensors and controls the
motors.
IR Sensors (Left and Right): Used to detect the black line.
Motor Driver (Adafruit Motor Shield): Controls the speed and direction of
two DC motors based on commands from the Arduino.
DC Motors (Left and Right Motors): Move the robot forward, left, or right.
Chassis: Physical body holding all components together.
Working:
Sensors continuously monitor the surface.
Arduino processes the sensor inputs:
o If both sensors detect white, robot moves forward.
o If left sensor detects black, robot turns left.
o If right sensor detects black, robot turns right.
o If both sensors detect black, robot stops.
Component List
1 Arduino UNO 1
3 IR Sensor Modules 2
4 BO-type DC Motors 2
5 Robot Chassis 1
6 Wheels 2
7 Castor Wheel 1
Battery Pack
8 1
(6V/12V)
As
9 Jumper Wires
needed
Hardware Connections
Left IR sensor output → Arduino analog pin A0.
Right IR sensor output → Arduino analog pin A1.
Motor Shield connections:
o Left Motor → M3 (Motor 3 pins)
o Right Motor → M4 (Motor 4 pins)
Motor Shield mounted onto Arduino UNO.
Power Supply:
o Motor shield powered through external battery (6V–12V).
o Arduino powered via USB (for testing) or external power supply.
Detailed Hardware Description
Arduino UNO
Arduino is the brain of the project. It processes inputs from IR sensors and
controls motor outputs through the motor shield.
IR Sensors
IR sensors consist of an IR LED and a photodiode. When placed over a white
surface, most infrared light is reflected, and the sensor reads a low value. When
placed over a black line, less light is reflected, and the sensor reads a higher
value.
Adafruit Motor Shield V1
The motor shield is used to easily drive two DC motors with independent speed
and direction control. It uses internal H-bridge circuits to manage the motors.
BO-type DC Motors
These motors convert electrical energy into mechanical motion. In this setup,
two motors are used — one for each wheel.
Chassis
The body structure that holds motors, sensors, Arduino, shield, and battery.
Flowchart
[Start]
↓
[Initialize Motors to 0 Speed and RELEASE]
↓
[Move Motors FORWARD at full speed for 40 ms]
↓
[Loop Start]
↓
[Read Left IR Sensor Value]
[Read Right IR Sensor Value]
↓
[Right Sensor detects black (right_value ≥ DETECT_LIMIT) AND Left Sensor does
NOT?]
↓
┌──────────────Yes──────────────┐
│ ↓
│ [turnRight()]
│ ↓
│ [Delay]
│ ↓
│ [Back to Loop]
│
No
↓
[Left Sensor detects black (left_value ≥ DETECT_LIMIT) AND Right Sensor does
NOT?]
↓
┌──────────────Yes──────────────┐
│ ↓
│ [turnLeft()]
│ ↓
│ [Delay]
│ ↓
│ [Back to Loop]
│
No
↓
[Neither Sensor detects black?]
↓
┌──────────────Yes──────────────┐
│ ↓
│ [moveForward()]
│ ↓
│ [Back to Loop]
│
No
↓
[Both Sensors detect black?]
↓
┌──────────────Yes──────────────┐
│ ↓
│ [stop()]
│ ↓
│ [Back to Loop]
│
No
↓
[Back to Loop]
Code Explanation
The code continuously reads values from the left and right IR sensors. Based on
the readings:
If both sensors detect no line (white surface) → move forward.
If left sensor detects line and right does not → turn left.
If right sensor detects line and left does not → turn right.
If both sensors detect line (both black) → stop the robot.
Motor speed and directions are carefully controlled using the Adafruit Motor
Shield commands.
Full Code
#include <AFMotor.h>
void setup() {
// Set the current speed of Left Motor to 0
motorL.setSpeed(0);
// turn off motor
motorL.run(RELEASE);
// Set the current speed of Right Motor to 0
motorR.setSpeed(0);
// turn off motor
motorR.run(RELEASE);
void loop() {
left_value = analogRead(LEFT_IR);
right_value = analogRead(RIGHT_IR);
// Right Sensor detects black line and left does not detect
if (right_value >= DETECT_LIMIT && !(left_value >= DETECT_LIMIT)) {
turnRight();
}
// Left Sensor detects black line and right does not detect
else if ((left_value >= DETECT_LIMIT) && !(right_value >= DETECT_LIMIT)) {
turnLeft();
}
// both sensors doesn't detect black line
else if (!(left_value >= DETECT_LIMIT) && !(right_value >= DETECT_LIMIT)) {
moveForward();
}
// both sensors detect black line
else if ((left_value >= DETECT_LIMIT) && (right_value >= DETECT_LIMIT)) {
stop();
}
}
void moveForward() {
if (lastDirection != 'F') {
// To provide starting push to Robot when last direction was not forward
motorR.run(FORWARD);
motorL.run(FORWARD);
motorL.setSpeed(255);
motorR.setSpeed(255);
lastDirection = 'F';
delay(20);
} else {
// If the last direction was forward
motorR.run(FORWARD);
motorL.run(FORWARD);
motorL.setSpeed(FORWARD_SPEED);
motorR.setSpeed(FORWARD_SPEED);
}
}
void stop() {
if (lastDirection != 'S') {
// When stop is detected move further one time to check if its actual stop or
not, needed when the robot turns
motorR.run(FORWARD);
motorL.run(FORWARD);
motorL.setSpeed(255);
motorR.setSpeed(255);
lastDirection = 'S';
delay(40);
} else {
// When stop is detected next time then stop the Robot
motorL.setSpeed(0);
motorR.setSpeed(0);
motorL.run(RELEASE);
motorR.run(RELEASE);
lastDirection = 'S';
}
}
void turnRight(void) {
// If first time Right Turn is taken
if (lastDirection != 'R') {
lastDirection = 'R';
// Stop the motor for some time
motorL.setSpeed(0);
motorR.setSpeed(0);
delay(BEFORE_TURN_DELAY);
// take Slight Right turn
motorL.run(FORWARD);
motorR.run(BACKWARD);
motorL.setSpeed(TURN_SLIGHT_SPEED);
motorR.setSpeed(TURN_SLIGHT_SPEED);
} else {
// take sharp Right turn
motorL.run(FORWARD);
motorR.run(BACKWARD);
motorL.setSpeed(TURN_SHARP_SPEED);
motorR.setSpeed(TURN_SHARP_SPEED);
}
delay(DELAY_AFTER_TURN);
}
void turnLeft() {
// If first time Left Turn is taken
if (lastDirection != 'L') {
lastDirection = 'L';
// Stop the motor for some time
motorL.setSpeed(0);
motorR.setSpeed(0);
delay(BEFORE_TURN_DELAY);
// take slight Left turn
motorR.run(FORWARD);
motorL.run(BACKWARD);
motorL.setSpeed(TURN_SLIGHT_SPEED);
motorR.setSpeed(TURN_SLIGHT_SPEED);
} else {
// take sharp Left turn
motorR.run(FORWARD);
motorL.run(BACKWARD);
motorL.setSpeed(TURN_SHARP_SPEED);
motorR.setSpeed(TURN_SHARP_SPEED);
}
delay(DELAY_AFTER_TURN);
}