Table of Contents


This article contains open-source Arduino code for a line-following robot which follows a black line on the ground. This code is free to modify as necessary. The original code was found in the book “Arduino Robotics” by John-David Warren et al. It has been modified to work with the newest version of Adafruit's Arduino-based motorshield.

Line-following robots are relatively simple for the average hobbyist to build. If you would like instructions on how to build the robot mechanically, you can find these instructions all across the great global web. A good place to start would be the aforementioned book. It has step-by-step instructions, a parts list, and a list of places to get the parts.

For my robot, I purchase a pre-designed robot chassis and an electronic line sensor. The line sensor unit had five pairs of LED emittors and detectors, which is what the code is designed to handle. Your sensor unit — whether you build it or purchase it — may have more or less sensors, but five sensors is a pretty good number for the purposes of this robot. If you need fewer sensors, just comment out the unneeded sensors. If you need more sensors in the code, you can add more easily. It shouldn't be too hard to do if you have any experience with Arduino programming. If you don't know how to do it, I don't know why you are building this robot at your current level of knowledge. Time to learn something new! Visit Arduino's home website to learn about programming, and then try again.

Something to note: For the particular robot that I built, mechanical difficulties prevented me from using two of the sensors on the sensor unit. You will notice that in the comments. However, the code was easier to handle when these sensors were left in the program. Instead, I soldered the two unused sensor wires together with the center sensor on the array so that the three centermost sensors functioned as one sensor. Otherwise, I would have had to rewrite the entire original program. So this code should end up working fine on a robot with three sensors or five sensors. But you will have to troubleshoot for yourself. I am just posting this to get you started, and to prevent you from having to think out the whole program from beginning to end. As long as you can define your sensors properly, and you are using an Arduino Uno microprocessor and an Adafruit motorshield version 2, you should be golden.

Arduino Linebot Code

// Arduino Linebot
// Follows a Black line on a Surface 
// Code by JDW 2010 – modified for Adafruit Motorshield v2. by Chris Anderson, Kyle Ceffaratti, and Alex Johnson. Free to modify as desired. 

// This step includes the Adafruit_Motorshield library for the motor-controller. You need to download it separately from the Adafruit website for the motorshield to work //   properly.
#include <Adafruit_MotorShield.h>
#include <Wire.h>
#include "utility/Adafruit_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield();     // initiate communication between shield and board 
Adafruit_DCMotor *motor_left = AFMS.getMotor(1);     // attach motor_left to the Adafruit motorshield M1
Adafruit_DCMotor *motor_right = AFMS.getMotor(3);      // attach motor_right to the Adafruit motorshield M3

// In this step, you create variables for sensor readings
// For simplicity (and because "what ain't broke shouldn't be fixed") sensors 4 and 5 ended up being unused on our Linebot. Those sensors were soldered into the port for // the center sensor so that the three centermost sensors worked as one sensor.
// However, we left them in the code in certain places to avoid having to rewrite the whole thing. You will have to change this part as you need to.

int sensor1 = 0;    // Sensor 1
int sensor2 = 0;    // Sensor 2
int sensor3 = 0;    // Sensor 3
int sensor4 = 0;    // Sensor 4
int sensor5 = 0;    // Sensor 5

// Create variables for adjusted readings

int adj_1 = 0;
int adj_2 = 0;
int adj_3 = 0;
int adj_4 = 0;
int adj_5 = 0;

// Sensor max/min thresholds. These thresholds are based upon infrared LED sensor readings. They define when your robot is reading the black line or not. 

int s1_min = 200;
int s1_max = 950;

int s2_min = 200;
int s2_max = 950;

int s3_min = 200;
int s3_max = 950;

int s4_min = 200;
int s4_max = 950;

int s5_min = 200;
int s5_max = 950;

// this threshold defines when the sensor is reading the black line
int lower_threshold = 20; 

// value to define a middle threshold (half of the total 255 value range)
int threshold = 128; 

// this threshold defines when the sensor is reading the white poster board or other surface (original programmer used a white poster board)
int upper_threshold = 230;

// this value sets the maximum speed of linus (255 = max). 
// using a speed potentiometer will over-ride this setting.

