Introduction: Arduino Autonomous Line Following Robot | MRU | BCIS

For this project, we have decided to design and implement an 'Autonomous Line Following Robot' utilizing the Arduino Uno Board. The scope of the robot is to follow a 'black' line drawn on a white surface.

The concept involves working with Infrared Tracking Sensor Modules which has IR Transmitters and Receivers (aka photo diodes) used for sending and receiving light. When IR light falls on a black surface, the light is absorbed by the black surface, thus resulting in no reflection back to the IR Sensor (See figure 2.1).

The Arduino Line Follower will sense the black line by using both, left and the right sensors placed above the line and send the signal(s) back to the Arduino for further computational processing. The low value of reflectance will be the parameter used to detect the position of the line by the robot. The higher value of reflectance will be the surface around the line (Black = Low Reflection | White = High Reflection). So in this linear array of IR sensors, if the left IR sensor presents the low value of reflectance, then the black line is towards the left. The controller then compensates for this by signaling the motors to go in the opposite direction of the line (See figure 2.2).

In addition to the 'Line following' functionality, we may also utilize the 'Ultrasonic Sensor' to incorporate an obstacle avoiding feature, which will then make the robot stop if any object is placed before it.

Pranay Patel | Daniel Wang

Mount Royal University | Computer Information Systems

Step 1: Gather Required Material

For a successful completion, we may need the following resources:

  • 1x - Arduino Uno Board (Figure 1.0)
  • 1x - Adafruit Motor Sheild (Figure 2.0)
  • 1x - Mini Breadboard
  • 2x - IR Proximity Sensors (Figure 3.0)
  • 2x - DC Motors (Figure 4.0)
  • 2x - Wheels (or substitute actuators)
  • 1x - Chasis / Body (Figure 5.0)
  • 1x - Switch (Optional)
  • 1x - Connector Wires (Figure 6.0)
  • 1x - 9v Battery (Can be substituted with series of 1.5v Batteries) (Figure 7.0)
  • 1x - Black or White Electric Tape (Figure 8.0)
  • 1x - Glue Gun (Optional)
  • 1x - Ultrasonic Sensor

Links to purchase essential materials:

Step 2: Assembly

Steps to assemble the materials:

  1. Mount the "Adafruit Motor Sheild" onto the "Arduino Uno Board" [See Figure 1.1]
  2. Place the mounted Arduno Board on to the 'Chasis/Body' of the robot and ensure its intact on the board.
  3. Pace the breadboard in Parallel to the 'Ardunio Board' board. [See Figure 1.2]
  4. Connect Left Motor to 'M2' slot and Right Motor to 'M3' slot on the Shield [See Figure 1.3]
  5. Add a power source to the "Adafruit Motor Sheild" (May add in a Swich)
  6. Add another (separate) power supply to the "Arduno Uno Board" [See Figure 1.4]
  7. Create a structure attached to the "Chasis/Body" low enough for the "IR Sensors" to detect the line.
  8. Place both sensors ~1 inch apart and stick it below the structure [See Figure 1.5]
  9. Connect both the sensors to the 'Breadboard' and to corresponding connectors on the Arduino board. Depending on the type/model of sensors chosen, you will most likely have three pins on the sensor: V+, G, S.
  10. Connect 'V+' (Voltage pin) to the '+' node on the breadboard, 'G' (Ground) to the '-' node on the breadboard, and 'S' (Signal) to the 'A1' (for left sensor) and 'A3' (for right sensor) pin on the "Arduino Uno Board"
  11. Once the entire assembly is complete, re-verify your connections, make adjustments to the structure, and have the unit ready for testing.

Step 3: Coding

#include #include "utility/Adafruit_MS_PWMServoDriver.h"

// Create the motor shield object with the default I2C address Adafruit_MotorShield AFMS = Adafruit_MotorShield(); // Or, create it with a different I2C address (say for stacking) // Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);

// Select which 'port' M1, M2, M3 or M4. In this case, M1 Adafruit_DCMotor *myMotor = AFMS.getMotor(2); Adafruit_DCMotor *myMotor3 = AFMS.getMotor(3); // You can also make another motor on port M2 //Adafruit_DCMotor *myOtherMotor = AFMS.getMotor(2);

#include RedBotSensor IRSensor1 = RedBotSensor(A1); // initialize a sensor object on A3 RedBotSensor IRSensor2 = RedBotSensor(A3); // initialize a sensor object on A7

void setup() { Serial.begin(9600); // set up Serial library at 9600 bps Serial.println("Adafruit Motorshield v2 - DC Motor test!");

AFMS.begin(); // create with the default frequency 1.6KHz //AFMS.begin(1000); // OR with a different frequency, say 1KHz


void loop() { Serial.print(; Serial.print(; delay(500); Serial.println(); action(); }

void action(){ if(isLeftBlack() && isRightBlack()){ moveForward(); } else if(isLeftBlack()){ moveRight(); } else if(isRightBlack()){ moveLeft(); } else{ myMotor->run(RELEASE); myMotor3->run(FORWARD); myMotor3->setSpeed(32); delay(200); myMotor3->run(RELEASE); //carStop(); } }

boolean isLeftBlack(){ return >= 700 ? true : false; }

boolean isRightBlack(){ return >= 700 ? true : false; }

void moveLeft(){ myMotor->run(RELEASE); myMotor3->run(FORWARD); myMotor3->setSpeed(35); delay(200); }

void moveRight(){ myMotor3->run(RELEASE); myMotor->run(FORWARD); myMotor->setSpeed(35);


void moveForward(){ myMotor->run(FORWARD); myMotor3->run(FORWARD); myMotor3->setSpeed(37); myMotor->setSpeed(37); }

void carStop(){ myMotor3->setSpeed(RELEASE); myMotor->setSpeed(RELEASE); myMotor->run(RELEASE); myMotor3->run(RELEASE); }

void moveBackward(){ myMotor->run(BACKWARD); myMotor3->run(BACKWARD); myMotor3->setSpeed(40); myMotor->setSpeed(40); }

Step 4: Testing

  1. Once the robot is assembled properly, arrange sufficient white surface (e.g. white cardboard, white flooring, etc) and draw lining path using a 'Black Electric Tape' [See figure 2.1]
  2. Place the robot on the surface, and initially align the 'IR Proximity Sensors' between/or above a black line.
  3. Turn on the power-supply for both, the 'Arduino Uno Board' and the 'Adafruit Motor Shield'
  4. Observe the demonstration