• Please visit and share your knowledge at our sister communities:
  • If you have not, please join our official Australia and New Zealand Homebrewers Facebook Group!

    Australia and New Zealand Homebrewers Facebook Group

AHB Wiki: PID Tuning

Australia & New Zealand Homebrewing Forum

Help Support Australia & New Zealand Homebrewing Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.

Adr_0

Gear Bod
Joined
4/4/13
Messages
1,776
Reaction score
684
Hi all,

This Wiki captures PID tuning, which is a follow-on from the basics on On/Off and PID control, found here:
http://aussiehomebrewer.com/topic/93924-ahb-wiki-pid-and-onoff-control-basics/?p=1431568

The tuning Wiki is below, which captures the following:
  • Specifics about the P, I and D terms
  • Why a home brewery is a little different to most common processes
  • Example P and PI responses
  • Tuning the controller
  • Notes on fridge/freezer control
View attachment PIDTuningWiki_rev0.pdf

Hopefully you find the Wiki is helpful.

Cheers,

Adrian
 
That's an excellent resource you've created. I do not think I've ever read a description of PID that is as accessible and as thorough.
 
Excellent.
Answered a lot of questions I'd had for a long time.
Thanks Adr_0
 
If anyone has any questions or experience they would like to share, it's probably a good spot to do so.
 
I have a question then!

For my HLTs (and HX) the PID parameters are K=500, I=0, D=0.45. (Arduino PID library)

It gets to within a few degrees of target in a reasonable time, and it never goes over.
The problem I have is that it bloody crawls those last few degrees.
In a small vessel it's pretty much OK, but in my big kettle (120L / 4500watt element) those last few degrees can take ages (an hour?). If I'm waiting around for it I can just fudge the set-point up a bit, and it gets the job done. But the whole point of the PID control is to not have to stuff around with it.

Adding any sort of Integral parameter produced overshoot, so we agree on that.

Is there some approach I can use to tune this?
It takes about an hour to heat ~120L water to say 75C, that's a long test-cycle time.
The arduino auto-tune library returned a useless result after about 20 minutes.

thanks,
-kt
 
Mr Wibble said:
I have a question then!

For my HLTs (and HX) the PID parameters are K=500, I=0, D=0.45. (Arduino PID library)

It gets to within a few degrees of target in a reasonable time, and it never goes over.
The problem I have is that it bloody crawls those last few degrees.
In a small vessel it's pretty much OK, but in my big kettle (120L / 4500watt element) those last few degrees can take ages (an hour?). If I'm waiting around for it I can just fudge the set-point up a bit, and it gets the job done. But the whole point of the PID control is to not have to stuff around with it.

Adding any sort of Integral parameter produced overshoot, so we agree on that.

Is there some approach I can use to tune this?
It takes about an hour to heat ~120L water to say 75C, that's a long test-cycle time.
The arduino auto-tune library returned a useless result after about 20 minutes.

thanks,
-kt
How long is your coil, and what's your element size and mash tun size?

I'm pretty sure Auber has P in units /100, so 300 is actually a gain of 3 - is Arduino the same? And do you know if the D term is in per second or per minute?
 
In my HLT, it's a big 185 litre pot with a 4500 watt heater element. Obviously the amount of water varies on brew-size.
Generally the more water, the slower it crawls over the finish line. With 120 litres, I guess it takes about an hour to cover the last 2 oC. This is my real problem, that lousy 2oC. It's quite frustrating, you can watch it and see the algorithm only flashes the heater on for a split-second, yet it still significantly below the correct temp. It's been suggested to not start using PID until it's within a degree of set-temp, but this removes the whole point of using PID.

BTW, and FWIW: The pot is insulated (yoga mats!).


But the HX ~ Ah, ahem, geeze.
735HERMIT_COIL_KIT_LG.png


Ok, so it's Nev's s.steel "HERM-IT" coil. - https://onlinebrewingsupplies.com/herm-it-r-coil/herm-itr-coil-kit
It doesn't say exactly how long it is, but 9x coils, with 12mm tube, ~90mm OD. So that's: 9 x Pi x 90 => 2544.7 -> so say 2.5 metres[1].
It's in a about a 6-litre pot, with a 2500 watt element. With the coil submerged, there's just about exactly 5 litres of water around it.
It doesn't really have a whole lot of trouble getting to the target temperature.


The way Arduino PID library[2] is used is that the PID-control governs the amount of a 5 second window used for heating each iteration.
So for "full power" that whole 5000ms is used, but for "half power" only 2500ms of it used, etc. The output of the PID computation is how much of that 5000ms should be used for heating in the upcoming 5000ms. It has to be like this, because a heating element can only be on or off.