int speed_value = 50;             // You can change the speed of your robot's drive motors by setting this value between 0 and 255. 
int speed_pot;

// end of changeable variables

void setup()  
  Serial.begin(9600); // Start serial monitor to see sensor readings. This step allows you to get a feel for the values that your sensors are reading.  You will have to //change the values in the above "thresholds" section based upon these readings.
  AFMS.begin(); /// create communication with board at default frequency 1.6KHz 
  // declare left motor 

  // declare right motor
// Next we start reading the sensors as part of the program loop. This loop will continuously read sensors and output to the drive motors.
// You can add more sensors or comment out sensors you don't need in this section. 
void update_sensors(){

  // this will read sensor 1
  sensor1 = analogRead(1);      // sensor 1 = leftmost sensor
  adj_1 = map(sensor1, s1_min, s1_max, 0, 255);
  adj_1 = constrain(adj_1, 0, 255);

  // this will read sensor 2
  sensor2 = analogRead(2);     //  sensor 2 = center
  adj_2 = map(sensor2, s2_min, s2_max, 0, 255);
  adj_2 = constrain(adj_2, 0, 255);

  // this will read sensor 3
  sensor3 = analogRead(3);         // sensor 3 = rightmost sensor
  adj_3 = map(sensor3, s3_min, s3_max, 0, 255);
  adj_3 = constrain(adj_3, 0, 255);

  // this will read sensor 4
  sensor4 = analogRead(3);     //  sensor 4 = unused
  adj_4 = map(sensor4, s4_min, s4_max, 0, 255);
  adj_4 = constrain(adj_4, 0, 255);

  // this will read sensor 5
  sensor5 = analogRead(4);  // sensor 5 = unused
  adj_5 = map(sensor5, s5_min, s5_max, 0, 255); 
  adj_5 = constrain(adj_5, 0, 255);

  // check value for speed potentiometer if present  speed_pot = analogRead(5) / 4;  


void loop(){

  update_sensors(); // update sensors 

    //speed_value = speed_pot;  // Leave commented out, unless using potentiometer 

  // first, check the value of the center sensor
  if (adj_2 < lower_threshold){

    // if center sensor value is below threshold, check surrounding sensors
    if (adj_1 > threshold && adj_3 > threshold){

      // if all sensors check out, drive forward	

    // you want the bot to stop when it reaches the black box.

    else if (adj_1 < lower_threshold){
      if (adj_2 < lower_threshold){
        if (adj_3 < lower_threshold){
          //if (adj_4 < lower_threshold){
            //if (adj_5 < lower_threshold){

              //  if all sensors are reading black, stop Linus.

  // otherwise, the center sensor is above the threshold
  // so we need to check what sensor is above the black line 

  else {

    // first check left sensors
    if (adj_1 < upper_threshold && adj_3 > upper_threshold){


    // then check sensor 5
    else if (adj_1 > upper_threshold && adj_5 < upper_threshold){


    // then check right sensor
    else if (adj_3 < upper_threshold && adj_1 > upper_threshold){


    // if not sensor 2, then check sensor 4
    else if (adj_2 > upper_threshold && adj_4 < upper_threshold){



  ///// Print values for each sensor

  /////sensor 1 values
  Serial.print("sensor 1:  ");
  Serial.print("  -  ");

  Serial.print("Adj 1:  ");
  Serial.print("  -  ");

  /////sensor 2 values
  Serial.print("sensor 2:  ");
  Serial.print("  -  ");

  Serial.print("Adj 2:  ");
  Serial.print("  -  ");

  /////sensor 3 values
  Serial.print("sensor 3:  ");
  Serial.print("  -  ");

  Serial.print("Adj 3:  ");
  Serial.print("  -  ");

  /////sensor 4 values
  Serial.print("sensor 4:  ");
  Serial.print("  -  ");

  Serial.print("Adj 4:  ");
  Serial.print("  -  ");

  /////sensor 5 values
  Serial.print("sensor 5:  ");
  Serial.print("  -  "); 

  Serial.print("Adj 5:  ");
  Serial.print(" ");

  //Serial.print("speed:  ");
  Serial.println(" ");


// end of code

Computer Science | Programming | Open Source

QR Code
QR Code arduino_linebot_code (generated for current page)