# how to use the value i get from the PID formula

hey every1,

i want to know what to do with the value that you get using the PID formula. How do i use this value to figure out the proper pwm value? im using an arduino duemilanove to build a grid solving robot, using a three sensor array. the line is of 3cm width and i am using an 3 line sensor array, which are seperated by a dist of 1.2 cm.

| --1.2-- | --1.2-- |

x=Kp*Proportional + Ki* Integral + Kd*Derivative.

say x comes out to be +5. Then are we sups to put the pwm value as (5-0/max)*255(where 0 is the target value)? but the max value keeps increasing with time because of the integal parameter...

sry am a newbie and i need sum solid tutoring...:) thx in advance

this is the line sensor i am using:

http://robosoftsystems.co.in/roboshop/index.php/grid-solving-sensor-module-digital-output-designed-for-nexus-competitions.html

here is my code till now… the pwm values are based on intuition… plz help me modify the program using PID concept

//Mpos +ve ==> left turn
//Mpos -ve ==> right turn

int s_lt2=1,//line sensor inputs, *2 extreme
s_lt1=2,
s_c=3,
s_rt1=4,
s_rt2=5;
int pwm_l=9,pwm_r=11,rt1=7,rt2=8,lt1=10,lt2=12;
void setup()
{
pinMode(s_lt2,INPUT);
pinMode(s_lt1,INPUT);
pinMode(s_c,INPUT);
pinMode(s_rt1,INPUT);
pinMode(s_rt2,INPUT);
pinMode(pwm_l,OUTPUT);
pinMode(pwm_r,OUTPUT);
pinMode(lt1,OUTPUT);
pinMode(lt2,OUTPUT);
pinMode(rt1,OUTPUT);
pinMode(rt2,OUTPUT);

}
//LOW means detects white line
void loop()
{
int d=0;
if (s_lt1==LOW&&s_c==LOW&&s_rt1==LOW)//000 case Mpos=0
{
digitalWrite(pwm_l,HIGH);
digitalWrite(pwm_r,HIGH);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//FORWARD
if(s_lt1==LOW&&s_c==LOW&&s_rt1==HIGH)//001 case Mpos=+1
{
analogWrite(pwm_l,48);
analogWrite(pwm_r,67);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn moderate left pwm
if(s_lt1==LOW&&s_c==HIGH&&s_rt1==HIGH) //011 Mpos+2//hard left
{
d++;
analogWrite(pwm_l,64);
analogWrite(pwm_r,100);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn left more speed
if(s_lt1==HIGH&&s_c==LOW&&s_rt1==LOW)//100 Mpos=-1// soft right
{
analogWrite(pwm_l,67);
analogWrite(pwm_r,48);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn right at low speed
if(s_lt1==HIGH&&s_c==HIGH&&s_rt1==LOW)//110 Mpos=-2// hard right
{
d–;
analogWrite(pwm_l,100);
analogWrite(pwm_r,64);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn right at more speed
if(s_lt1==HIGH&&s_c==HIGH&&s_rt1==HIGH)//111 lost line… come back using last value.
{
if(d<0)
{
analogWrite(pwm_l,127);
analogWrite(pwm_r,75);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn right at high speed
else if(d>0)
{
analogWrite(pwm_l,75);
analogWrite(pwm_r,127);
digitalWrite(lt1,HIGH);
digitalWrite(lt2,LOW);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn left at high speed.
}
}

also where all should i put delay statements?

Some questions.

The device in the data sheet has 5 sensors. You are only reading three of them. Why are you not reading all 5?

Why do you want to add delays? You control the speed of the robot using different values in the digitalWrite statements.

Instead of "magic" numbers that are easily missed if a change is made, define some values, instead:

# define FAST 127

Use these in place of the magic number:

digitalWrite(pwm_1, MEDIUMFAST);

If you decide to change what value represents slow, you change one line of code, rather than hunting through the code looking for all the places the value is used.

Finally, order the groups of statements, logically. Hard left, soft left, straight, soft right, hard right. Put starting and confused blocks at one end of the list.

It makes it easier to figure out what is wrong when the robot fails to execute a soft left correctly, when the other modes are working.

thx for the advice.. the updated program is given below.

my extreme sensors are for sensing junctions. Since my 3 middle sensors are fully contained within the line in case of straight(Mpos=0), i need some other mechanism to detect the junctions. hence the extreme sensors which are at some distance will both simultaneouly give high if a junc is encountered. Hence i have not included them in the PID thing. as it is, its a grid, so i only need to go staright or make 90 degree turns. hence not so much precision is required. (or do i?)

can you please telll me how to figure out therse magic nos using the PID alorithm?

//Mpos +ve ==> left turn
//Mpos -ve ==> right turn
#define SLOW 47
#define MEDIUMSLOW 68
#define MEDIUM 75
#define MEDIUMFAST 100
#define FAST 127
int s_lt2=1,//line sensor inputs, *2 extreme
s_lt1=2,
s_c=3,
s_rt1=4,
s_rt2=5;
int pwm_l=9,pwm_r=11,rt1=7,rt2=8,lt1=10,lt2=12;
void setup()
{
pinMode(s_lt2,INPUT);
pinMode(s_lt1,INPUT);
pinMode(s_c,INPUT);
pinMode(s_rt1,INPUT);
pinMode(s_rt2,INPUT);
pinMode(pwm_l,OUTPUT);
pinMode(pwm_r,OUTPUT);
pinMode(lt1,OUTPUT);
pinMode(lt2,OUTPUT);
pinMode(rt1,OUTPUT);
pinMode(rt2,OUTPUT);

}
//LOW means detects white line
void loop()
{
int d=0;
if(s_lt1==HIGH&&s_c==HIGH&&s_rt1==LOW)//110 Mpos=-2// hard right
{
d–;
analogWrite(pwm_l,MEDIUMFAST);
analogWrite(pwm_r,64);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn right at more speed
if(s_lt1==HIGH&&s_c==LOW&&s_rt1==LOW)//100 Mpos=-1// soft right
{
analogWrite(pwm_l,MEDIUMSLOW);
analogWrite(pwm_r,SLOW);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn right at low speed

if (s_lt1==LOW&&s_c==LOW&&s_rt1==LOW)//000 case Mpos=0// straight
{
digitalWrite(pwm_l,HIGH);
digitalWrite(pwm_r,HIGH);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//FORWARD
if(s_lt1==LOW&&s_c==LOW&&s_rt1==HIGH)//001 case Mpos=+1/soft left
{
analogWrite(pwm_l,SLOW);
analogWrite(pwm_r,MEDIUMSLOW);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn moderate left pwm
if(s_lt1==LOW&&s_c==HIGH&&s_rt1==HIGH) //011 Mpos+2//hard left
{
d++;
analogWrite(pwm_l,64);
analogWrite(pwm_r,MEDIUMFAST);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn left more speed

if(s_lt1==HIGH&&s_c==HIGH&&s_rt1==HIGH)//111 lost line… come back using last value.
{
if(d<0)
{
analogWrite(pwm_l,FAST);
analogWrite(pwm_r,MEDIUM);
digitalWrite(lt1,LOW);
digitalWrite(lt2,HIGH);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn right at high speed
else if(d>0)
{
analogWrite(pwm_l,MEDIUM);
analogWrite(pwm_r,FAST);
digitalWrite(lt1,HIGH);
digitalWrite(lt2,LOW);
digitalWrite(rt1,LOW);
digitalWrite(rt2,HIGH);
}//turn left at high speed.
}

}

can you please telll me how to figure out therse magic nos using the PID alorithm?

Where did you get that formula?

I think that trial-and-error is the best way to get numbers that work.

i got it from here..

http://www.chibots.org/index.php?q=node/339

Sorry if I'm wrong here, but I think you're asking for what values to use for your PID constants.

Tuning PID controls is complicated, but there are some guidelines that might work if your system is simple enough.

a) Tune P(roportional) first. Set I = D = 0. Get your system correcting for errors without going crazy. Going unstable is fine; it will probably constantly hunt/overshoot. b) Next tune D(erivative). Slowly increase it until your system stops overshooting/is adequately damped. You might be able to increase P after you dial in some D. c) Finally tune I(ntegral), but if it works without I then leave I = 0. I is often only needed for systems that have a lot of inertia and are slow to respond. E.g. HVAC system controls with large thermal mass, or low-G guidance systems.

Beyond this trial and error approach, it takes a lot of mathematics (Laplace transforms anyone?) to model a system and calculate these constants.

is PID also applicable for digital sensors? if yes how do i implement PID with digital sensors?

What sort of digital sensors?

PID control requires closed-loop feedback that tells the controller what the error vector is between current and target state. In the case where your sensors can only provide you an error vector with only magnitudes 1 or 0, PID control is useless.

There are digital sensors that count increments and are very useful and common for PID control; encoders.

the link is given above, the data sheet says it has some sort of comparator circuit which compares the sensor output with a predefined POT value and hence gives either a 1 or 0.

the link is given above, the data sheet says it has some sort of comparator circuit which compares the sensor output with a predefined POT value and hence gives either a 1 or 0.