Lesson 07 - Line Following

Learn how to use the line follow module

By ,    Minute


Watch the livestream


What you’ll learn

In this lesson you will learn how to use the line follow module to make the robot follow along a line, or stay within a marked area.


Downloadable Track PDFs

Download the PDFs here:


What you’ll need


Preparation

  1. Connect the SMARS to the USB cable, and the USB Cable to your computer
  2. Launch the Arduino IDE on your computer
  3. Create a new Sketch, by clicking the New Sketch button

Let’s code

You can download the code below from GitHub, but it’s better to type it in yourself line by line, as you will get to understand what each line means.

/*
 * Kevin McAleer
 * 24 July 2020 
 * 
 * Line Following Code
 * See Lesson 07 for the full tutorial
 * https://www.smarsfan.com/play/lessons/lesson_07_linefollow
 * Watch the livestream video:
 * https://youtu.be/u9VT32q7ero 
 * 
 *
 */

// set the line sensor thresholds
int light_threshold = 650;
int dark_threshold = 300;
int lineNumber; // stores the line sensor value
int lineSensorPin = A4; // line sensor analog output


// set Motor A to Arduino Pins
int motor_A = 12; // official Arduino Motor Shield uses D12
int motor_B = 13; // official Arduino Motor Shield uses D13
int buzzer = 4;          // digital pin D4 (not the same as A4)

// set the Motor Speed using the Arduino Pins
int motor_A_speed = 10; // Fundumoto shield uses D10 (the official Arduino Motor Shield uses D3)
int motor_B_speed = 11; // official Arduino Motor Shield uses D11

// set the time between motor on and motor off
int wait_in_milliseconds = 10;

/////////////////////////////////////
/*
 * Movement block of code, from the movement lessons
 * https://www.smarsfan.com/play/lessons/lesson_01_movement
 * https://www.smarsfan.com/play/lessons/lesson_02_turning
 * 
 */

// move forward
void forward() {

  // set the direction to forward
  digitalWrite(motor_A, LOW);  
  digitalWrite(motor_B, HIGH);

  // set to full speed
  analogWrite(motor_A_speed, 255);
  analogWrite(motor_B_speed, 255);

  // wait
  delay(wait_in_milliseconds);

  // stop
  analogWrite(motor_A_speed, 0);
  analogWrite(motor_B_speed, 0);
}

void backward(){
  // set the direction to backward
  digitalWrite(motor_A, HIGH);  
  digitalWrite(motor_B, LOW);

  // set to full speed
  analogWrite(motor_A_speed, 255);
  analogWrite(motor_B_speed, 255);

  // wait
  delay(wait_in_milliseconds);

  // stop
  analogWrite(motor_A_speed, 0);
  analogWrite(motor_B_speed, 0);
}

void turnRight(){
  // set both motors the same direction to spin on the spot
  digitalWrite(motor_A, HIGH);  
  digitalWrite(motor_B, HIGH);

  // set to full speed
  analogWrite(motor_A_speed, 255);
  analogWrite(motor_B_speed, 255);

  // wait
  delay(wait_in_milliseconds);

  // stop
  analogWrite(motor_A_speed, 0);
  analogWrite(motor_B_speed, 0);
}

void turnLeft(){
  // set both motors the same direction to spin on the spot
  digitalWrite(motor_A, LOW);  
  digitalWrite(motor_B, LOW);

  // set to full speed
  analogWrite(motor_A_speed, 255);
  analogWrite(motor_B_speed, 255);

  // wait
  delay(wait_in_milliseconds);

  // stop
  analogWrite(motor_A_speed, 0);
  analogWrite(motor_B_speed, 0);
}

/////////////////////////////////////

int readLineSensor() {
  return analogRead(lineSensorPin);
}

void setup() {
  // set the Serial to 9600 baud and open it for comms
  Serial.begin(9600);

  // set the Arduino pin to OUTPUT mode
  pinMode(motor_A, OUTPUT);
  pinMode(motor_B, OUTPUT);
  pinMode(buzzer, OUTPUT);
}

void loop() {
  // Read the value from the line sensor (connected to the line sensor pin)
  lineNumber = readLineSensor();

  // move forward while the line sensor is white
  while(lineNumber > light_threshold)
  {
       Serial.println("move forward"); 
    // move forward
    forward();
     Serial.println(lineNumber); 
    lineNumber = readLineSensor();
  }
   Serial.println(lineNumber); 
  if(lineNumber < light_threshold){
    turnLeft(); 
  } 
  else {
     Serial.println(lineNumber); 
    backward();
    backward();
    turnLeft();
  }
  Serial.println(lineNumber); 
}

What the code means

  • The TCRT5000 shines infrared light at the floor and measures how much bounces back. White paper reflects a lot (a high reading) and a black line reflects very little (a low reading).
  • readLineSensor() uses analogRead() to get a number from 0 to 1023.
  • While the reading is above light_threshold (650) the robot is on white paper, so it keeps driving forward in short 10 millisecond bursts.
  • When the reading drops, the sensor has reached the line, so the robot turns left until it finds white again. This keeps it running along the edge of the line.

Every sensor and every floor is different, so watch the numbers in the Serial Monitor and adjust light_threshold to sit halfway between your white and black readings.

Try it yourself

  1. Print one of the track PDFs and see how fast SMARS can get round it.
  2. Change wait_in_milliseconds from 10 to 20. Is it faster or does it lose the line?
  3. Challenge: use the dark_threshold variable so the robot only turns when the reading is really dark.

Check your understanding

Quick quiz 1 of 2

Why does the line sensor give a low reading over a black line?

Quick quiz 2 of 2

Your SMARS keeps losing the line. What should you try first?

What’s next

Congratulations on finishing the course! Try these next:

You can use the arrows  ← → on your keyboard to navigate between lessons.


What are you looking for?
Watch Videos Get Ideas Learn Something Read a Review Read the Blog Search
... Z Z z