This is the complete guide about how to make a perfect PID Arduino based Line following Robot. this is the last post in the section of making a good and easy DIY Line follower.All the basic things we have already discussed.in this post we will discuss the final arduino code for making a fast line following robot.But before anything Read these previous linked articles:


Arduino smart and fast line following Robot


Arduino PID advance line following Robot


I called this Robot the smart and fast because the good and amazing thing in the arduino code is whenever the robot leaves the line where it forgets its path suddenly it will recall the last saved values that where it was.So the last sensor values tell whether it is on the left side or right.Now here we will not discuss each and every part for making line following robot.We will just recall few things and discuss the final code here.


Contents:

  • Steps for making Line following Robot
  • Required components list
  • Arduino PID based Line following Robot Code

Steps for making Line Following Robot


There are Five main steps for making Line following Robot.All the steps have been discussed in the posts mentioned above.

  1. Objective
  2. Selection of Components
  3. Mechanical Parts assembling
  4. Electronic components Wiring
  5. Programming & Testing
  6. Tuning

Well the first four have been discussed in above mentioned two articles in detail.Here we will discuss only the last part.The programming and testing part.


Objective


Our objective is to follow the line either black or white.Defining the objective is very importatnt before doing anything.Like define what kind of arena you are going to make a Robot for.Some arena’s have very complex structures and some have only or few checkpoints to pass and some have inclined surfaces.So it is necessary to define the objective for making a good Robot and what features it needs.Here we are going to make a simple line following robot that follows the line and never leaves the line ever.It knows where it was and how to be back on the track again.

 


PID Arduino Code & Testing


This is the modified arduino line following Robot code.We will discuss the each and every section of this code.As the Arduino programming is not difficult and easy enough to understand so you will understand each and every thing easily.

Define Motor Control Inputs:

const int motorRPin1 = 7; // pin 1 for the right motor, connected to IN1 on motor driver              
const int motorRPin2 = 4;  // pin 2 for the right motor, connected to IN2 on motor driver
const int motorREnable = 6; // enable pin for the right motor (PWM)

const int motorLPin1 = 3; // signal pin 1 for the left motor, connected to IN3            
const int motorLPin2 = 2; // signal pin 2 for the left motor, connected to IN4
const int motorLEnable = 5; // enable pin for the left motor (PWM)

Defining Sensors

int irSensorAnalog[5] = {0,0,0,0,0};

// an array to hold boolean values (1/0) for the ir sensors, based on the analog reading and the predefined threashold
int irSensorDigital[5] = {0,0,0,0,0}; 


int treashold = 700; 

// binary representation of the sensor reading from left to right
int irSensors = B00000; 

// sensors detecting the line
int count = 0;

The Very first line defines the sensors in an array.The binary values will be stored there.

The Threshold is a value defined for sensor that in the range of 700 the sensor will detect the line.The sensor we use is also works as an obstacle avoidance so this is the threshold that defines the analog values of the sensor.We will get the analog values from 0-700 when the sensor on the black or white line.

We define sensor in a binary for understanding the coming values.Reading analog values and working on the tuning of code is somehow difficult and not accurate.So for ease we define those analog in binary.We can now easily detect which sensor is on the line. in the form of 1 and 0.

Define Deviation:

// deviation from the line [-180 ; +180]. the negative is for left and + for right
int error = 0;

//  store the last value of error
int errorLast = 0;  

// a coorection value, based on the error that is used to change motor speed with PWM
int correction = 0; 

// keep track of the laps
int lap = 0; 


// PWM to control the motor speed [0 - 255]
int maxSpeed =255;


int motorLSpeed = 0;
int motorRSpeed = 0;

Define Motor Outputs:

void setup() {
Serial.begin(9600);
  /* Set up motor controll pins as output */
  pinMode(motorLPin1,OUTPUT);        
  pinMode(motorLPin2,OUTPUT);
  pinMode(motorLEnable,OUTPUT);
  
  pinMode(motorRPin1,OUTPUT);        
  pinMode(motorRPin2,OUTPUT);
  pinMode(motorREnable,OUTPUT);
   
  /* IR sensor pins as input.... */
  for (int i = 0; i < 5; i++) //............
{
    pinMode(irPins[i], INPUT);//.............
  }
  

  TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM01) | _BV(WGM00); 
  TCCR0B = _BV(CS00); 
}

Code for Serial Monitor:

