PID Line Follower Code Verification....

Hey guys,
I have written a PID code for a line follower.
It uses a 5-sensor array.
Here’s the code:

int Lp = 7;  //motorpins
int Ln = 4;
int El = 5;  //pwm for left motor
int Rp = 8;
int Rn = 12;
int Er = 6;  //pwm for right motor
int right_speed = 0;
int left_speed = 0;
long sensors[] = {0, 0, 0, 0, 0};
long sensors_average = 0;
int sensors_sum = 0;
int posn = 0; //position
int proportional = 0;
long integral = 0;
int derivative = 0;
int last_proportional = 0;
float Kp = 0;  // Havent decided the values yet
float Ki = 0;
float Kd = 0;
int error_value = 0;
int max_speed = 200;
int set_point = 0;//the posn on the center of line, I have to decide the value yet

void setup(){
  pinMode (Lp, OUTPUT);
  pinMode (Ln, OUTPUT);
  pinMode (El, OUTPUT);
  pinMode (Rp, OUTPUT);
  pinMode (Rn, OUTPUT);
  pinMode (Er, OUTPUT);
  
  digitalWrite (El,LOW);
  digitalWrite (Er,LOW);
}

void read_sensors () {
  for (int i = 0; i < 5; i++) {
  sensors[i] = analogRead(i);
  sensors_average += sensors[i] * i * 1000;
  sensors_sum += int(sensors[i]);
  }
}

void pid_calc () {
  posn = int(sensors_average / sensors_sum);
  proportional = posn - set_point;
  integral = integral + proportional;
  derivative = proportional - last_proportional;
  last_proportional = proportional;
  error_value = int(proportional * Kp + integral * Ki + derivative * Kd);
}

void calc_turn(){
  if (error_value < -256) {
    error_value = -256;
  }
  
  if (error_value > 256) {
    error_value = 256;
  }
  
  if (error_value < 0) {
    right_speed = max_speed + error_value;
    left_speed = max_speed;
  }
  
  else {
    right_speed = max_speed;
    left_speed = max_speed + error_value;
  }
}


void motor_drive (int right_speed, int left_speed) {
  analogWrite(Er, right_speed);
  analogWrite(El, left_speed);
  //delay(20);
}

void loop () {
  read_sensors ();
  pid_calc ();
  calc_turn ();
  motor_drive (right_speed, left_speed);
}

Questions:
1.) Do I need to add something?
2.) Do I have to define the sensor pins? or will the arduino by itself consider the 5 analog input pins?
3.) If I have to define the sensor pins then how do I write them in the array form ? (I know we can do that by # define)
4.) will it work?

Ty for your help…

Do I have to define the sensor pins?

If the sensors are analog sensors, no. The analog pins are input only, so it is not necessary to tell the Arduino that.

will it work?

You're the one with the hardware. You do have the hardware, don't you. If not, writing a boatload of code that you can't test/validate is an exercise in frustration.

SolidSnake31295:
4.) will it work?

We have a very simple mantra where I work. If it hasn't been tested, it doesn't work.

What I now have is a digital sensor array and I know that wont work with PID.
I have ordered the analog array and am now waiting for the shipment. :slight_smile:

Will it work?

I meant to ask that is the code complete? Do I need to add something else?

Ty

Do I need to add something else?

A heaping helping of patience, grasshopper.

I have ordered the analog array and am now waiting for the shipment.

When it arrives, you'll know.

void read_sensors () {
  for (int i = 0; i < 5; i++) {
  sensors[i] = analogRead(i);
  sensors_average += sensors[i] * i * 1000;
  sensors_sum += int(sensors[i]);
  }

here are some minor problems with your code

sensors[i] = analogRead(i)

here analogRead(i), is not going to get u any results
it should be analogRead(Ai)
since thats the pin number for analog sensors, analogRead(i) will always try to get an
analog reading from pins 0,1,2,3,4 which is toally wrong :smiley:

sensors[i] * i * 1000;

here the first value will always be 0 since i is 0 , so reading from sensor 1 will always be negative

Moderator edit: CODE TAGS

PaulS:
The analog pins are input only

I don't think that's correct - I can do digital input and output on my UNO's analog input pins. However, they do default to inputs so you're right that the pinMode initialisation is redundant.

it should be analogRead(Ai)
since thats the pin number for analog sensors, analogRead(i) will always try to get an
analog reading from pins 0,1,2,3,4 which is toally wrong :smiley:

Complete nonsense.
A0..A5 and 0..5 are completely interchangeable for analogRead.

I can do digital input and output on my UNO's analog input pins.

You can't do analog output on any pin, though, which was my point.

PaulS:
You can't do analog output on any pin, though, which was my point.

That's a valid point, but not quite what you wrote.

That's a valid point, but not quite what you wrote.

I wrote:

The analog pins are input only

As an analog pin, it is input only. That the same physical pin can also be used as a digital pin has no bearing on the direction associated with an analog pin.

Hi ther ! I got a problem while tuning PID.
I have been following tutorial from following link.
http://samvrit.tk/tutorials/pid-control-arduino-line-follower-robot/
I tried to implement the pseudo-code given there but the problem is Derivative parameter always comes zero. Is there any error ?

// ------ Initialization----------//

float error = 0, posTarget = 0, posCurrent = 0;
float P = 0, I = 0, D = 0;
float Kp = 2, Ki = 0, Kd = 1.5;
float errorPrev = 0;
float correction = 0;

    //----------- Calculations (inside loop) ---------//
    error = 0;
    error = posTarget - posCurrent;
    P = error*Kp;
    //I = I+error;
    //I = I*Ki;
    D = error - errorPrev;
    D = D*Kd;
    correction = P+I+D;
    errorPrev = error;