Arduino Line Following Bot

by 1030278 in Circuits > Arduino

96 Views, 1 Favorites, 0 Comments

Arduino Line Following Bot

IMG_2662.jpg

Welcome to my Instructible on a line follower bot controlled by an Arduino and a motor module!


This project demonstrates how to build a simple line following robot using an Arduino Uno, two FM90 DC motors, an L298N motor driver, and two TCRT5000 infrared sensors. When finished, the robot will be able to autonomously follow a strip of black electrical tape by detecting the contrast between the dark tape and the light-coloured floor.


The robot uses differential steering, meaning it changes direction by varying the movement of its left and right wheels. The design is built on an aluminum chassis with two powered front wheels and a freely rotating rear caster wheel.


This project introduces concepts such as sensor feedback, motor control, wiring troubleshooting, and mechanical design.

Supplies

IMG_2662.jpg

For this project, you'll need:


Electronics:

  1. Arduino Uno
  2. L298N Motor Driver Module
  3. 2 × TCRT5000 Infrared Reflective Sensors
  4. 2 × FM90 DC Motors in Micro Servo Body
  5. 12 V Rechargeable Battery
  6. Mini Breadboard (or regular)
  7. Jumper Wires (male to female)
  8. Male to male wires (if needed)
  9. Female to female wires (if needed)
  10. Regular wires
  11. Electrical Tape


Mechanical Components:

  1. Aluminum Robot Chassis
  2. 2 × Wheels
  3. Rear Caster Wheel
  4. Spacers/Standoffs
  5. Washers
  6. Mounting Screws and Nuts
  7. Counterweight (if needed)


Tools:

  1. Phillips Screwdriver
  2. Flathead Screwdriver
  3. Wire Cutters
  4. Computer with Arduino IDE
  5. USB Cable

Inspect the Chassis

IMG_2679.jpg
IMG_2674.jpg
IMG_2667.jpg

The robot is built on an aluminum chassis that includes pre-drilled mounting holes and motor slots. These features simplify assembly as no drilling, cutting, or 3D printing is required.


Before installing components, be sure to identify:

  1. Motor mounting slots
  2. Electronics mounting holes
  3. Battery placement area
  4. Rear caster wheel mounting location


Because the mounting holes are predetermined, component placement options are limited. This became an important factor later when balancing the robot.

Install the Motors and Wheels

IMG_2673.jpg
IMG_2666.jpg
IMG_2664.jpg
IMG_2668.jpg

The chassis contains dedicated slots for the FM90 DC motors.


Procedure


  1. Remove wheels from both motors by unscrewing.
  2. Insert the left motor into the left motor slot.
  3. Insert the right motor into the right motor slot.
  4. Align the mounting holes.
  5. Secure the motors using screws.


Important Tip


Test each motor before installation.

Connect each motor (with wheel) briefly to a power source and ground, and verify that:

  1. It spins smoothly.
  2. There is no excessive noise.
  3. It does not stall unexpectedly.


A faulty motor can make troubleshooting extremely difficult later. Additionally, the motor should spin regardless of whether you connect power to the negative or positive, as motors can spin forward and backward.

Attach the Wheels

FSIIMESMPX8RZ32.jpg
F8PBZ24MPX8RZ1C.jpg

Remember the last step where you unscrewed the wheels? You can reconnect them in this step now that the motors are in place.


Attach one wheel to each motor shaft and screw them on using the Phillips screwdriver.


Ensure both wheels are fully seated, rotate freely, and have little to no wobble.

Install Rear Caster Wheel

IMG_2677.jpg
IMG_2676.jpg

A caster wheel was mounted at the rear of the chassis, and unlike drive wheels, the caster wheel is not powered. It pivots freely in any direction and provides support while allowing the robot to turn smoothly.


Secure the caster wheel by positioning it at the appropriate holes and using spacers to screw them in. Simply place the spacer above the hole on the chassis and screw it in from the bottom.

Mount the Arduino Uno

IMG_2681.jpg
IMG_2680.jpg

The Arduino Uno serves as the robot's controller.

The Arduino was mounted using spacers and screws attached to the chassis mounting holes.


To mount it, position one of the Arduino's corner screw holes directly above a precut hole on the chassis. Place a spacer in between these two holes and screw on both ends.


The spacers elevate the Arduino above the chassis and prevent electrical shorts.


It's important to remember that because the chassis contained fixed mounting locations, the Arduino could not be placed exactly where desired.

Mount the L298N Motor Driver

IMG_2685.jpg

The L298N motor driver controls the motors based on commands from the Arduino.


Like the Arduino, the motor driver was mounted using spacers and screws, and mounting it is the same as mounting the Arduino: Place a screw hole above a chassis hole, insert a spacer in between the two holes, and screw in on both ends.