I think this 5 second time amount is a bit arbitrary, if it's shorter or longer, the PID algorithm would still turn the heater on for a calculated percentage of the time.
With a smaller time, it would evaluate the should-I-apply-heat-now question more often, but I expect it would heat much the same (probably).

I'm not at all familiar with any PID stuff other than this Arduino Library (I did not do any control systems courses at uni), so I can't really say what the units represent - if anything.

I have, for example, used the same PID library to hover a quad-copter test-balance-arm by changing the motor speed on feed-back from a gyro' (here P=2, I=0.95, D=0.011) - so the library works well, and is pretty flexible. But I don't think it has the concept of the units meaning anything in the non-mathematical sense. I guess that's not much help but.

thanks,
-kt

[1] circumference of a circle is (Pi x diameter), a coil is roughly /N/ diameters, thus length is (/N-coils/ x Pi x diameter).
[2] http://playground.arduino.cc/Code/PIDLibrary and an intro to it http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/
 
So where are the probes that are controlling your temperature? If you're using 2.5m if coil in 5L that's pretty good, though your temp control should be on the wort return to the mash tun.

I say good because you should also be able to get a fair bit of pump flow - what is your limitation there? Do you have a KK fully open or choked?

And the other temperature problem is on the HLT, where you have a PID controller and it struggles to get that last degree or two? This isn't a problem in your mash?
 
Probe on the HX is on the top of the coil right at exit.

Probe on the HLT is near the bottom, on the same level as the element.
The HLT probably does need a mixer, or recirculating pump.

Using KK pumps, fully open. Silicon hose inter-connects.
 
Sweet.

Yeah, regarding the HLT you've hit the nail on the head. Mixing - even by stirring - will help that a lot. For the PID on the HLT I would drop the D term completely - make it 0 - and keep the Gain at 500. Technically the element is a touch under-sized to get a good ramp rate - 7200W is probably ideal - but if this isn't an option you might consider gas assist as well (with an alarm from your Arduino at 80-90°C to turn it off). Mixing of the HLT means you should hit your setpoint with P control only and it should be bang on.

Regarding your MLT, if I were you I would actually consider putting control in your mash tun, in the middle and maybe 2-3" below the surface, and plugging the existing probe takeoff on the HERMIT. Your P and D values should probably be 100 and 2... I'm guessing that by some other applications your integral and derivate units are minutes, not seconds. In your wort return temperature you'll get an overshoot of 1-3°C for a period of 5-10 minutes but should hit your mash temp quite well. For 80L-120L mash volume this should be ok. For 80L you can hopefully do a 10°C ramp in 30-35min and 120L in 40-45min.
 
Just for interest as well, here is a bit of sensitivity with HEX water volume over your HERMIT, assuming a 65 to 77°C ramp - I was curious how hot the water would get and how much capacitance the extra water would give (worsening overshoot). I kept the same P 1, D 3min values for all four. Interesting anyway. The RED is 5L of water over the coil, with BLUE being 3L, orange 7.5L and green 10L.
MrWibble-HEXvol-3-5-7.5-10.png

All of my modelling has been using the 240V KK pump with 1/2" SS tube. This ends up sitting around 8lpm (assuming 2.5m + 1m of extra plumbing) - theoretically - which I think is fine. You can possibly achieve more but I'm not sure about your mash geometry and drawoff, and if you'd get stuck mashes at higher flows.

I think the KK pumps are fine with the HERMIT coils or RIMS, but I think a slightly bigger pump is needed in systems where there's 10-15m of coil, just to overcome the pressure loss and keep flow up - to keep turning over the mash volume. On the KK by the time you have 50ft/16m of coil you're only at 4lpm which doesn't do you a lot of favours for bringing the mash temperature up.
 
Problems made worse by the ~3m of silicon tubing used for inter-connects (Mash->Pump->HX->Mash).

I've read that s.steel pipe (even with bends) gives much less pressure loss (over silicon).
But I'd need a more permanent setup for my system before these could even be thought-about.
Time to get to work on that brew-stand.
 
I'm trying to use Mr Wibble's controller and am having a lot of trouble with the PID control. 14.5l in mash tun, HERMS + Kaixin pump. Here are the two scenerios I've trialled -

