Difference between revisions of "PID"

From emboxit
Jump to: navigation, search
(Cytron)
 
m (1 revision)
 
(No difference)

Latest revision as of 16:51, 11 September 2015

Wikipedia

PSEUDOCODE
previous_error = setpoint - process_feedback
integral = 0
start:
 wait(dt)
 error = setpoint - process_feedback
 integral = integral + (error*dt)
 derivative = (error - previous_error)/dt
 output = (Kp*error) + (Ki*integral) + (Kd*derivative)
 previous_error = error
 goto start

File:Pid-ziegler-nichols-1.jpg



mbed

File:Pid-mbed-1.jpg
  • Where
Kp is the Ultimate Gain where there is constant oscillation
Tu is the oscillation period


ANALOG PID

Elektor UK 2008 September page 62

600px
Servo control
The electronics for the servo drive can be kept quite simple (see Figure 3). P1 is used to set the input signal sensitivity and determines the maximum 
projection format. P2 sets a DC-offset, which is used to move the projection image a little, for example. 
IC1a amplifies the difference between the signal from the magnet sensor and the input signal. 
When this difference is positive, the motor turns in the opposite direction compared to when this signal is negative. 
In this way a closed loop is created which is necessary for controlling the servo. 
IC1b is a proportional-differential (PD) amplifier. <----correction: IC1a is PD amp...
This is indispensable to correct the phase of the feedback loop.
IC2 and IC3 are connected as a bridged amplifier for driving the motor. 

These ICs,  type  TDA2030,  are  intended  as an audio amplifier but are functionally just big difference amplifiers that can deliver about 3 A. 
More than enough for this type of motor. Four diodes prevent the inductive flyback voltage of the motor from damaging the IC.The power supply voltage for these ICs 
is provided by a 7809 regulator. With a 9-V power supply, IC2 and IC3 can drive the motor with plus and minus 6  volts. In the prototype IC2, IC3 and 
the  7809  were  all  mounted  without insulation on a common heatsink. The current consumption of the servos depends on the amount of drive. This 
is typically not more than 100-200  mA each. The average power consumption of the entire projector including a 5 mW red laser module is about 300 mA. Bat-
teries will therefore not last very long, but powering from a mains adapter or a small lead-acid battery for ‘in-the-field operation’ are good options.

Circuit Cellar analog

1000px

To Classify



PID in C

Motor Control using PWM and PID

<cpp> /* The following code is a PID loop implementation using floating point variables. The structure (pid_f_t) is first initialized using pid_init_f() with the minimum and maximum values for the manipulated variable. The minimum is useful if the motor requires some minimum PWM duty cycle to make it turn while the maximum ensures the PID algorithm does not try to exceed one hundred percent duty cycle. The pid_update_f() function takes the current set point and the process variable as well as the constants stored in the pid_f_t structure to compute the manipulated variable. The application loop should include a function to

measure the current or speed, 
call pid_update_f() to calculate the manipulated variable, 
then set the PWM value according to the manipulated variable.
  • /

typedef struct{

 float max /*! Max manipulated value */;
 float min /*! Miniumum manipulated value */;
 float e /*! Error value */;
 float i /*! Integrator value */;
 float kp /*! Proportional constant */;
 float ki /*! Integrator constant */;
 float kd /*! Differential constant */;

} pid_f_t;

/*! \details This function initializes the data in a PID structure.

*
*/

void pid_init_f(pid_f_t * ptr /*! A pointer to the PID data structure */,

   float min /*! The manipulated variable's minimum value */,
   float max /*! The manipulated variable's maximum value */){
 memset(ptr, 0, sizeof(pid_f_t));
 ptr->min = min;
 ptr->max = max;

}

/*! \details This function updates the value of the manipulated variable (MV)

* based on the current state of the PID loop.
*/