The available mounting holes forced the module into a less-than-ideal position, which contributed to uneven weight distribution.


Tip: Now that you've installed both the L298N and Arduino, try to pivot and adjust their position so that the weight is evenly distributed across the chassis so that you won't have to deal with any issues regarding uneven wheel traction later on. Once you've found a position you like, fasten the screws and test to make sure the Arduino and L298N don't wiggle.

Install the Breadboard

IMG_2691.jpg

A mini breadboard was attached directly to the chassis using tape, although you can use a full-size breadboard as well. However, a full-size breadboard will make it harder to fit all components on the chassis.


To secure the breadboard onto the chassis, choose an appropriate location that isn't already used and tape the breadboard to that location.


The breadboard will be your hub for most power distribution and sensor connections.


Ensure that the breadboard is firmly attached before driving the robot.

Mount the Infrared Sensors

IMG_2693.jpg
IMG_2665.jpg
IMG_2698.jpg

This is one of the trickiest parts about this project, as it's paramount that the Infared Sensors are both close to the floor, and spaced apart properly to account for the width of the electrical tape and some error.


The line-following system uses two TCRT5000 infrared reflective sensors. The sensors were mounted at the very front of the chassis between the two wheels.


These sensors emit infrared light, where white surfaces reflect more light and black surfaces reflect less. The Arduino reads the differences between these reflections to determine the sensor's position relative to the line.


Height:

Sensor placement is extremely important. To position the sensors as close as possible:

  1. Spacers were used for mounting.
  2. Washers were added to fine-tune the height.


The final sensor position placed them only a few millimetres above the floor, allowing for more accurate and reliable line detection.


Mounting the sensors onto the chassis is similar to steps 5 and 6, except now you're just doing it to the underside rather than on top. Locate the cut-out section between the wheels at the front of the chassis and position the sensor's screw holes directly under it. Insert a spacer in between and then screw on either side just enough so that the sensor doesn't fall out. Slide the sensors and spacers along the cutout until the distance between the two sensors is a bit longer than the width of the electrical tape. If the sensor isn't close enough to the floor, insert some washers into the spacers until a desirable height is reached.

Mount the Battery

IMG_2694.jpg

Now that every other component is mounted properly, you can look for a suitable location to mount the battery case. Make sure that this location is close to the L298N module.


To mount the battery, take the battery case and tape it to a chosen location on the chassis. A 12V battery will soon be able to be inserted into this case, powering the bot.

Wiring the Robot: Sensors

Screenshot 2026-06-13 101431.png

NOTE: Almost all wires in this build require male-to-female connections. However, if you are short on these specific types of wires, you can simply take a male-to-male wire and connect it to a female-to-female wire. Use electrical tape to secure the connection... Congrats! You've just made a male-to-female wire!


Power Connections


Left Sensor - (male-to-female wires)

  1. Connect the VCC pin of the left sensor to the positive power rail on the breadboard.
  2. Connect the GND pin of the left sensor to the negative power rail on the breadboard.
  3. Connect the OUT pin of the left sensor to Arduino Digital Pin 4.


Right Sensor - (male-to-female wires)

  1. Connect the VCC pin of the right sensor to the positive power rail on the breadboard.
  2. Connect the GND pin of the right sensor to the negative power rail on the breadboard.
  3. Connect the OUT pin of the right sensor to Arduino Digital Pin 2.


Breadboard Power - (regular wires)

  1. Connect the Arduino 5V to the positive breadboard rail.
  2. Connect the Arduino GND to the negative breadboard rail.


This allows both sensors to receive power from the breadboard while sending their output signals directly to the Arduino.

Wiring the Robot: L298N Module

Screenshot 2026-06-13 090456.png
Screenshot 2026-06-13 091618.png

The L298N motor driver receives commands from the Arduino and controls both motors.

NOTE: The ENA and ENB connections on the L298N module require you to remove the case. To do this, simply take pliers or tweezers and pull the black caps off, revealing the pins underneath.


Control Signal Connections

Connect the following pins from the Arduino to the L298N:


Arduino Pin L298N Pin

Pin 5 | IN1

Pin 6 | IN2

Pin 10 | IN3

Pin 11 | IN4

Pin 9 | ENA

Pin 3 | ENB


ENA controls the speed of the left motor while ENB controls the speed of the right motor.

IN1 and IN2 control the direction of the left motor, while IN3 and IN4 control the direction of the right motor.


Power Connections

  1. Connect the positive terminal of the 12V battery to the +12V terminal on the L298N.
  2. Connect the negative terminal of the battery to the GND terminal on the L298N.