P = 500, D = 0.45 - full heating when far from setpoint, but very very slow to get to target temp (over an hour and still didn't quite get there).

P = 100, D = 2 - cycling heating even when 35°C off target temp. Got there relatively quickly and overshot by 7°C still going higher. Stopped.

This seems to counter the advice in the manual in post #1. Any ideas?
 
TheWiggman said:
I'm trying to use Mr Wibble's controller and am having a lot of trouble with the PID control. 14.5l in mash tun, HERMS + Kaixin pump. Here are the two scenerios I've trialled -

P = 500, D = 0.45 - full heating when far from setpoint, but very very slow to get to target temp (over an hour and still didn't quite get there).

P = 100, D = 2 - cycling heating even when 35°C off target temp. Got there relatively quickly and overshot by 7°C still going higher. Stopped.

This seems to counter the advice in the manual in post #1. Any ideas?
My first point would be to try and get definite answers on the units used. I understand there is a library - is there any documentation accompanying this? I ask this because even professional controls engineers make the common mistake of simulating response, and don't know whether units in the control system are in minutes, seconds, repeats person minute, gain, etc.

Secondly, you should keep gain the same when you are changing D as they are directly related to a certain point. A setting if 500 for P is probably fine.

So talking about the behaviour, it's possible that you were closer with the first settings and needed a shorter derivative window, so a changed from 0.45 to 2 is not totally unreasonable (factor of 4), but with the gain change you are potentially changing the compensation by a factor of 20. You likely have a system with inherent overshoot, so it needs controller action to keep to setpoint - believe it or not P is part of this too.

It does really come back to documentation and understanding the units or at least expected behaviour of the D and (if anyone it interested for their work) particularly the units for I.

I can run some examples if you give me some more info on your setup, but hopefully that's a bit of useful information.
 
One more quick one...

If you found that the initial response didn't overshoot and took a while to get to setpoint, I would call this a little doughy. Shouldn't you then reduce the D term?

You should try P 500, D 0... And then perhaps D of 0.2 if you get find you got overshoot with D of 0.

The D term coukd be Gain, but it could be time or number of evaluations as well. Thinking about your response, it's quite possible that the D was gain and was overreacting to changes in PV or error, with lag exacerbating the issue. So D should be reduced and gain increased.

So should still get to the same answer of P 500, D of 0 or 0.2.
 
P 500 and D 2.0 resulted in slow to get there and slowly overshot by about a degree over 10 mins. Trying D 400 and D 1 to see how it goes.
 
TheWiggman said:
P 500 and D 2.0 resulted in slow to get there and slowly overshot by about a degree over 10 mins. Trying D 400 and D 1 to see how it goes.
Why are you changing the gain? The overshoot is not resulting from excessive gain like self-regulating systems, it's from lag in your system. Leave the P at 500 and change the D.
 
Because...
P = 500, D = 0.45 - quick ramp but never actually got to target after an hour within 5°C
P = 100, D = 2.00 - slow to ramp, huge overshoot
P = 500, D = 2.00 - quicker to ramp, some overshoot

P = 400, D = 1.00 - moderate ramp, slowly got to target with no overshoot

Main reason I changed P was to see the impact it might have. From what I can gather P and D are related, else wouldn't I max out P to 10000 or what-not? Yes I have referred to the manual, but follow my logic...
Assume P is a powerhouse in isolation then wouldn't it make more sense to just keep pushing P up until I hit overshoot? Then -
  • Increase P until I get some overshoot and get a decent ramp rate
  • Increase D to remove overshoot. Doughs up system
  • Increase P to improve ramp and reduce doughiness, D reduces overshoot.
  • Increase D to wind down overshoot
  • Repeat
Depending on how i want my system to behave there'll be an ideal P for an ideal D. Hence I'm trying to find that point - which I'd argue I'm nearly at. With D at 1 I'll try P at 600 tonight and see how this behaves, then adjust accordingly if required but this will be based on observation. A tiny bit of overshoot doesn't bother me (as long as it's controlled) but I do want it to ramp quickly to raise the temp of the mash as quickly as possible, which lags a fair way behind the HEx out.

Quick note - my simple mind is getting confused with the term 'gain' in the manual and posts as I've always thought each K value (KP, KI, KD) was the gain for the proportional, integral and derivative terms respectively. However in the manual you refer to P, I and D values in those words ("Set the P value...") and also refer to the gain. It's had me a bit lost anyway, might be worth clarifying.
 
You are 100% correct that P and D are related. It makes it harder to see they impact of what you're doing if you're changing both, so I suggested keeping P at 500. There are probably 10 others perfect pairs of P/D values.

I'm sorry about the terminology - I guess I was trying to talk in concepts and capture different types of controllers. P will always be proportional gain, but you enter in value in your controller - either or.

Integral could be a gain, time or resets/time - and the structure of the calculation influences this too. Integral can be tough to get your head around, and you are shooting blindly if you don't know the units. Luckily we don't need it... But it's a good question to ask ("Which units are we dealing with here?") if you work in industry with controllers.

D is also gain, but similarly it's evaluated over seconds or minutes - again very dependent on the configuration of the system, and the value you enter will depend on this. It can also be evaluated as the change in error, or the change in temperature which should be 'summed' differently - just to throw another spanner in the works.

Incidentally, do you have a copy of the code for the controller output calculation, if you're using Arduino?
 
Code looks good. Looks like change in PV/temperature is used instead of change in error. Interestingly though they normalise the ki and kd to 1 second, but still apply it on the same time (100ms). I'm not sure if a longer sample time would be better - it depends on the resolution or minimum change registered on the temperature probe. Might make it jumpier than it should be.

I think your path is ok, to go for P of 500/600 and the D = 1.

P = 500, D = 0.45 - (normalised ratio of 111:1) quick ramp but never actually got to target after an hour within 5°C
P = 400, D = 1.00 - (normalised ratio of 40:1) moderate ramp, slowly got to target with no overshoot
P = 500, D = 2.00 - (normalised ratio of 25:1) quicker to ramp, some overshoot
P = 100, D = 2.00 - (normalised ratio of 5:1) slow to ramp, huge overshoot
*these ratios include normalisation back to 1 second for the kd gain

Have you implemented the code exactly as published in those links? If the change in error is defined and used with 'kd' it should be "ITerm + kd * derror "; similarly it should definitely not be "ITerm + kd * dinput " or " ITerm - kd * derror ". If it's not this, I suspect your problem is that there with the overshoot examples there was not enough gain to keep it under control, and with a sample time of 0.1s your kd gets multiplied by 10.

There is possibly a lot of drive on the initial setpoint change that is ending up as heat in your HEX, then when your coil hits setpoint you still have this sitting there. If you have extra drive from the Derivative action in the intial ramp, this could be made worse.
 
You'll have to ask Mr Wibble that, it's his program I'm using.
Here's an interesting one... I played with the demo sketches and used P and D only as per the original trials Mr Wibble had in there. I didn't have all my flashy screens and such, so had the unit plugged into an SSR and left the controller do its thing. It NEVER got to the target. I hooked it up to my PC and forced a temp value / input (i.e one that would remain constant) to see what the PID would output.
It didn't change.
A big difference between the target and the feedback resulted in 100% output on the controller. If I moved the input up to say within 10% the output would drop to 90% but would never change. If however I added some I the output would creep up until it got to 100% no matter how close to the target it was. Proper PID control. So at the moment I have that set to 0.01 just so it behaves properly, but I'm still not sure why I have to.
 
I don't quite know what you mean about 'proper PID control'. I think I understand what you were doing, but correct me if I'm wrong...

It sounds like you have a constant temperature forced, and presumably a constant set point, so a constant error.

Looking at the code this will calculate out to a particular control output (100%, 90%) purely based on the error. Given the temperature is being forced, if is constant, the error is constant so the output is constant.
 
And in this case, the I would be the only thing to drive the output any differently. Each iteration of the code will add the error x ki, so will add to the output. This should get to 100%, but the temperature still won't change.

Again, correct me if I'm wrong in my understanding of what you're trying.

The PID control Wiki should cover why brewing systems do not benefit from Integral.
 
Adr_0 said:
I don't quite know what you mean about 'proper PID control'. I think I understand what you were doing, but correct me if I'm wrong...

It sounds like you have a constant temperature forced, and presumably a constant set point, so a constant error.

Looking at the code this will calculate out to a particular control output (100%, 90%) purely based on the error. Given the temperature is being forced, if is constant, the error is constant so the output is constant.
Constant temperature forced, yes. From what you're saying then this behaviour is correct. This is not appropriate behaviour however, and not being a process engineer I can only explain in terms of what I see. From what I can see there is a benefit to integral control which I'm happy to be constructively challenged.

In the manual refer to this pic -

System.png

This model assumes there is no heat loss in the system. In reality there is, and there will always be a slight difference between the input temp and the output temp. This difference will be significant to start with but it will creep slowly until it gets to say 0.1°C. To move this temp from 65.9°C to 66°C it will be necessary to add energy, and with a constant output approaching zero it means mathematically the system will stabilise to below the target temp. My observations without any integral control is that the system won't stabilise on the target temp, it will get close but never get there. I've still got my HERMS with 14.5l of water in it I didn't get a chance to brew with on the weekend so I'll run another temp test tonight.

FYI P = 600, I = 0.1, D = 2 resulted in 0.2°C overshoot but stabilised exactly on 40.0°C after about 10 mins of overshoot. The mash tun lagged by about 2°C when the HExout was within 1°C of target. I'm happy with that. I'll try tonight with no 'I' and report back.
 
TheWiggman said:
Constant temperature forced, yes. From what you're saying then this behaviour is correct. This is not appropriate behaviour however
Step through the code and calculate what you think the output would be if you had a constant temperature. Think also about what would happen to the 'input' value if there is nothing acting on it - i.e. if it's forced to a constant value, and not being a process engineer I can only explain in terms of what I see. From what I can see there is a benefit to integral control which I'm happy to be constructively challenged.

In the manual refer to this pic -

attachicon.gif
System.png

This model assumes there is no heat loss in the system. In reality there is, and there will always be a slight difference between the input temp and the output temp. This difference will be significant to start with but it will creep slowly until it gets to say 0.1°C. To move this temp from 65.9°C to 66°C it will be necessary to add energy, and with a constant output approaching zero it means mathematically the system will stabilise to below the target temp. My observations without any integral control is that the system won't stabilise on the target temp, it will get close but never get there. I've still got my HERMS with 14.5l of water in it I didn't get a chance to brew with on the weekend so I'll run another temp test tonight.

FYI P = 600, I = 0.1, D = 2 resulted in 0.2°C overshoot but stabilised exactly on 40.0°C after about 10 mins of overshoot. The mash tun lagged by about 2°C when the HExout was within 1°C of target. I'm happy with that. I'll try tonight with no 'I' and report back.
You raise a good point - there is definitely energy leaving the system, but it doesn't make the system self-regulatory, and doesn't result in a steady-state error. The main thing that would make it self-regulatory is a mass flow - going back to the heat balance equations in the Wiki. Considering the energy lost from the mash tun walls, pipe, etc., we're still left with a °C/min steady temperature drop, rather than a °C steady state error in a flowing system. In the Wiki it talks about insulation. Insulation is analagous to energy - it can completely remove that energy loss (W or J/s). If you only use a bit, putting it between your sensing temperature probe and your mash tun will help with getting these temps as close as possible.

Read the very next part in the Wiki past the diagram. Practically speaking, you could very well use a very long integral time (30, 60min) or - considering the arduino is in gain - a very small gain. The reality is that it doesn't correct any steady state error, and only contributes to overshoot. The very small amount that would be appropriate might as well be zero. I have tried to keep things simple, but I can appreciate it's sometimes fun to over-complicate things.

The loss to surroundings is a °C/min, and a proportional output on the element also gives °C/min which can be balanced perfectly. I think the problem you are seeing is either being caused by the Derivative action on the controller - have you actually tried it with P only? - or is the result of flow mixing of this temperature in the mash tun. Your answer depends on where you're measuring with your controller.

Which brings me to my next point... if you control on the coil outlet temperature, there is no reason why you can't get to a setpoint and hold this very well with P or PD. The mash tun will take a while to catch up - likely a very long time with a low flowrate - as it's relying on the mechanism of mixing. To get a good response in your mash tun, you can either use extra temperature or a high flow - so a bit of overshoot in your coil will probably help you if you get it right. If your system has inherent overshoot, why introduce more with I? That's what D is for, or P.

And finally, the response you described (0.2°C overshoot for ~10min, settling down to the SP) can be achieved with PD only - or possibly even P only. If you read through the Wiki you will realise that my overall tone is to keep it simple and you'd be surprised how well P will do. If you have inherent overshoot, D will help out. Adding any sort of I will introduce overshoot, which makes things unncessarily complex. Your system sounds like it has some inherent overshoot (caused by lag) so I would have suggested you're on the right track with the system you have trying for a P of 500/600 and a D around 1... but you're ultimately welcome to try whatever you wish.
 
When I've tried to describe PID (or any discrete component of it) to others I've likened it to standing in a room with a heater on the other side. The heater heats up the space between you and it. If you turn if off once you're comfortable, the heat will continue to travel and disperse through the room resulting in more heat than you want. By the time you're comfortable again and you turn it back on, it takes a while to heat back up and you get too cold.

Back to mashing, I think where my logic is differing here is that I am assuming that when the element stops heating that there will be no increase in temperature of the output from then on. If this were true then my comments in post 28 holds - I have looked through the code, and you will never reach target temp with P only (because when the error is zero the output will be zero). If residual energy remains in the HEx vessel such that the temperature is higher than the target that will still transfer heat to the mash, there is potential overshoot if P is too high.

Time for a play again tonight.
 
Back
Top