PID... maybe I need a PhD...?

Hi Guys,

I used Tim Wescott's PID without a PhD document to come up with my controller loop. Now, my application is a light source that is being controlled with the duty cycle of a pwm - I have a current feedback loop that is telling me how much current is going through the LEDs. Now to get these values on the same scale, I just read what my ADC reads at maximum allowed current and that is 100%. And then my input (IRDrive) is controlling how intens the LEDs should be (again in %). My control loop looks like this: double UpdatePID(SPid * pid, double error, double position) { double pTerm, dTerm, iTerm; pTerm = pid->pGain * error; // calculate the proportional term // calculate the integral state with appropriate limiting pid->iState += error; if (pid->iState > pid->iMax) pid->iState = pid->iMax; else if (pid->iState < pid->iMin) pid->iState = pid->iMin; iTerm = pid->iGain * pid->iState; // calculate the integral term dTerm = pid->dGain * (position - pid->dState); pid->dState = position; return pTerm + iTerm - dTerm; } And I played around with various P,I and D gains but seem not to be able to get it ionto a steady state, it keeps flocking all over. The struct looks like this: typedef struct { double dState; // Last position input double iState; // Integrator state double iMax, iMin; // Maximum and minimum allowable integrator state double iGain, // integral gain pGain, // proportional gain dGain; // derivative gain } SPid; Before I implemented the PID controller, I simply had this: AVGfdbckprcnt = ((float)100/(float)MAX_CURRENT) * AVGfeedback; /* if (AVGfdbckprcnt < IRDrive){ if (CurrPWM < 255) CurrPWM++; PWM_WriteCompare(CurrPWM); } else if (AVGfdbckprcnt > IRDrive){ if (CurrPWM > 0) CurrPWM--; PWM_WriteCompare(CurrPWM); } else continue; PWM_WriteCompare(CurrPWM); Which worked fine and now i replaced this with: AVGfdbckprcnt = ((float)100/(float)MAX_CURRENT) * AVGfeedback; CurrPWM = UpdatePID(&Cntrl, AVGfdbckprcnt-IRDrive, AVGfdbckprcnt); PWM_WriteCompare(CurrPWM); which doesn't quite work yet... Any clues, hints or suggestions would be appreciated!

Thank you! roN

Reply to
cerr
Loading thread data ...

Ok,

I got a few more details. In order to tuine the controller, in the doc it says "If it isn't set already, set the proportional gain to a starting value between 1 and 100. Your system will probably either show terribly slow performance or it will oscillate. If you see oscillation, drop the proportional gain by factors of eight or 10 until the oscillation stops."

Now at 1 my circuit oscillates thus I go down and down and down and am now at a pGain or 0.020405 and it's still oscillating - it just seems like the smaller the number gets, the lower the oscillation frequency gets. I'm now in the milliHertz area already, it seems like it trys to reach the target ever 3 (or so) seconds and the rest of the time it's just at 0. It also seems to change as I modify the target to reach but there's no talk of that in the doc from T. Wescott. Not sure if my code is off somewhere...?

Any hints or suggestions anyone?

Thanks, R> Hi Guys,

Reply to
cerr

From your followup posting, this may not be a simple loop oscillation. A bit of info on your timing would help, maybe it's inferrable from your code but I don't have the energy to troll through it. Can you let us know the frequency of the PID function and of the PWM?

Reply to
Bruce Varley

* if

I'm not sure what else is going on, but your error term should be command - feedback; you've got the value backwards.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
Reply to
Tim Wescott

What is the basic behavior of your LED circuit? It seems that this should be a fairly instantaneous (if not always nicely linear) response: i.e., the response to a step change in the drive is a step change in the feedback, without any "tail" -- is this so?

If so, then I'm surprised. That sort of behavior is best handled with a pure integrator (proportional and differential action are only of help when the plant shows lag that extends past the next sampling instant). A purely proportional gain will either be stable or will go into an oscillation with a period of half the sampling rate; it certainly won't do what you're seeing. Given that your original code is a very crude approximation of a pure integrator, I'm even more puzzled why pure proportional gain causes problems.

Try fixing your sign inversion problem, then (if I'm correct about your plant behavior) try setting the proportional and derivative gains to zero, and experiment with integral gain only. You should be able to deduce proper operation -- if the current is too high then the drive should go down, and visa-versa. What integral action will give you that your current algorithm doesn't (aside from not giving control guys who look at it headaches) is a much faster response when the actual feedback is a good deal different than the target value.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
Reply to
Tim Wescott

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.