My line follower cant follow the line

Hi..
currently im working on a line follower robot.Now im at the programming phase.

i wrote a programme and try to work it out..but after i uploaded the programme to the robot ..robot miss the line all the time..it start to jumping over..can anyone tell me what is the bug on my code..
here is the code.. actually in this code doesn't use PID controller at all..please ignore the names and unused variables

//PID controller variables
float setPoint=0,Error=0;
int current_pos=0,deviation=0;
/////////////////////////////
boolean s_array[4]={
  false};

//Mdriver Control Pins
int m1pwm=13;
int m2pwm=8;
int m1x=12;
int m1y=11;
int m2x=10;
int m2y=9;
int M1speed=0;
int M2speed=0;

void setup(){

  Serial.begin(9600);
  //TCRT5000 Sensor Input
  pinMode(A4,INPUT);
  pinMode(A5,INPUT);
  pinMode(A6,INPUT);
  pinMode(A7,INPUT);
  // Mdriver OUTPUT pins
  pinMode(13,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(8,OUTPUT);

}
void PID_Controller(){
  

  //TCRT5000 sensor array inputs
  s_array[0]=digitalRead(A4);
  s_array[1]=digitalRead(A6);
  s_array[2]=digitalRead(A7);
  s_array[3]=digitalRead(A5);
  
  Serial.print(s_array[0]);
  Serial.print(s_array[1]);
  Serial.print(s_array[2]);  
  Serial.println(s_array[3]);
  

//Setting current position to 1 0 0 0-LEFT
  if(s_array[0]==true && s_array[1]==false && s_array[2]==false && s_array[3]==false){
    M1speed=150;
    M2speed=100;
    
    
    
    Serial.println("Hard Left");
  }

  //Setting current position to 1 1 0 0-LEFT
  else if(s_array[0]==true && s_array[1]==true && s_array[2]==false && s_array[3]==false)
  {
        M1speed=100;
        M2speed=130;
        Serial.println("Soft Left");
  }
  //setting current position to 0 1 0 0-LEFT
  else if(s_array[0]==false && s_array[1]==true && s_array[2]==false && s_array[3]==false){
  
        M1speed=100;
        M2speed=115;
        Serial.println("Soft Left");
  }
  //setting current position to 0 1 1 0
  else if(s_array[0]==false && s_array[1]==true && s_array[2]==true && s_array[3]==false){
        M1speed=100;
        M2speed=100;
        Serial.println("Forword");
  }
 
  //setting current position to 0 0 1 0
  else if(s_array[0]==false && s_array[1]==false && s_array[2]==true && s_array[3]==false){
        M1speed=115;
        M2speed=100;
        Serial.println("Soft Right");
  }
  //setting current position to 0 0 1 1
 else if(s_array[0]==false && s_array[1]==false && s_array[2]==true && s_array[3]==true){
        M1speed=100;
        M2speed=130;
        Serial.println("Soft Right");
  } 
 
  //setting current position to 0 0 0 1
  else if(s_array[0]==false && s_array[1]==false && s_array[2]==false && s_array[3]==true){
        M1speed=150;
        M2speed=100;
        Serial.println("Hard Right");
  }
  //setting current position to 000000000
  else{
        M1speed=0;
        M2speed=0;
        Serial.println("nothing");
  }
  
  
}
int Mdriver(){
  digitalWrite(12,HIGH);
  digitalWrite(11,LOW);
  digitalWrite(10,LOW);
  digitalWrite(9,HIGH);
  analogWrite(13,M1speed);
  analogWrite(8,M2speed);
}


//
void loop(){
  s_array[4]=false,false,false,false;
  

  PID_Controller();
  Mdriver();
  

  

}

Make sure that the line is detected at all. Ambient light may cause bogus.

Make sure that the signals are as expected, when you move only the sensor over the line (motors off).
Is the left/right position okay or reversed?
Add another branch for any unexpected combination, showing a bogus alert message.

Hint: you can encode the signals into one integer value, so that you can use a switch() to select the proper action.

Depending on the mechanical construction of the robot, it may happen that it misses the line while turning left/right. If so, keep the robot turning until the line is detected again. What will happen when the line is seen again? You may have to move differently, on entering or leaving the line at either side.

Write a very short program to print different values to the Serial Monitor when the sensor is put on the line and moved around. That way you will know if the sensor is reading correctly.

...R

Robin2:
Write a very short program to print different values to the Serial Monitor when the sensor is put on the line and moved around. That way you will know if the sensor is reading correctly.

...R

+1 to what R said.

What kind of line are you trying to follow? Black electrical tape can be very reflective to IR. Black masking tape makes better lines.

If you do what Robin2 suggests you can test the various line material.

Thank you guys ... I found the problem of the robot and now it follows the line ... But it is too slow ..so i decided to move to PID controller algorithm

but still i didn't able to tune the robot properlly..Here is the code....

//PID Controller Variables
float kp=12.0,ki=0,kd=0;
float Error=0,P=0,I=0,D=0,PID_value=0;
float previous_Error=0,Previous_I=0;
boolean s_array[4]={false,false,false,false};
int initial_motor_speed=75;
//======================================================
//Mdriver Control Pins
int m1pwm=13;
int m2pwm=8;
int m1x=12;
int m1y=11;
int m2x=10;
int m2y=9;
//======================================================
//Motor speed variables
int M1speed=0;
int M2speed=0;
//======================================================
void read_sensor_values(void);
void calculate_pid(void);
void motor_control(void);


void setup(){

  //Serial.begin(9600);
  //TCRT5000 Sensor Input
  pinMode(A4,INPUT);
  pinMode(A5,INPUT);
  pinMode(A6,INPUT);
  pinMode(A7,INPUT);
  // Mdriver OUTPUT pins
  pinMode(13,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(8,OUTPUT);


}
void read_sensor_values(){

  //Reading Sensor Values
  s_array[0]=digitalRead(A4);
  s_array[1]=digitalRead(A6);
  s_array[2]=digitalRead(A7);
  s_array[3]=digitalRead(A5);
  
  Serial.print(s_array[0]);
  Serial.print(s_array[1]);
  Serial.print(s_array[2]);
  Serial.print(s_array[3]);
  Serial.print(" : ");

  //setting Error value to 1 0 0 0
  if(s_array[0]==true && s_array[1]==false && s_array[2]==false && s_array[3]==false){
    Error=3;
  }
  //setting Error value to 1 1 0 0
  else if(s_array[0]==true && s_array[1]==true && s_array[2]==false && s_array[3]==false){
    Error=2;
  }
  //setting Error value to 0 1 0 0
  else if(s_array[0]==false && s_array[1]==true && s_array[2]==false && s_array[3]==false){
    Error=1;
  }
  //setting Error value to 0 1 1 0
  else if(s_array[0]==false && s_array[1]==true && s_array[2]==true && s_array[3]==false){
    Error=0;
  }
  //setting Error value to 0 0 1 0
  else if(s_array[0]==false && s_array[1]==false && s_array[2]==true && s_array[3]==false){
    Error=-1;
  }
  //setting Error value to 0 0 1 1
  else if(s_array[0]==false && s_array[1]==false && s_array[2]==true && s_array[3]==true){
    Error=-2;
  }
  //setting Error value to 0 0 0 1
  else if(s_array[0]==false && s_array[1]==false && s_array[2]==false && s_array[3]==true){
    Error=-3;
  }
  else{
    
  }
  

}
void calculate_pid(){
  P=Error;
  I=I+Error;
  D=Error-previous_Error;
  PID_value=(kp*P)+(ki*I)+(kd*D);
  previous_Error=Error;
  
  Serial.print("P=");
  Serial.print(P);
  Serial.print("I=");
  Serial.print(I);
  Serial.print("D=");
  Serial.print(D);
  
}
void motor_control(){
     //Calculating the effective motor speed:
     M1speed=initial_motor_speed+PID_value;
     M2speed=initial_motor_speed-PID_value;
     /*if(s_array[0]==false && s_array[1]==false && s_array[2]==false && s_array[3]==false){
     M1speed=0;
     M2speed=0;
     }*/
     //constrain
     constrain(M1speed,0,170);
     constrain(M2speed,0,170);
     
     
     digitalWrite(12,HIGH);
     digitalWrite(11,LOW);
     digitalWrite(10,LOW);
     digitalWrite(9,HIGH);
     analogWrite(13,M1speed);
     analogWrite(8,M2speed);

}
void loop(){
    Serial.print("M1speed:");
    Serial.print(M1speed);
    Serial.print("M2speed:");
    Serial.println(M2speed);
    read_sensor_values();
    calculate_pid();
    motor_control();
  /*  delay(35); 
    digitalWrite(12,LOW);
    digitalWrite(11,HIGH);
    digitalWrite(10,HIGH);
    digitalWrite(9,LOW);
    delay(5); */
}

Serial output can really slow a program down. Changing the baud to 115200 should help some but you might want to limit the serial output to a couple times a second.

  if (millis() - lastDebug > DEBUG_PERIOD)
  {
    lastDebug += DEBUG_PERIOD;
    // debug statements go here
  }

"DEBUG_PERIOD" is a constant indicating how many milliseconds should pass between debug statements. I think 250ms would be good interval to try.

"lastDebug" should be an unsigned long.

If you decide you want a debug statement every loop to test some specific aspect of the code, you can change this line:

  if (millis() - lastDebug > DEBUG_PERIOD)

to

  if (1) // (millis() - lastDebug > DEBUG_PERIOD)

This way you'll be back to having a debug statement every loop.

Tuning a PID system can be a challenge. You generally start with I and D set to zero and begin the tuning process by finding a good value for P. Often the proportional component is all that is needed.

If you're still having trouble make sure and tell us the serial output and how the robot was behaving. Let us know what you expected and what unexpected behaviour was observed.

Hi there im little bit new to the PID and advance programming techniques..
i designed a line following robot and it is working well with the basic line following algorithm ..Now i want to design more accurate algorithm for my robot using PID..
can any one give me introduction how to use pid library for line following robot..and what are the inputs and outputs and how to connect them with sensor readings and pwm motor control signal

thanks

Thank you very much ..
I tested the program(new pid program ) more than 50 times and still i havent got any good results.
I started with the kp value by setting ki,and kd to zero.. but some times robot shoot away from the line and some times it dont turn at all..
And i use 2 types of lines to test the robot . A straight line and a curvy line with the shape of letter "s".some times robot fillowa the straight line with little bit shaking, and when i put the robot on the curvy line it even cant track the line .
Im still trying and hope to do more tuning

damith14:
I will tested the program(pid) more than 50 times and still i havent got any good results.

Did the code work before you added PID?

I thought your earlier reply said the robot was working?

What do the words quoted below mean?

damith14:
I found the problem of the robot and not it follow the line ...

Im sorry .. my english is not very good..
I corrected the grammar mistakes from above replys..please read once again.

Did the code work before you added PID?

Yes..The robot works well with basic line following algorithm ..but it is little bit slow..
So i made a new pid algorithm .. robot doesnt work with this new algorithm .still i didnt able to tune kp kd,ki successfully ..im still trying ..
Thanks very much

@damith14, do not cross-post. Threads merged.