I'm having issues tuning a PID controller - specifically the I-term. First - here's a little info about my system:

I'm heating a coil (R ~= 1.8 Ohms) to 750°F. My power delivery system is working fine. I'm applying a maximum of 12V to the coil, so there's about 7A going through the heater. I'm monitoring temperature with a k-type thermocouple. I've double-checked with another thermocouple and DMM to make sure my microcontroller is reading the right temperature data. It is. If you have clarifying questions about the system hardware I'd be happy to answer but I'm pretty sure my issue is coming from my tuning method.

I'm following these Ziegler-Nichols PID tuning tutorials: 1 2 3

I set my I-term and D-term gain to zero and slowly increased my P-term gain until I got stable oscillations:

P Gain = 5 P Gain = 6 P Gain = 7 P Gain = 7.5 P Gain = 8.0

After achieving stable oscillations and choosing a P-term gain of 8.0, I calculated my new P-term and I-term values per the equations in the tutorials (P Gain = 3.63, I Gain = 0.42):

P Gain = 3.63, I Gain = 0.42

As you can see, although the oscillations are much more centered, they have not diminished as they do in the first tutorial. When I calculate and implement the D-term gain, I still get unsatisfactory behavior:


My Question is this: where do I go from here? Should I start over with a new P-term? Change I-term and keep everything else the same? Change D-term and keep everything else the same? Any input is welcome.

From 130°F with error term:

From 130°F

  • \$\begingroup\$ I just skimmed the first few graphs. So I and D terms are not used, only P, if I gather you. A way oscillation takes place with pure P term is lag/delay. And probably variable lag/delay, if you wrote the software without extreme care to timing. When I write a PID, it will have variability between input sample time and control output time that is on the order of a few microseconds. Rock solid repeatability. And I keep the delay as short as possible, too. First step would be to tighten up your timing. Don't pursue an I-term until timing is as good as possible. "I" isn't a 'delay' remedy. \$\endgroup\$
    – jonk
    Jun 20, 2018 at 19:43
  • \$\begingroup\$ Didn't have room to add it and besides I think you already know it, but placement of the K-type thermocouple matters. Thermal delay in the system is bad, too, though its delay is usually more repeatable than some software I've seen often can be. Dealing with delay is manageable. Dealing with variable delay is much harder. \$\endgroup\$
    – jonk
    Jun 20, 2018 at 19:47
  • \$\begingroup\$ Try a negative value for your differential term. \$\endgroup\$
    – Andy aka
    Jun 20, 2018 at 20:18
  • \$\begingroup\$ The oscillations look like limit cycles that can be obtained in a saturated system. Saturation has the effect of progressively reducing the loop gain as the error signal amplitude increases and, conversely, increasing the loop gain as signal amplitude decreases. So you get relatively small oscillations when the output is approximately equal to the input; any tendency to increase the amplitude of oscillations will automatically reduce the loop gain, hence they settle to self-sustaining amplitude. Reduce the fixed loop gain to remove the limit cycle. \$\endgroup\$
    – Chu
    Jun 20, 2018 at 23:00
  • \$\begingroup\$ I'm not an expert on control systems at all, this is an honest question... Why are you using a microcontroller at all? A few op amps and passive components can implement pid easily, and be much more power efficient. Passive aren't exactly matched of course, and can have temperature stability issues, but it seems (to me) the better solution. Is digital really preferred these days for even this simple controller? \$\endgroup\$
    – Matt
    Jun 21, 2018 at 2:37

4 Answers 4


Update: See the update 3 at the bottom. After re-reading the answer I realized that some of my statements below are not applicable to thermal systems.

One thing strikes immediately as suspicious, on all P-only graphs the oscillation is happening under setpoint. That is not how P term works. In order to oscillate it must cross setpoint.

So, figure out this part, and I think it will go well with the rest.

Update 1: most important here are thermal inertia, timing and continuous linear control action. For example, if output power cuts-off at some low value you can see oscillations under setpoint.

Regardless of that, in a context of PID tuning the "stable oscillations" that you need to achieve as first tuning step should go way beyond setpoint.

