# How to implement a self tuning PID-like Controller

I am trying to write a micro-controller program for controlling temperature in a system with the following characteristics:

• output can only be On or Off, with fixed cycle frequencies (~2-10 per hour)
• The plant is slow to respond (measurable changes in temperature take a long time > 10 minutes).
• The plant loses temperature based on environmental conditions.
• the set-point can vary in large steps based on user demand.

I am writing a controller that aims to minimize error, as well as adhering to the cycle-rate provided as an input.

This could easily be done with a PI controller and it's output converted to the duty-cycle. The problem is that the program needs to auto-tune and choose correct Kp, Ki constants and adapt to varying environmental conditions and changes in heating capacity. Therefore, tuning the PI controller in advance is not too useful.

Using an actual PI or PID is not a requirement. I'm open to use of Fuzzy-Logic if it helps, also have a machine-learning algorithm on the chip that models the system response and heat-loss (linear approx.) which suggests information about measured step response. Just don't know what to do with that information.

A couple of posts suggest I could use the modelling data to tune the PI on-line, as well the lab-view manual that suggests I could use Fuzzy-Logic to tune the PI.

My question is, what is the best approach for this kind of scenario (e.g. PID, fuzzy-pid, convolution, etc) and how would I go about actually implementing it in software/practice.

I'm not a EE so any input would be greatly appreciated.

• I wrote an answer about using a simplex algorithm to automatically tune PID controllers over on the Robotics SE that may be of interest. Commented Nov 28, 2012 at 16:45
• @embedded.kyle great, I understand simplex/greatest-acent. Can you tell what he used to for x1,x2? I'm having trouble relating them to PID constants. Commented Nov 28, 2012 at 17:20
• It's been a while but I believe we used something like x1 = P, x2 = I, x3 = D. x0, the center of gravity, is whatever measurement of stability is most important to you. In my application, motor control, we had two loops. The x0 of one was velocity and the x0 for the other was current. See here for more. Commented Nov 28, 2012 at 18:23
• @embedded.kyle do you mind turning your comment into an answer? add any additional info if you wish. -thx Commented Dec 7, 2012 at 14:34
• A bounty? Oh, boy! Done and done. Commented Dec 7, 2012 at 15:25

I wouldn't go so far as to call PID outdated. But there certainly is room for improvement. One way in which I have auto-tuned PID control loops is to use the Nelder-Mead method which is a form of hill climbing simplex algorithm. It has the benefit of being able to converge and reconverge on a target parameter that moves over time.

From this paper:

For example in our case of PID parameters tuning {KP, KI, KD} a simplex is tetrahedron. Nelder–Mead generates a new test position of simplex by extrapolating the behavior of the objective function measured at each test point arranged as the simplex. The algorithm then chooses to replace one of these test points with the new test point and so the technique progresses.

My particular application was for motor control. We had two loops, a PID current control loop and a PI velocity control loop. We set our vertices to P, I, and D respectively and ran statistics on the output of the loop. We then ran the reflection, expansion, contraction, and reduction over and over again until the current or velocity control targets generated were within a few standard deviations.

With our product, the VP was very concerned with how the motor "sounded". And as it turned out, it "sounded" better when the current target bounced a bit more than was mathematically optimal. So, our tuning was done "live" in that we let the algorithm seek while the motor was running so that user's perception of the motor sound was also taken into account. After we found parameters that we liked, they were hard-coded and not changed.

This probably would not be ideal for you since you state, "putting the system in oscillation even as a part of auto-tuning is not acceptable to the users". Our system would most certainly oscillate and do other horrible things while it was auto-tuning.

However, you could run two copies of the PID controller. One that was "live" and actually controlling the process. And a second that was constantly being auto-tuned while being fed the same inputs as the "live" controller. When the output of the auto-tuned controller became "better" or more stable, you could swap the coefficients into the "live" controller. The controller would then perform corrections to the process until the desired performance was achieved. This would prevent oscillations that can be perceived by the user during auto-tuning. But if the inputs change drastically and the PID controller is no longer optimal, the auto-tuning can swap in new coefficients as they become available.