Arduino Connections

  1. Connect one Arduino GND pin to the GND terminal on the L298N with a regular wire. There should be two ground wires in the ground screw terminal of the L298N.
  2. Connect the 5V output of the L298N (leftmost screw terminal) to the Vin port of the Arduino. This will give the Arduino power.



Uploading Code

IMG_2695.jpg
Screenshot 2026-06-13 101919.png

Before wiring the motors, you need to upload the code to the Arduino. This allows you to immediately test motor direction after wiring and make corrections on the spot.


How the code works:

The two IR sensors continuously read the floor beneath them. Based on what they detect, the Arduino tells the motors what to do:

  1. Both sensors on the line -- drive forward
  2. Only left sensor on the line -- turn left to correct
  3. Only the right sensor on the line -- turn right to correct
  4. Neither sensor on the line -- stop


The SPEED variable controls how fast the motors spin. It accepts values from 0 to 255. In code, vspeed controls forward speed and tspeed controls turn speed. Good starting values are 40 and 100, respectively. You can tune this later during testing.


To upload:

  1. Install the Arduino IDE on your computer if you haven't already
  2. Copy the full code below into a new sketch
  3. Connect your Arduino to your computer via USB
  4. Click Upload

Once uploaded, the Arduino is ready. You can now wire the motors in the next step and immediately verify their direction.


Important: When uploading, make sure that the correct port and Arduino are selected (red arrow). Once the code is finished and you've verified the correct settings, click the upload button (red square).


Code (I took inspiration from "Line Following Robot | Arduino Project Hub"):


// --- PIN SETUP ---
// Initializing the variables

int sr = 2; // right IR sensor output
int sl = 4; // left IR sensor output

int mr1 = 10; // right motor wire 1
int mr2 = 11; // right motor wire 2
int ml1 = 5; // left motor wire 1
int ml2 = 6; // left motor wire 2

int enr = 3; // right motor speed (PWM)
int enl = 9; // left motor speed (PWM)

int led = 13;

// --- SPEED SETTINGS ---
int vspeed = 40; // how fast it goes straight (0-255)
int tspeed = 100; // how fast it turns (usually higher than vspeed)
int tdelay = 20; // how many milliseconds it commits to a turn before checking sensors again

// sensor readings get stored here each loop
int svr = 0;
int svl = 0;

// tracks which way the robot last turned so it can search if it loses the line
int lastTurn = 0; // -1 = last turned left, 1 = last turned right

void setup() {
// tell Arduino which pins are outputs (motors) and which are inputs (sensors)
pinMode(mr1, OUTPUT);
pinMode(mr2, OUTPUT);
pinMode(ml1, OUTPUT);
pinMode(ml2, OUTPUT);
pinMode(led, OUTPUT);
pinMode(sr, INPUT);
pinMode(sl, INPUT);

Serial.begin(9600); // start serial so we can monitor sensor readings for tuning

delay(5000); // 5 second pause so you have time to put the robot down before it starts
}

void loop() {
svr = digitalRead(sr);
svl = digitalRead(sl);

// print sensor state each loop so we can debug and tune in Serial Monitor
Serial.print("L:"); Serial.print(svl);
Serial.print(" R:"); Serial.println(svr);

// both on black tape = centered, go straight
if (svl == LOW && svr == LOW) {
cruiseAhead();

// left on black, right on white = drifted right, correct left
} else if (svl == HIGH && svr == LOW) {
correctLeft();

// right on black, left on white = drifted left, correct right
} else if (svl == LOW && svr == HIGH) {
correctRight();

// both on white = lost the line completely, spin toward last known direction to find it again
} else {
searchLine();
}
}

void cruiseAhead() {
// both motors spin forward at the same speed
// LOW/HIGH combo on the IN pins determines direction
// these are reversed from default because of how the motors are physically wired
digitalWrite(mr1, LOW); digitalWrite(mr2, HIGH);
digitalWrite(ml1, LOW); digitalWrite(ml2, HIGH);
analogWrite(enr, vspeed); // set right motor speed
analogWrite(enl, vspeed); // set left motor speed
}

void backward() {
// both motors spin backward, exact opposite of forward
digitalWrite(mr1, HIGH); digitalWrite(mr2, LOW);
digitalWrite(ml1, HIGH); digitalWrite(ml2, LOW);
analogWrite(enr, vspeed);
analogWrite(enl, vspeed);
}

void correctRight() {
// one motor goes forward, other goes backward = robot pivots right on the spot
// runs at tspeed which is higher for snappier corrections
digitalWrite(mr1, HIGH); digitalWrite(mr2, LOW);
digitalWrite(ml1, LOW); digitalWrite(ml2, HIGH);
analogWrite(enr, tspeed);
analogWrite(enl, tspeed);
delay(tdelay); // hold the turn for tdelay ms before checking sensors again
lastTurn = 1; // remember we last turned right
}