Also, before introducing I-term make sure you added anti-windup measures. This is extremely important in thermal control systems due to inherently slow response.

Update 2: I just recalled this article, which I used to write my own auto-tuning library long time ago. It did not work well for me because my mechanical system had strict acceleration restrictions. But I think it should be very good for a system with slow response, such as yours.

Update 3: There is inherent complexity to P-term response due to the nature of thermal systems. Unlike typical servo applications the downward slope cannot be controlled by reversing control command, it happens naturally and depends on environment conditions. The consequences are:

  • There is no or very limited overshot due to P-term, no matter how big it is. So typical PID tuning methods like Ziegler–Nichols might not work as expected.
  • The I-term requires aggressive anti-windup measures, especially taking into account non-symmetrical slopes.
  • Rather then improving response the D-term might cause instability, especially if feedback is noisy.
  • Output power should be considered an additional process variable for the purpose of tuning. You can achieve more or less stable temperature, but if your output power continues to oscillate widely your system is not actually stable.

One of the tricks of thermal control systems is to closely match power plant to the process. Meaning - if your heater is too powerful it will be harder to tune.

If you have very fine control over power output your proportional band can be quite narrow, meaning P-term only applies to the limited range near setpoint and works as On/Off switch otherwise.

Another trick is to always change only one term at a time, but make big changes (like double or halve the term) at least initially. Thermal systems do not respond to small changes as servos do.

  • \$\begingroup\$ Wouldn't an ideal P-only system always oscillate below the setpoint? After all, Kₚ * error approaches zero when the process value approaches the setpoint. \$\endgroup\$
    – piojo
    Jun 21, 2018 at 5:59
  • 2
    \$\begingroup\$ Ideal P-only system will never oscillate, it will be forever trying to approach setpoint from below. This assumes that ideal system does have some friction loss. In order to oscillate your error must change the sign, and that can only happen when you cross the setpoint. Of course, I am talking about ideal system with linear response. In thermal system with high inertia and switch-type control the oscillations indeed might happen below setpoint. \$\endgroup\$
    – Maple
    Jun 21, 2018 at 6:32

Can you post your implementation within your microcontroller?

What I think is going wrong in that final graph is that your I term has a gigantic amount of accumulated error by the time you get to the setpoint, and the oscillations not settling is due to that integrated error from the initial rise having no way of being resolved. If you wrote the PID controller from scratch, I would try clearing the integrated error after a few oscillations, or decreasing I and increasing P/D. You could also try using just a pure P/D controller.

It would also help if you could post a graph that included the error term, if you have any way of generating that.

  • \$\begingroup\$ Sure thing, waiting for the heater to cool down to room temperature and then I'll run another trial - that's another thing I was a bit unsure of, do I need to wait for the heater to go all the way down to room temp before testing new parameters? Or can I start the cycle at, say, 200°F? \$\endgroup\$ Jun 20, 2018 at 18:25
  • \$\begingroup\$ Try starting the cycle at 200°F and see what happens! If the resulting oscillations are a bit smaller then I might be right. If you have the time, I would also try increasing the setpoint 50°F at a time. \$\endgroup\$
    – Tri
    Jun 20, 2018 at 18:28
  • \$\begingroup\$ Started cycle from 130°F - looks like the oscillations are even bigger. One sec I'll add the picture to my post \$\endgroup\$ Jun 20, 2018 at 18:34
  • \$\begingroup\$ Sorry, I meant to ask you to post the accumulated error term (as in the number that the I constant gets multiplied by), not the actual error. \$\endgroup\$
    – Tri
    Jun 20, 2018 at 18:49

Those oscillations are some other nature. The Kp=8 is not nearly critical. You should make a lower setpoint, then increase P-Gain to get stable oscillations, and they are huge.

Post a trend of process value (temperature) and manipulated value (output) vs time. Show your setup - how do you control the heater?


Keep I & D at zero, now tune your P term so that it doesn't quite reach setpoint (imagine it reaching setpoint at infinity). Now, add in a tiny bit of I to speed up the rate at which it reaches setpoint. I've never needed to use D, it's very susceptible to noise on the input measurement. Your graphs show oscillation because P is too high.


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.