float pid_update_f(float sp /*! The set point */,

   float pv /*! The process variable */,
   pid_f_t * ptr /*! A pointer to the PID constants */){
 float temp;
 float e;
 float p;
 float manp;
 float tmpi;
 e = ptr->e;
 ptr->e = sp - pv;
 tmpi = ptr->i + ptr->e;
 //bound the integral
 manp = ptr->kp * ptr->e + ptr->ki * tmpi + ptr->kd * (ptr->e - e);
 if ( (manp < ptr->max) && (manp > ptr->min) ){
   ptr->i = tmpi;
 } else if ( manp > ptr->max ){
   manp = ptr->max;
 } else if ( manp < ptr->min ){
   manp = ptr->min;
 }
 return manp;

} </cpp>


Build Your Own Microcontroller Based PID Control Line Follower Robot (LFR) – Second Part

File:Pid-c-1.jpg

<cpp> ... unsigned char MaxSpeed; // Hold Motor Maximum Speed unsigned int Kp,Ki,Kd; // PID Parameters int prev_res=0, prev_err_1=0, prev_err_2=0; // PID Control Variables

... ... int motor_res,err_func; float KP,KI,KD,cont_res;

// Get the Error Function err_func=sensor_val - TARGET_VAL;

// Divide all the PID parameters for decimal value KP=Kp * 0.1; KI=Ki * 0.01; KD=Kd * 0.01;

// Calculate the Motor Response using PID Control Equation cont_res=(float)(prev_res + KP * (err_func - prev_err_1) + KI * (err_func + prev_err_1)/2.0

              + KD * (err_func - 2.0 * prev_err_1 + prev_err_2));        

// Now we have to Limit the control response to the Maximum of our motor PWM Motor Value motor_res=(int)cont_res;

if (motor_res > MaxSpeed)

 motor_res = MaxSpeed;

if (motor_res < -MaxSpeed)

 motor_res = -MaxSpeed;

// Save the Motor Response and Error Function Result prev_res=motor_res; prev_err_2=prev_err_1; prev_err_1=err_func; </cpp>


PID control algorithm- C language

<cpp>

  1. ifndef PID_H_
  2. define PID_H_
  3. include

//Define parameter

  1. define epsilon 0.01
  2. define dt 0.01 //100ms loop time
  3. define MAX 4 //For Current Saturation
  4. define MIN -4
  5. define Kp 0.1
  6. define Kd 0.01
  7. define Ki 0.005

float PIDcal(float setpoint,float actual_position) { static float pre_error = 0; static float integral = 0; float error; float derivative; float output;

//Caculate P,I,D error = setpoint - actual_position;

//In case of error too small then stop intergration if(abs(error) > epsilon) { integral = integral + error*dt; } derivative = (error - pre_error)/dt; output = Kp*error + Ki*integral + Kd*derivative;

//Saturation Filter if(output > MAX) { output = MAX; } else if(output < MIN) { output = MIN; }

       //Update error
       pre_error = error;
return output;

}

  1. endif /*PID_H_*/

</cpp>

edaboard

<cpp> //Simple PID //PID = GainP * actual error + GainI * SUM(previous errors) + GainD * (actual error - last error) //error = sp(set point) - pv(process value) float pid (float sp, float pv){

 err_old = err;
 err     = sp - pv;
 //note. Dead zone example: if (err<2 && err>-2){err=0;}
 P_err  = err;
 I_err += err_old;
 D_err  = err - err_old;
 return 0.1*P_err + 0.3*I_err + 0.02*D_err;

}

</cpp>

<cpp> /*u=kp*(e+Td*diff(e)+Td*int(e)) y0=analog input 1; r0=ref=set point or reference; T=sample time; qd=diff constant=Kp*Td/T; //Td:diff time qi=integral cosntant=Kp*T/Ti; //Ti:Integration time Kp=prop gain;*/

float pid (float r0, float y0) { e0=r0-y0; D=qd*(e0-e1); if (((u>umin)||(e>0))&&((u<umax)||(e<0))) //antiwindup integral //Your code should use the || and && operators I=I+qi*(r0-y0);

u=Kp*e0+D+I;//pid control signal if (u>umax) u=umax; //antiwindup PID if (u<umin) u=umin;

e1=e0; //save old values y1=y0; } </cpp>

Practical PID Controls



PID Theory


Cytron

File:Cytron clip image0271.jpg


Atmel