• The NM method does require to run its wild points on the objective function (i.e. user's real world). However, I believe a crude model (space-state?) can be built on the micro-controller itself based on sensor measurements. It would then run your proposed 'shadow' PI controller as it optimizes. I'm not sure of this an over-kill since it may be possible to tune a PI to a known setting and then scale the Kp and Ki based on the sensor readings and system response. Either way, well done sir. Commented Dec 7, 2012 at 16:07
• @MandoMando Thank you very much! And I really like the term 'shadow' PI controller. Commented Dec 7, 2012 at 16:54

A PID controller is useful in situations where the behavior of system being controlled can be reasonably approximated as being a sum of the control stimulus, the integral of the control stimulus and the integral of that first integral. Some temperature control systems may satisfy such a criterion, if there is an object which is heated uniformly by the stimulus, and if that object transfers heat uniformly to some other object at a rate proportional to the temperature difference between them. For example, the first object might be a heating element, and the second object might be the air circulating in a room, if there is enough air circulation for the air to be regarded as having a single uniform temperature. For thermal models more complicated than that (e.g. ones which may involve thermal gradients within a solid medium), achieving optimal results will require something more sophisticated than a PID controller.

I would suggest that a good approach might be to have the controller, when the heater is on, continuously estimate how hot the device being regulated would get if the output were switched off immediately, and the temperature to which it would end up cooling off if the heater were switched on as soon as permissible after that. Also estimate what those values would be if the heater were left on for another second, two seconds, three seconds, etc. Switch off the heater when those values are as good as they're going to get. Then once the heater is off, start performing similar calculations, but swapping the roles of on/off, hot/cold, etc., to decide when to switch back on. Depending upon the thermal behavior of the system, it may be necessary to use a 'min/max' look-ahead strategy to look a step or two ahead.

Being able to change the state of the control (on or off) 2-10 times per hour doesn't lend itself to duty cycle control. The output of a PI loop is going to be a control signal that varies in magnitude as a function of the error, and your plant can (realistically) only accept a binary input (off or on), since the 'frequency' of the control duty cycle that can be accepted is a fraction of a hertz.

You may want to simplify things and go with hysteretic control:

• the system turns on when the temperature crosses a lower limit
• the system turns off when the temperature crosses an upper limit
• there is sufficient distance between the upper and lower limits to prevent bouncing of the control output
• the idea to is to take PI output say: 60% and convert to on-time = 60% of cycle -> 0.6 x 30 minutes -> 18 minutes on and 12 minutes off during the 30 minute cycle. the bang-bang controller you suggest does not guarantee keeping to the required cycle-rate (say switching on, no more than n times per hour) and keeping a low error at the same time. it may be necessary for the system to temporarily overshoot for a period of time to balance the loss during the off-time. Commented Nov 28, 2012 at 17:14

A typical (although admittedly simplistic way of doing this) is called gain scheduling. It is a classic approach to non-linear control when you have an observable variable (or variables) that your system changes with (scheduling parameter). In your system that variable would most likely be temperature. The idea is that you create a list of controller gains at different values of the scheduling parameter (temperature) and as the scheduling parameter changes you use those gains in your controller (be it PI, PID, state feedback or whatever). If this sounds really simple, it's because it is. However it does work and is used in some very complicated systems.

If you want to get fancy, you could implement a machine learning algorithm to generate your gain matrix. This would result in the evolving and learning controller you seem to be describing. However, it could be overkill if the system can be fully characterized.

Edit: Sorry, I misread a little. You are trying to control temperature so the "environmental conditions" you spoke of would be your scheduling parameter.

You could go full blown Recursive Least Squares controller, cf Astrom and Wittenmark, Adaptive Control, but I don't know if the microcontroller will have enough oomph to do this.