0
\$\begingroup\$

I have tried my hand at writing a PID controller to control a the output power of a laser in response to the measured temperature of some thing. The measurement of the temperature can be very noisy at certain temperature ranges, though the picture below was taken in a less noisy range.

Here is a current view of the PID in action

enter image description here

My current issue is not the oscillation in the command signal to the laser, I have since found some descent parameters that smooth it out nicely. My real issue is the initial drop off to the lower limit of the command signal range then the rise back to appropriate levels.

Some more background. The PID itself works by first using a lookup table to command the laser signal to a "close" value of what it should be to get the initial temperature close for the PID, it does this for X amount of seconds (20-30 has worked well to get it to a stable temperature).

The idea behind this was to hopefully fix the issue we were (are) having of the PID initially wildly oscillation between the minimum and maximum output signal. This is highly undesired and can hurt the thing being heated.

So once the lookup table value command time has expired the PID is then given control, in the image above you can see pretty clearly when this is (the initial sharp drop). Then it relatively quickly rises back to an appropriate signal.


What I think is happening is that the previous error and previous integral terms have not yet accumulated proper values (they start at 0) for the PID to produce the proper command signal at the desired set point.

Is the way to fix this to initialize the previous error and previous integral to values close to what they are when the PID is stable near the end of the graph?

\$\endgroup\$
  • 1
    \$\begingroup\$ The sharp drop is because the error is high. The proportional term is going to go way down, and since you have no integral built up, of course the output will drop. I'm not exactly keen on the "lookup table" approach, I'd rather see the loop better tuned, but if you are okay with the lookup table, just force that value to the integral term, suppressing P and D until the time expires, then enabling the full PID with the integral preset. \$\endgroup\$ – R Drast Sep 21 '16 at 13:50
  • \$\begingroup\$ Or increase P. The response is classic low bandwidth controller w.r.t. desired response \$\endgroup\$ – JonRB Sep 21 '16 at 14:02
  • \$\begingroup\$ @RDrast I think you should make that an answer. \$\endgroup\$ – Andy aka Sep 21 '16 at 14:26
1
\$\begingroup\$

The sharp drop is because the error is high. The proportional term is going to go way down, and since you have no integral built up, of course the output will drop.

I'm not exactly keen on the "lookup table" approach, I'd rather see the loop better tuned, but if you are okay with the lookup table, just force that value to the integral term, suppressing P and D until the time expires, then enabling the full PID with the integral preset.

With regard to the comment about increasing the proportional gain, I'd advise against that as increasing the proportional gain would probably drive that system into oscillation; and increasing it would also cause a much sharper drop when switched from "Startup" to "Run" mode.

Ultimately, you probably do want to pre-load the integral term with your pre-calculated output value and just let it run. Tuning PID's by just playing with the gains (or gain/reset/rate, depending where your come from) usually doesn't end up with a stable system.

There are many methods of tuning PID loops, but if you must "Wing" it, typically reduce the I and D terms to zero, run P up until the system oscillates, and back P off by about half. That should give you a steady state error. Next, increase I slowly, until the error is eliminated, and the system doesn't hunt. D should normally only be used slightly in most loops, but might be necessary in very dynamic controls.

\$\endgroup\$
1
\$\begingroup\$

You are essentially correct, the PID controller reduces the output because both the P and I terms start off near zero. P is small because the error is small, and I is small because it is initialised at zero. The solution is as you say - set the I term to the value which would result in the desired output when the P and D terms are zero, then pass control over to the PID loop. This is known as "bumpless transfer".

Additionally, I don't think your PID system is well tuned (though you say it has improved since taking those traces). There are many ways of tuning a PID controller, but the quickest and simplest is the Ziegler–Nichols method. You should be able to get much better control than in your images. You might find you need different PID values for different setpoints. In which case you need a lookup table, and if you want to do smooth transfers between zones in the lookup table you can use bumpless transfer there too.

I think you would also benefit from speeding up the PID loop or temperature measurement. At the moment, you only have a couple of data points per oscillation, the PID loop will work better if you can get about 10.

\$\endgroup\$
  • \$\begingroup\$ Yes, the image above is a bit old, the oscillations you see have basically disappeared for its current tuning, but as I said the drop (bump) is still present. // Also that is another issue I forgot to mention, The measurement of the temperature is dependent on another system to produce the data from which the temperature is derived, which this system cannot be changed. So I am stuck with a range of 2 (in the image) to potentially 30 seconds between loop updates. \$\endgroup\$ – KDecker Sep 21 '16 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.