Guide to Autonomous Line Follower Robot Using Arduino
- Get link
- X
- Other Apps
Autonomous Line Follower Robot Using Arduino
A step‑by‑step tutorial to build, program, and fine‑tune a DIY line follower robot with Arduino.
Introduction
Line follower robots are classic projects for beginners and intermediate hobbyists. They teach you how to read sensor data, control motors, and implement simple feedback loops. In this guide you will build an autonomous line follower robot using Arduino, from hardware selection to fully functional code.
By the end of the tutorial you will have a compact robot that can:
- Detect a black tape line on a white surface.
- Adjust its speed and direction in real‑time.
- Recover from bends and intersections automatically.
Required Parts & Materials
Arduino Uno (or Nano)
Microcontroller board for reading sensors and driving motors.
L298N Motor Driver
Dual H‑bridge to control two DC motors with speed (PWM).
IR Sensor Array (QTR‑8RC or 5‑sensor module)
Detects contrast between the line and the background.
Chassis & Wheels
Lightweight plastic or acrylic frame with two driven wheels and a caster.
Battery Pack (6 V – 9 V)
Provides power to the Arduino and motors.
Step 1 – Wiring Diagram
Before soldering, lay out the components on a breadboard and follow the connections below.
- Motor driver: ENA → PWM pin 5, ENB → PWM pin 6; IN1 → pin 7, IN2 → pin 8, IN3 → pin 9, IN4 → pin 10.
- IR sensor array: VCC → 5 V, GND → GND, OUT pins → A0‑A4 (analog inputs).
- Power: Connect the battery’s + to VIN (or motor driver’s +12 V) and GND to the common ground.
Step 2 – Assemble the Chassis
Secure the motor driver, Arduino, and sensor array onto the chassis. Keep the sensor module close to the front edge, about 10 mm above the floor, to maintain reliable line detection.
- Mount the two DC motors onto the chassis using the provided brackets.
- Attach the caster wheel at the rear center for balance.
- Fix the IR sensor array with double‑sided tape or screws, ensuring the sensor faces downward.
- Route the wiring neatly to avoid entanglement with rotating wheels.
Step 3 – Arduino Sketch (PID Line Following)
The following code reads five analog sensors, computes a position error, and applies a simple PID controller to adjust motor speeds.
// ---------- Pin Definitions ----------
const uint8_t sensorPins[5] = {A0, A1, A2, A3, A4};
const uint8_t ENA = 5; // PWM left motor
const uint8_t ENB = 6; // PWM right motor
const uint8_t IN1 = 7; // Left motor direction
const uint8_t IN2 = 8;
const uint8_t IN3 = 9; // Right motor direction
const uint8_t IN4 =10;
// ---------- PID Constants ----------
float Kp = 0.8; // Proportional gain
float Ki = 0.0; // Integral gain
float Kd = 0.12; // Derivative gain
float setPoint = 0; // Desired position (center)
float integral = 0;
float previousError = 0;
// ---------- Helper Functions ----------
void setMotorSpeed(int leftSpeed, int rightSpeed) {
// Left motor
digitalWrite(IN1, leftSpeed >= 0);
digitalWrite(IN2, leftSpeed < 0);
analogWrite(ENA, constrain(abs(leftSpeed), 0, 255));
// Right motor
digitalWrite(IN3, rightSpeed >= 0);
digitalWrite(IN4, rightSpeed < 0);
analogWrite(ENB, constrain(abs(rightSpeed), 0, 255));
}
int readLinePosition() {
long weightedSum = 0;
long total = 0;
for (uint8_t i = 0; i < 5; i++) {
int val = analogRead(sensorPins[i]); // 0 (black) – 1023 (white)
int thresh = 500; // simple threshold
int binary = (val < thresh) ? 1 : 0; // 1 = line detected
weightedSum += binary * (i * 2000); // positions: 0‑8000
total += binary;
}
if (total == 0) return 0; // line lost – keep last position
return (int)(weightedSum / total - 4000); // centre = 0
}
// ---------- Setup ----------
void setup() {
pinMode(ENA, OUTPUT); pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT);
for (uint8_t i = 0; i < 5; i++) pinMode(sensorPins[i], INPUT);
Serial.begin(115200);
}
// ---------- Main Loop ----------
void loop() {
int position = readLinePosition(); // -4000 … +4000
float error = (float)position; // error vs centre
// PID calculations
integral += error;
float derivative = error - previousError;
float correction = Kp*error + Ki*integral + Kd*derivative;
previousError = error;
// Base speed and correction
int baseSpeed = 150;
int leftSpeed = baseSpeed + correction;
int rightSpeed = baseSpeed - correction;
setMotorSpeed(leftSpeed, rightSpeed);
// Debug output
Serial.print("Pos:"); Serial.print(position);
Serial.print(" Corr:"); Serial.println(correction);
delay(10);
}
Tips for tuning:
- Start with
Kp = 0.6,Kd = 0.1. Adjust until the robot follows smoothly. - If the robot oscillates, increase
Kdor reduceKp. - Use
Kionly for long straight sections where drift accumulates.
Step 4 – Calibrate the Sensors
Because surface reflectivity varies, calibrate each sensor to define a reliable threshold.
- Upload the
Calibrationsketch (replace the PID code temporarily). - Place the robot on a white surface; record the maximum analog values.
- Place it on a black line; record the minimum values.
- Set the threshold for each sensor as
(max+min)/2and update thereadLinePosition()function accordingly.
Pro tip: Store the thresholds in EEPROM so you only calibrate once.
Step 5 – Testing & Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Robot drifts off line | Threshold too high or PID gain low | Re‑calibrate sensors; increase Kp. |
| Oscillates wildly | Excessive Kp or insufficient Kd |
Decrease Kp, raise Kd. |
| Motors stall on sharp turns | Base speed too high | Lower baseSpeed or increase motor voltage. |
| No response from sensors | Wiring error or wrong pin numbers | Double‑check connections and Arduino pin mapping. |
Advanced Enhancements (Optional)
- Bluetooth Control: Add an HC‑05 module to switch between autonomous and manual mode.
- OLED Display: Show live sensor values, error term, and PID output.
- Battery Monitoring: Use a voltage divider to display remaining battery percentage.
- Path Memory: Store line coordinates in an SD card for later replay.