Guide to Autonomous Line Follower Robot Using Arduino

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.

Wiring diagram for line follower robot
Figure 1: Complete wiring between Arduino, L298N, IR sensors, and motors.
  • 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.

  1. Mount the two DC motors onto the chassis using the provided brackets.
  2. Attach the caster wheel at the rear center for balance.
  3. Fix the IR sensor array with double‑sided tape or screws, ensuring the sensor faces downward.
  4. 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 Kd or reduce Kp.
  • Use Ki only for long straight sections where drift accumulates.

Step 4 – Calibrate the Sensors

Because surface reflectivity varies, calibrate each sensor to define a reliable threshold.

  1. Upload the Calibration sketch (replace the PID code temporarily).
  2. Place the robot on a white surface; record the maximum analog values.
  3. Place it on a black line; record the minimum values.
  4. Set the threshold for each sensor as (max+min)/2 and update the readLinePosition() 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.