Go Down

Topic: LFR with help of PID programing (Read 271 times) previous topic - next topic

Shiv_Pratap_Singh

Hello there,

I have been making LFR with help of PID programming using 5 linear array sensor .The problem is sensor read the value very slowly i.e when sensor detect the black and respond to the arduino uno at that point of time bot has already cross the line and it did not take the turn.(I think problem is synchronization between motor and sensor as programme is right.)

This problem only comes when line width is 25mm and supply of motor is 9V. But when i gave 5V supply and line width is 50mm then bot complete the track without any problem. And one more thing I am using
L293d IC directly without any  motor shield board.

And here my programme:

Code: [Select]

int l1=2;
int l2=3;
int r1=4;
int r2=12;
int enl=11;
int enr=5;
int a[5];

int last_proportional=0;
int integral=0;

char select_turn(unsigned char found_left,unsigned char found_right,unsigned char found_st);
int mod(int v);
int set_motors(int a,int b);
void turn (char dir);
void PID();
int right=0;
int left=0;
void setup()
{
  pinMode(6,INPUT);
  pinMode(7,INPUT);
  pinMode(8,INPUT);
  pinMode(9,INPUT);
  pinMode(10,INPUT);
 pinMode(l1,OUTPUT);
pinMode(l2,OUTPUT);
pinMode(r1,OUTPUT);
pinMode(r2,OUTPUT);
pinMode(enl,OUTPUT);
pinMode(enr,OUTPUT);

Serial.begin(9600);
}


 

void loop()
{
PID();
set_motors(200,200);
delay(20);
unsigned char found_left=0;
unsigned char found_right=0;
unsigned char found_st=0;
readline();
if(a[0]==LOW)
found_left=1;
if(a[4]==LOW)
found_right=1;
if(a[2]==LOW)
found_st=1;
unsigned char dir;
dir=select_turn(found_left,found_right,found_st);
turn(dir);
}

 int set_motors(int l,int r)
{


if(l>0&&r>0)
{
analogWrite(enl,mod(l));
analogWrite(enr,mod(r));
digitalWrite(l1,LOW);
digitalWrite(l2,HIGH);
digitalWrite(r1,LOW);
digitalWrite(r2,HIGH);
}
else if(l<0&&r>0)
{
analogWrite(enl,mod(l));
analogWrite(enr,mod(r));
digitalWrite(l1,HIGH);
digitalWrite(l2,LOW);
digitalWrite(r1,LOW);
 digitalWrite(r2,HIGH);

}
else if(l>0&&r<0)
{analogWrite(enl,mod(l));
analogWrite(enr,mod(r));
digitalWrite(l1,LOW);
digitalWrite(l2,HIGH);
digitalWrite(r1,HIGH);
digitalWrite(r2,LOW);

}
else if(l==0&&r==0)
{
analogWrite(enl,mod(l));
analogWrite(enr,mod(r));
digitalWrite(l1,HIGH);
digitalWrite(l2,HIGH);
digitalWrite(r1,HIGH);
digitalWrite(r2,HIGH);

}
}

  int readline()
{
for(int i =0;i<5;i++)
{
a[i]=digitalRead(6+i);
}
int v;
v=(4000*a[0]+3000*a[1]+2000*a[2]+1000*a[3]+0*a[4])/(a[0]+a[1]+a[2]+a[3]+a[4]);

return v;
}
int stop()
{
 analogWrite(enl,255);
analogWrite(enr,255);
digitalWrite(l1,HIGH);
digitalWrite(l2,HIGH);
digitalWrite(r1,HIGH);
digitalWrite(r2,HIGH);
}

  void turn(char dir)
{
 switch(dir)
 {
 case'L':
 set_motors(-200,200);
 delay(350);
break;
 case 'R':
 set_motors(200,-200);
 delay(350);
 break;
 case'B':
 set_motors(-200,-200);
 delay(650);
 break;
 case 'S':
 
 break;
 }
}
 
 void PID()
{
 int i;
 int power_difference=0;
 float kp,ki,kd;
 unsigned int position;
 int derivative,proportional;
while(1)
{
position=readline();
Serial.println(position);
proportional=((int)position-2000);
derivative=proportional-last_proportional;
integral=integral+proportional;
last_proportional=proportional;
kp=0.9823;
ki=0.000015;
kd=0.0082;
power_difference=proportional*kp+integral*ki+derivative*kd;
Serial.println(power_difference);

const int max=250;
if(power_difference >max)
 power_difference=max;
if(power_difference<-max)
power_difference=(-1*max);
if(power_difference<0)
{
set_motors(max+power_difference,max);
}
else{
set_motors(max,max-power_difference);
}
readline();
if(a[0]==LOW||a[4]==LOW)
return;
else if(a[0]==HIGH&&a[1]==HIGH&&a[2]==HIGH&&a[3]==HIGH&&a[4]==HIGH)
return;

}
}
char select_turn(unsigned char found_left,unsigned char found_right,unsigned char found_st)
{
 if(found_left==1)
 return 'L';
 else if(found_st==1)
return 'S';
 else if(found_right==1)
return 'R';
else
return 'B';
}
 int mod(int v)
{
 if(v<0)
 return -1*v;
 else if(v>0)
 return v;
}

DrDiettrich

With a higher voltage the motors turn faster. You'll have to change the PID parameters, perhaps also reduce the delays.

Power_Broker

#2
Mar 05, 2017, 08:12 pm Last Edit: Mar 05, 2017, 08:32 pm by Power_Broker
NEVER USE delay(). Never, never, never. This is what is making your LFR seem to react slowly. Also, you should check out the Arduino demo "Blink Without Delay" (just google it).
"The desire that guides me in all I do is the desire to harness the forces of nature to the service of mankind."
   - Nikola Tesla

DrDiettrich

BlinkWithoutDelay is available in the IDE examples.

Shiv_Pratap_Singh

sir,
i have also tried to reduce delay and give less max voltage to enable pin of l293d to motors but its not working same problem is occurring.

(Is it necessary to give different voltage to enable pin? )

Shiv_Pratap_Singh

I removed the delay as it is in "Blink Without Delay" but nothing happen.
(Any other help?)




ardy_guy

#6
Mar 06, 2017, 05:35 am Last Edit: Mar 06, 2017, 05:53 am by ardy_guy
NEVER USE delay(). Never, never, never.
That's a bit of an over-simplification; delay() has its place. (But no, probably not in an LFR.)

But for example if you were to try an I2C write according to this from the Playground:

Code: [Select]

void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
    int rdata = data;
    Wire.beginTransmission(deviceaddress);
    Wire.send((int)(eeaddress >> 8)); // MSB
    Wire.send((int)(eeaddress & 0xFF)); // LSB
    Wire.send(rdata);
    Wire.endTransmission();
  }


.... without a short delay thus:

Code: [Select]

void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
    int rdata = data;
    Wire.beginTransmission(deviceaddress);
    Wire.send((int)(eeaddress >> 8)); // MSB
    Wire.send((int)(eeaddress & 0xFF)); // LSB
    Wire.send(rdata);
    Wire.endTransmission();
    delay(5); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  }


.... it's unlikely to work.


[irishAccent]Have you tried turning it off and on again?[/irishAccent]

DrDiettrich

Please understand that you have to tune a PID for every single application. If your application changes, like the voltage is increased in your case, you have to configure the PID for that application again.

Go Up