Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help with digital pid implementation

Status
Not open for further replies.

vinayakdabholkar

Advanced Member level 4
Joined
Nov 29, 2009
Messages
114
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,296
Location
goa
Activity points
2,195
I have implemented a digital pid as a second order module based on the following equations
ek = sk - yk; /* Calculate error term */
rk = ek + M1;
uk = a0*rk + M2; /* Calculate output */
rk 2 = rk 1; /* Update variables */
rk 1 = rk;
M1 = -b1*rk 1 - b2*rk 2;
M2 = a1*rk 1 + a2*rk 2;

based on this output yk i have to vary the duty cycle of my pwm
sk is my setpoint of 1.2 while yk is the ADC output*resolution of ADC, so a analog value
I have the duty cycle going from 0-40. i.e 40 is 100% duty cycle
How do i set the duty cycle based on this output uk and the error ek as if error is more i have to increase the duty and if error is less i have to decrease it ?
I have wriiten a code but it doesnt work
Code:
while(1)
{
yk=ADCRead(0);            //Read Channel 0
ek=sk-yk;                 //calculate the error
rk = ek+M1;
uk = (a0*rk)+M2;          /* Calculate output */
//new_duty=yk;                          
if(ek>1)                  // if error is positive
       {
       new_duty=init_duty+yk; //increase duty by yk
       if(new_duty>40)        // if max duty has been reached  
                     {
                     new_duty=40; // set duty to max=40
                     }  
       }  
else if(ek<0)                  // if error is negative 
           {
           new_duty=init_duty-yk; // decrement duty by yk
           if(new_duty<0)         // if min duty has been reaached
                        {
                        new_duty=0; // set duty to 0
                        }
           }
else
    {
    new_duty=4; //if error is zero set duty to 10 which is required 10% 
    }     
SetDCPWM1 (new_duty);           
SetDCPWM2 (new_duty);

- - - Updated - - -

My init_duty is 4 i.e 10% and the duty increment and decrement are by uk and not yk
 

The equations suggest a general time discrete second order system using the controllable canonical form. But it's not implemented in the code, M1 and M2 aren't calculated.

new_duty should be set from controller output uk. Technically, variable types, number ranges and parameter scaling matters. This details can't be seen from your code.

P.S.: A digital controller usually needs auxilary functions, particularly anti-windup. It can't be easily implemented in the canonical form, other PID impementations are better suited for it, e.g. the velocity algorithm.
 
Last edited:
The equations suggest a general time discrete second order system using the controllable canonical form. But it's not implemented in the code, M1 and M2 aren't calculated.
I implemented them but by mistake skipped the end of the code
Code:
rk2=rk1;                  
rk1=rk;
M1=(-b1*rk1)-(b2*rk2);
M2=(a1*rk1)+(a2*rk2);
new_duty should be set from controller output uk. Technically, variable types, number ranges and parameter scaling matters. This details can't be seen from your code.
could you tell me more on this, the variable types, parameter scaling aspects
some reference will be good
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top