Building a PID Line Follower Robot with Arduino

Line Follower Robot
In this tutorial, we'll build a more intelligent and smooth line follower robot using PID control. Instead of making hard turns or reacting late, a PID-controlled robot adjusts motor speeds dynamically to stay on track with precision.
🔍 What is PID Control?
PID stands for Proportional, Integral, and Derivative. It’s a control system algorithm used in robotics to reduce error:
- P (Proportional): Reacts to how far off the robot is from the line
- I (Integral): Accumulates past error (optional here)
- D (Derivative): Reacts to how quickly the error is changing
This method provides smoother motion and higher accuracy compared to simple conditional logic.
🧰 Components Required
- Arduino Uno/Nano
- L293D or L298N Motor Driver
- BO Motors with Wheels (x2)
- IR Sensors (x3) – Left, Center, Right
- Chassis and Power Supply (7.4V–12V)
- Jumper Wires and Battery Holder
🔌 Circuit Diagram

Line Follower Robot Circuit Diagram
🔗 Pin Mapping (Example)
- Motor A: IN1 = 7, IN2 = 6, ENA = 9
- Motor B: IN3 = 5, IN4 = 4, ENB = 10
- IR Sensors: Left = 3, Center = 8, Right = 2
💻 Arduino PID Code
Copy and upload the code below to your Arduino:
// Motor pins
const int in1 = 7, in2 = 6;
const int in3 = 5, in4 = 4;
const int ena = 9, enb = 10;
// IR sensor pins
const int irl = 3;
const int irc = 8;
const int irr = 2;
// PID constants
float Kp = 25;
float Ki = 0;
float Kd = 15;
int baseSpeed = 120;
int maxSpeed = 255;
float error = 0;
float previousError = 0;
float integral = 0;
void setup() {
pinMode(in1, OUTPUT); pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT); pinMode(in4, OUTPUT);
pinMode(ena, OUTPUT); pinMode(enb, OUTPUT);
pinMode(irl, INPUT); pinMode(irc, INPUT); pinMode(irr, INPUT);
}
void loop() {
int left = digitalRead(irl);
int center = digitalRead(irc);
int right = digitalRead(irr);
if (left == 0 && center == 1 && right == 1) error = -1;
else if (left == 0 && center == 0 && right == 1) error = -0.5;
else if (left == 1 && center == 0 && right == 1) error = 0;
else if (left == 1 && center == 0 && right == 0) error = 0.5;
else if (left == 1 && center == 1 && right == 0) error = 1;
else if (left == 0 && center == 0 && right == 0) error = 0;
else {
stopMotors();
return;
}
integral += error;
float derivative = error - previousError;
float correction = Kp * error + Ki * integral + Kd * derivative;
previousError = error;
int leftSpeed = constrain(baseSpeed - correction, 0, maxSpeed);
int rightSpeed = constrain(baseSpeed + correction, 0, maxSpeed);
moveForward(leftSpeed, rightSpeed);
}
void moveForward(int lSpeed, int rSpeed) {
digitalWrite(in1, HIGH); digitalWrite(in2, LOW);
digitalWrite(in3, HIGH); digitalWrite(in4, LOW);
analogWrite(ena, lSpeed); analogWrite(enb, rSpeed);
}
void stopMotors() {
digitalWrite(in1, LOW); digitalWrite(in2, LOW);
digitalWrite(in3, LOW); digitalWrite(in4, LOW);
analogWrite(ena, 0); analogWrite(enb, 0);
}
📏 PID Tuning Tips
- Start with:
Kp = 25
,Ki = 0
,Kd = 15
- If it wobbles too much, increase
Kd
- If it reacts too slowly, increase
Kp
- Leave
Ki
at 0 unless you see long-term drift
🧪 Testing
Place the robot on a dark line over a light surface. It should track the line smoothly, adapting dynamically on curves. If not, recheck sensor alignment and PID values.
📦 Final Notes
Congratulations! You've now built a professional-grade PID line follower. Experiment with 5-sensor versions, analog sensors, or even Bluetooth control for next-level upgrades.
Tip: For affordable components, consider MakerBazar, Robu.in, or ElectronicsComp instead of Amazon/Flipkart. They’re cheaper but might take 7–15 days for delivery.