void correctLeft() {
// mirror of correctRight(), pivots left instead
digitalWrite(mr1, LOW); digitalWrite(mr2, HIGH);
digitalWrite(ml1, HIGH); digitalWrite(ml2, LOW);
analogWrite(enr, tspeed);
analogWrite(enl, tspeed);
delay(tdelay);
lastTurn = -1; // remember we last turned left
}

void searchLine() {
// lost the line on both sides, spin in the last known direction to recover it
// this beats just stopping because the robot actively hunts for the line again
if (lastTurn == 1) {
correctRight();
} else {
correctLeft();
}
}

void stop() {
// cut power to both motors by setting enable pins to 0
analogWrite(enr, 0);
analogWrite(enl, 0);
}

Wiring the Robot: Motors

Screenshot 2026-06-13 102528.png

The two FM90 DC motors connect directly to the output terminals of the L298N.


Left Motor

Connect the two wires from the left motor to the L298N's:

  1. OUT1
  2. OUT2


Right Motor

Connect the two wires from the right motor to the L298N's:

  1. OUT3
  2. OUT4


If the motors are spinning in the wrong direction, don't worry. That's what we will be correcting in the next step!


Now that you're done wiring the robot, the final result should look similar to:


Correcting Motor Direction

IMG_2692.jpg

During testing, the motors initially rotated in the wrong directions.


To solve this issue, change the orientation of the wiring from the outputs of the L298N module to the motor, or recode the direction logic in the Arduino code.

Either solution is viable, and it depends largely on the builder's preference.


If you prefer to fix the direction in code rather than rewiring, locate the forward() function:

void forward() {
digitalWrite(mr1, LOW); digitalWrite(mr2, HIGH);
digitalWrite(ml1, LOW); digitalWrite(ml2, HIGH);
analogWrite(enr, vspeed);
analogWrite(enl, vspeed);
}


For each motor, swapping HIGH and LOW reverses its direction:

// Before (spins one way)
digitalWrite(mr1, LOW); digitalWrite(mr2, HIGH);

// After (spins opposite way)
digitalWrite(mr1, HIGH); digitalWrite(mr2, LOW);


Apply the same swap to ml1/ml2 if the left motor needs reversing. Do this for all four motor functions: forward(), backward(), right(), and left().

Re-upload the code after making changes and test again.


Always verify motor direction before beginning line-following tests.

Balancing the Bot

IMG_2688.jpg

One unexpected problem involved uneven traction.


One wheel consistently maintained better contact with the floor and produced more forward motion than the other wheel.


This caused the robot to drift even when both motors were running.


Cause

The fixed mounting locations forced the Arduino and motor driver into positions that created an uneven weight distribution.

Solution

A counterweight was added to the lighter side of the chassis.


After adding the counterweight:

  1. Both wheels maintained better contact with the floor.
  2. Traction became more consistent.
  3. The robot drove significantly straighter.


This demonstrates the importance of proper weight distribution in mobile robotics.

Testing

IMG_2697.jpg
IMG_2699.jpg

The robot was tested on a smooth, white marble-like floor.

The line was created using black electrical tape.

This combination worked well because the sensors could clearly distinguish between the dark tape and the light floor.


Testing Procedure


  1. Place the robot over the tape.
  2. Turn on the power.
  3. Observe the sensor responses.
  4. Adjust sensor height if needed.
  5. Verify turning behaviour.


Sensor Calibration

IMG_2698.jpg

The TCRT5000 sensors include adjustable potentiometers (white knobs with a line across the middle for flathead).


Calibration can improve:

  1. Detection accuracy
  2. Response speed
  3. Reliability under different lighting conditions


To calibrate sensors, turn the potentiometers with a flathead until an optimal test result is produced.


Always calibrate sensors on the same surface that will be used during operation.

Troubleshooting

IMG_2696.jpg

Robot Does Not Move

  1. Check battery voltage.
  2. Verify power connections.
  3. Ensure the motor driver is receiving power.


Robot Turns the Wrong Direction

  1. Verify motor wiring.
  2. Reverse motor logic in the code.


Robot Loses the Line

  1. Lower the sensors.
  2. Reposition the sensors.
  3. Calibrate the TCRT5000 modules.


Robot Drifts to One Side

  1. Check wheel traction.
  2. Verify motor operation.
  3. Adjust weight distribution.


Robot Stops Randomly

  1. Inspect all wiring connections.
  2. Secure loose wires using electrical tape.
  3. Verify jumper wire connections.