What is PID?



Proportional Integral Derivative the name defines 3 mathematical functions. The Main work of PID is to reduce the error of whatever we are controlling.



It takes the input compares it to the behaviour needed and adjust it accordingly.



 



Why PID For Line Follower?



Line follower seems to follow the Line accuratly at lower Speeds but as we increase the Speed it either get's off track or wobbles alot here PID comes in handy.



Basically a line follower can be designed with 3 sensor-:



1. Middle Sensor to keep bot in center



2. Right Sensor to turn the Bot right



3. Left to turn the bot left



This will follow the Line but we know the consequences



We can use PID instead here we will see the work of 5 sensor 3rd sensor as detecting center line but sometimes the line are so broad that for bot to move straight the the middle sensor has to be increased by 1 or 2 just make sure the ratio for turning right/left sensors will be equal.



00100 center Straight 



00001 Turn Right



10000 Trun Left// with greater angle 



11000 Turn Left// with some less angle



and there are other possibilities like 00011 etc. the greater angle or less angle its not we are providing angles to turn we are actually controling the speed of the motor by angularWrite



like if we want a left turn slight it calcultes the PID value Adds it to the Right Motor Speed and Subtracts it from the Left motor Speed.



Now Let's Disscuss How it calculates the PID Value



It highly depends on the error value



 



Binary ValueWeighted Value



          



00001             4



00011             3



00010             2



00110             1



00100             0



01100            -1



01000            -2



11000            -3



10000            -4



00000            -5 or 5 (depending on the previous value)



Now lets's disscuss the pseudo Code



start: error = (target_position) - (theoretical_position) integral = integral + (errordt) derivative = ((error) - (previous_error))/dt PIDvalue = (Kp*error) + (Ki*integral) + (Kd*derivative) previous_error = error wait (dt) goto start



Initially Kp,Ki,Kd values are Zero 0



Here Comes the Tricky Part Of PID we have to Tune it.



TUNING



Start With increasing the kp value(Increase it by 1 everytime and see the behaviour) till the bot starts to follow the line if it overshoots the line decrease the kp value don't care about wobbling



Now Leave ki for lets jump to Kd it calculates the error derivative which will monitor the error changes with respect to time henc it will stop bot making wobbling.



Now adjust the Ki value for Final touch its value should be between 0.5-1.



For final saying if a bot works fine with only Kp,Ki values just ignore Kd.



Requirements-:



1. Arduino Uno





2. LM7805 IC



                                                                           



3. 12 Volt Battery



4. Wheels



5. Motors Any RPMS



                                                    



6. Jumper Wires



7. Motor Driver L298 or L293 



                          



8. Chesis



                                           



9. Bread Board



10. Castor Wheel



                                                          



11. IR Sensors 6 array or 3 array sensors



Procedure-:



1. Fit the Arduino Motor Driver, Sensors motors and Caster Wheel



2.  Now connect the Motors as show in Video and Connect the Motor driver through a 12v Dc Supply and Connect the Pins to Arduino as Shown-:



 



 



                                                 



 



3. Now Get the Input From Sensors and Supply the Power to the Sensors and Arduino as they Require 5 volt convert 12 volt to 5 volt Using Lm7805 IC





                                                                                                              



4. Upload the Code Kp=15,ki=0,kd=5 for 100 Rpm Motor and Initial Speed =100



                                  Kp=25,ki=0.6,Kd=10 for 200 Rpm Motor with Inital Speed =135



 As I tested i found the above results and this may vary too.




float Kp=0,Ki=0,Kd=0;
float error=0, P=0, I=0, D=0, PID_value=0;
float previous_error=0, previous_I=0;
int sensor[5]={0, 0, 0, 0, 0};
int initial_motor_speed=100;

void read_sensor_values(void);
void calculate_pid(void);
void motor_control(void);

void setup()
{
pinMode(3,OUTPUT); //PWM Pin 1
pinMode(4,OUTPUT); //PWM Pin 2
pinMode(8,OUTPUT); //Left Motor Pin 1
pinMode(9,OUTPUT); //Left Motor Pin 2
pinMode(10,OUTPUT); //Right Motor Pin 1
pinMode(11,OUTPUT); //Right Motor Pin 2
Serial.begin(9600); //Enable Serial Communications
}

void loop()
{
read_sensor_values();
calculate_pid();
motor_control();
}

void read_sensor_values()
{
sensor[0]=digitalRead(A0);
sensor[1]=digitalRead(A1);
sensor[2]=digitalRead(A2);
sensor[3]=digitalRead(A3);
sensor[4]=digitalRead(A4);

if((sensor[0]==0)&&(sensor[1]==0)&&(sensor[2]==0)&&(sensor[3]==0)&&(sensor[4]==1))
error=4;
else if((sensor[0]==0)&&(sensor[1]==0)&&(sensor[2]==0)&&(sensor[3]==1)&&(sensor[4]==1))
error=3;
else if((sensor[0]==0)&&(sensor[1]==0)&&(sensor[2]==0)&&(sensor[3]==1)&&(sensor[4]==0))
error=2;
else if((sensor[0]==0)&&(sensor[1]==0)&&(sensor[2]==1)&&(sensor[3]==1)&&(sensor[4]==0))
error=1;
else if((sensor[0]==0)&&(sensor[1]==0)&&(sensor[2]==1)&&(sensor[3]==0)&&(sensor[4]==0))
error=0;
else if((sensor[0]==0)&&(sensor[1]==1)&&(sensor[2]==1)&&(sensor[3]==0)&&(sensor[4]==0))
error=-1;
else if((sensor[0]==0)&&(sensor[1]==1)&&(sensor[2]==0)&&(sensor[3]==0)&&(sensor[4]==0))
error=-2;
else if((sensor[0]==1)&&(sensor[1]==1)&&(sensor[2]==0)&&(sensor[3]==0)&&(sensor[4]==0))
error=-3;
else if((sensor[0]==1)&&(sensor[1]==0)&&(sensor[2]==0)&&(sensor[3]==0)&&(sensor[4]==0))
error=-4;
else if((sensor[0]==0)&&(sensor[1]==0)&&(sensor[2]==0)&&(sensor[3]==0)&&(sensor[4]==0))
if(error==-4) error=-5;
else error=5;

}

void calculate_pid()
{
P = error;
I = I + previous_I;
D = error-previous_error;

PID_value = (Kp*P) + (Ki*I) + (Kd*D);

previous_I=I;
previous_error=error;
}

void motor_control()
{
// Calculating the effective motor speed:
int left_motor_speed = initial_motor_speed-PID_value;
int right_motor_speed = initial_motor_speed+PID_value;

// The motor speed should not exceed the max PWM value
constrain(left_motor_speed,0,255);
constrain(right_motor_speed,0,255);

analogWrite(9,initial_motor_speed-PID_value); //Left Motor Speed
analogWrite(10,initial_motor_speed+PID_value); //Right Motor Speed
//following lines of code are to make the bot move forward
/*The pin numbers and high, low values might be different
depending on your connections */
digitalWrite(8,HIGH);
digitalWrite(9,LOW);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
}


5. Tune the Kp,Ki & Kd values 



6. Enjoy 



 



Video



 



                               https://youtu.be/_DFrhwN1_60