void loop() {

  Serial.print(digitalRead(A0));
Serial.print(' ');
Serial.print(digitalRead(A1));
Serial.print(' ');
Serial.print(digitalRead(A2));
Serial.print(' ');
Serial.print(digitalRead(A3));
Serial.print(' ');
Serial.print(digitalRead(A4));
Serial.println(' ');
delay(1500);
 Scan();
 UpdateError();
 UpdateCorrection();
 Drive();
}

Reading Sensors:

void Scan() {
  // Initialize counters, sums etc.
 
  count = 0;
  
  irSensors = B000000;
    
  for (int i = 0; i < 5; i++) //................
{
    irSensorAnalog[i] = analogRead(irPins[i]);

    if (irSensorAnalog[i] >= treashold) {
        irSensorDigital[i] = 1;
    }
    else {irSensorDigital[i] = 0;}
    Serial.print(irSensorAnalog[i]);
    Serial.print("|");
    count = count + irSensorDigital[i];
    int b = 4-i;
    irSensors = irSensors + (irSensorDigital[i]<<b);


    }    
}

Define Sensor Cases:

void UpdateError() {
  
  errorLast = error;  
  
  switch (irSensors) {
     
    case B00000:
       if (errorLast < 0) { error = -180;}
       else if (errorLast > 0) {error = 180;}
       break;
     
     case B10000: // leftmost sensor on the line
       error = -150;
       break;
     
     case B01000:                      
       error = -120;
       break;

     case B00100:  
       error = 0;
       break;
       
     case B00010: 
       error = 120;
       break;           

     case B000001: // rightmost sensor on the line
       error = 150;
       break;
       
/* 2 Sensors on the line */         
    
     case B11000:
   
       error = -150;
       break;
      
     case B01100:
       error = -150;
       break;

     case B00110: 
       error = 150;
       break;           

     case B00011:
       error = 150;
       break;
     

/* 3 Sensors on the line */    
      
     case B11100:
        //case B01110:
       error = -150;
       break;
      
     case B00111:
  
       error = 150;
       break;

 /* 4 Sensors on the line */       
  
     case B11110:
       error = -150;
       break;
       
     case B11101:
       error = -150;
       break;
      
     case B01111:
       error = 150;
       break;
       
     case B10111:
      //case B11011:
       error = 150;
       break;

/* 5 Sensors on the line */      
     
      
     case B11111:
       error = -150;
       break;
   
     default:
     error = errorLast;
  }
}

ErrorLast = error is the command that stores the last value of the sensor if sensor loses line.

error is the value that will be used for tuning of line following robot.This will increase or decrease the speed according to the case.we will discuss this in the tuning section of the post.

There are two basic functions left you can understand by yourself.Now we will move towards the final code:


PID Arduino Line following Robot Final code

Download Code:

Robot Tunning- Line Follower code


case B10000: // leftmost sensor on the line

       error = -150;
       break;
     
     case B01000:                      
       error = -120;
       break;

     case B00100:  
       error = 0;
       break;
       
     case B00010: 
       error = 120;
       break;           

     case B000001: // rightmost sensor on the line
       error = 150;
       break;

Here this is the part of code that you have to change according to your conditions.As you can see that the case one hare in binary represents that the 1 is for sensor on the line and 0 for nothing.So in first case there is only one sensor on the line the left most.The error is -150 and when this -150 goes into the following formula:

  if (correction >= 0) {
    motorRSpeed = maxSpeed - correction;
    motorLSpeed = maxSpeed;
  }
  
  else if (correction < 0) {
    motorRSpeed = maxSpeed;
    motorLSpeed = maxSpeed + correction;
  }

This formula calculates the accurate speed for the specified motor in this case the left motor.So by changing the values of error we can adjust the motors speed and we can smooth the way it follows the line.It is same as changing the values of kp kd and ki in PID. So this one is the easiest way to control.


Motor Speed By Error Values:

When we change the error values in the code we must know what speed our motor will give at the end.So here I calculated this speed when we change values of error function.

If  Error   :    Speed

120 = 180

90=200

60=215

30=225

Well these are the values that i have calculated as according to this code.You can also calculate all other values by above given formula.If the Robot could not adjust on any of the values well change the correction values in conditions.


The code is very easy and understandable. Adjust according to your connections and your Robot.Test and modify until you get the perfect results.Watch the video of my Robot in Action.It was a baby Arena but in lots of Robots mine got first position.Subscribe to our YouTube channel for more Tutorials and ideas.Stay connected and always have faith on yourself.

What's your reaction?

Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0

Leave a reply

Your email address will not be published. Required fields are marked *