PID and app note AVR221--scaling output (update)

Go To Last Post
51 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm working on the air flow system for my smoker, well described https://www.avrfreaks.net/forum/d...

for background.

 

I've put together my 5VDC micro-fan, PT100 temperature sensor with conditioning to 0-5VDC input, and an appropriate re-purposed AVR board.  The pieces appear to work well.

 

In "closing the loop", I thought I might as well do it right and use PID.  As right now it is still on the bench, I have no solid idea of what the "time constant" of the "plant" is, and similar rigorous control engineering items.  (For background, if I open up another of the four intake holes the [mostly] charcoal fire gets hotter such that the simple grill thermometer starts rising in a minute or two.  So surprisingly fast.)

 

I adapted the code from Atmel's app note

AVR221: Discrete PID controller
 

and it is reacting as expected on the bench.  [As written it takes 40% of Mega48 code space.  About half of that for the PID routines and the other half being 32-bit arithmetic operations which were not otherwise in the app.  I may make a 16-bit "lite" version for later re-use.  After going through the below, small numbers are fine for this and many other AVR8 apps.  After all, one typically only starts with a 10-bit or less ADC value, and ends up with a control parameter of 7- (e.g., whole percent) to maybe 10- or 12-bits for PWM or DAC.]

 

When the PID routine is called with the setpoint/desired and measurement/"process" values, the result is a 16-bit signed integer.  Makes sense--trivial example with a P gain of 1 and measured value 10 below setpoint, the result is 10.  Measured value 10 above setpoint, result is -10.  And so on adding I and D terms.

 

1)  Setpoint and measurement need to be in the same units.  Makes sense for a general-purpose routine, but often isn't that way in a real app.  Not really a problem for me in this app and no real question here, but I posted it as a discussion point for comment.

 

2)  "Style" of the routine.  The max values [internal and result] are more or less hard coded to avoid overflow and runaway.  Again for comment:  Shouldn't these be exposed with an API to allow limits less than INT_MAX and similar?

 

3) Shouldn't there be a deadband provision somewhere?  Or is this done outside of the GP PID engine?  [Perhaps I should be starting with a different PID "library" with all this stuff?]

 

4) Now the "real" question.  Led into by the mention of "units" in 1). 

 

What is the best way to scale the return value to my needs?

 

Let's work through a simple example, based on the above "Measured value 10 above setpoint, result is -10."  Great; makes sense.  In my smoker, that means that the measured temperature is 235 degrees F and the setpoint/desired temperature is 225 degrees F.

 

But the input to my "plant" sets the speed (or duty) of the fan.  Let's say I want a value 0% to 100% to PWM the fan.  I can't go lower than 0%/off.

 

How do I take the output of the PID routine, -10, and apply that to the fan percentage?  For sake of discussion, the fan could currently be running at 25% or 52%, right?  It just needs to be cut back a bit...

 

 

 

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Mon. Dec 29, 2014 - 02:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm curious how the fan effects temperature.  My guess is no flow means suffocation of the fire?  High flow acts like a bellows?

 

One thing I'm fairly sure about is that, if you intend to use integral gain, you need to slew the desired temperature according to the slope(s) of the heating capabilities of the plant.  Otherwise you will overshoot dramatically (where drama is proportional to I gain).

 

Most likely I would start by measuring the maximum rates (up and down) of temperature change based on full-off and full-on.  That would determine your slew rate(s).  Then it's just garden variety tuning of P gain (and I and/or D if required), right?  (Assuming fancy control techniques aren't required - e.g. gain scheduling.)

C: i = "told you so";

Last Edited: Thu. Dec 11, 2014 - 11:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

An interesting problem... measure temperature but control fan speed in the hope of modifying temperature.

 

Relationship between fan spped and air volume tends to be non linear. Problem.

 

Given the smoker structure how does the temperature change as a function of fanspeed ( PWM duty cycle)? Do you need to linearise it via a LUT?

 

It might behoove you You to modify the PID algorithm to include some feed forward compensation. This would consists of a simple line of code where by ( refering to the app note ) You would arithmetically add a scaled vale of set point directly to the output of the PID controller.

 

Ufeedforward= Upid + Kfeedforward*Yo

Kffedforward is guestimated by setting all PID coefficients to zero and then Kfeedforward is set by looking for best open loop performance ( minimum error as Yo is varied ).

 

Effect of this modification is to reduce burden on the PID algorithm.

 

I guess it would be obvious to state that the Ufeedforward value is scaled to map into the range of PWM duty cycle from 0 to 100% ( if duty cycle is an int then the U value needs to be scaled into an int so that it produces a 0 to 100% duty cycle ).

 

As for loop update time operate the smoker open loop. step the fan speed and observe the deadtime/delay it takes the tempsensor to respond and use that as the first approximation to loop update rate.

 

If this blows up and burns the smoked eels...i am outa here

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
How do I take the output of the PID routine, -10, and apply that to the fan percentage?

Obviously not so literally, but:

new_fan_speed = old_fan_speed * (1 + (pid() / 100.0));

This treats the return value of pid() as a percentage by which to tweak the current fan speed.  Takes no account of the actual range of values which pid() may return, nor the fan's top speed.  Modify with scaling and limits as required.

 

This sounds very much like a classic 'cruise control' problem.

Too slow -> open throttle a little

Too fast -> close throttle a little

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Thu. Dec 11, 2014 - 11:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The sensors need to be faster than the plant. I assume that the temperature sensor responds in seconds, and the cooker heats up in hundreds of seconds, so no prob there. In the cruise control example, the integral error would inch up when going down a hill, so it should slow down more. I could never figure out what the speed of the error was for. The only control you have is fan speed? No propane valve open/closed? So whats the analogy in the cooker to gravity? Wind blowing on it and making it cool faster?

 

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lee nice thread with lots of interesting things to ponder I am interested in this sort of thing so sorry if my post bores you!

 

Controlling thermal systems can be  as complicated as you want it to be, there is such a diverse range of conditions and variables that come into play with many things extremely difficult to measure or quantify, the mechanical world is very complicated

 

In my experience its possible to get very good control with textbook responses just by playing around with a given setup and don't even try to model it! , at the end of the day we are in effect treating the system as a second order system and it gives good results most of the time but remember its always much more complicated than that so you might have to adjust a real system to allow for things thats beyond the scope of the classical theoretical treatment

 

I have been involved using PID loops in some complicated systems. Systems that under certain conditions create their own heat through chemical reactions

 

Iits systems operating over a wide range of temperatures I have probably had the most trouble with, where time responses of the sensors themselves start to introduce delays and distortions you can tune a loop at room temp (20-30C) but it will be far too aggressive at -40C , I have even battled thermal runaway in transistors which was a real bitch, what happens is there is a sharp knee in the response to an increase input so it just goes off the scale up and then backs off way too much down again and control is lost

 

These ordinary systems can become extraordinary under certain conditions and searching for the system equations and time constants is just not possible it would take a lifetime so what I have been taught to do is to do some real world work for real world results and test your system under the conditions you want to operate, lots of step responses where you start at a given temperature and measure the response in getting to the setpoint

 

Thermal systems are very slow and this has to be reflected in your sampling interval, I have never had a thermal system where I sampled at more than once every ten seconds, over sampling just causes chaos and you have to allow a nice amount of time for a system to respond to a change before you decide to change more slowly does it

 

Through me being me based on nothing but messing about I have noticed that with thermal systems its very useful to find out how long it takes for your output to start to change, you can count it in your head! you change the input enough to create a change and get the delay in changing it to seeing it respond if you understand me this pure delay is important as its value is based on your systems dynamics with some of the complicated stuff added in and I have had the best results basing my sampling interval on a multiple of this value, try sampling at different multiples of this time period and get a feel for the response

 

Of course all the values change given different operating conditions most notably ambient/local temps so by  testing your system you can decide a lot, if you want a set PID control loop then maybe some of your operating conditions could make the loop unstable and you can guard against this by using if statements to limit power, or even ramp up with a changing setpoint given whatever conditions you are presented with hell for the more advanced engineering systems a PID controller might not be good enough and you get all academic!

 

Note also when you work out your error it has a certain magnitude and you times this by the P (I or D) to give a change amount but  this value has a magnitude that is proportional to the output maximum

 

i.e the maximum pulse width might be 255 so if working in celsius a 10 degree error is (10/255)% if we changed to a 16 bit PWM then our output would be far less of a change and what we are talking about here is gain, there is a gain when looking at the change in output from input and it is all quite complicated as everything all comes into play together having the same effect

 

If you think about it you could change that 8 bit PWM to 16 bit and if you increased the sampling time then in theory (under some circumstances) you could have the same response as before as you increase by less but more times in the same period!

 

By increasing the magnitude of say P then its like more gain and the same applies to the value you are measuring, i.e change to milidegrees and reduce the PID values scale by 1000 for the same effect so because of all this common action the whole lot is included in the two numbers the error and the PID constants what you end up doing in practice by tuning the loop (in autopilot mode) is set up the parameters so that the changes are realistic values  like 5% steps for small errors 

 

Its actually not required to use the D term for thermal systems but I am a sucker for adding it too, it just feels more complete it does have a noticable effect on the response and I like to see how it predicts the future when things change fast but the final response is the same without it

 

In practice I find it easier to forget all that Kc, 1/Ki and all that crap

 

And use the error to work out a change

 

change = P*error_new + I*Ts(error_new +error_old)/2; + D(error_new-error_old)/Ts;

 

Pulse width = pulsewidth +change;

 

Ts is sampling interval

 

P I and D don't have to be between 0 and 1 dont be scared to experiment

 

How do I take the output of the PID routine, -10, and apply that to the fan percentage

Invert the eror so its a +10, its a positive increase we need

So use

 

Error= Setpoint-measurement

So very roughly!

Error_new = 10 , error_old=error_new, TS =10

 

P=1, I=0.5, D=0.5

 

Change = 1*10 +10*0.5*(10+10)/2 +0.5(10-10)/10

 

Change = 10 +50 +0

 

Pulsewidth= pulsewidth+60

 

 

So your pulsewidth has a width of 60

 

the next interval  say the error is 5

 

error_new= 5, error_old=10

 

change = P*error_new + I*Ts(error_new +error_old)/2; + D(error_new-error_old)/Ts;

 

Pulse width = pulsewidth +change;

 

Change = 1*5 +10*0.5*(5+10)/2 +0.5(5-10)/10

 

Change = 5 +37.5 -0.25

 

Change = 42

 

pulse width is now 102

 

As the error changes sign so does the change and like I said earlier you can get text book responses

 

Obviously you alter the values so that the values work in this example a 5 degree change in error should induce some differential action so you tune the parameters to make it happen

 

 

Last Edited: Fri. Dec 12, 2014 - 01:29 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks to all for the comments.  First, as I said in the linked overview thread:

[This is so important that I should put the "HELP!!!" and URGENT!!! in the title, as this is for air-flow control for my outdoor cooker (UDS -- Ugly Drum Smoker). I built a 16-gallon.]

LOL.  Being a 'Freak I can't just let the simple and working-well manual design alone.  Nooo--I have to apply an AVR to it.  wink

 

Background:  Current operation:  A metal "oil drum", upright.  Covered during operation with open bunghole on the top lid serving as the "chimney".  Four ~3/4"/~20mm holes spaced around the circumference near the bottom that serve as air intake.  1" round magnet for each hole as the "damper".  For typical "low-and-slow" pork BBQ cooks, the target temperature is about 230 degrees F; about 110 C.

 

The heat source (more described in the link) is charcoal in a basket with a few wood chunks on top, arranged to burn in a "linear" fashion starting with a few lit coals which ignite the neighbors as time goes on.  One load of about 5 pounds of charcoal, 2 or 3kg, gives about an 8-hour burn at 200-250F.  Given the nature of the loading of the fire basket and re-using partial coals from previous runs and variability in wood chunks, it isn't like running a propane burner or electric heater.  In addition, a single-wall uninsulated drum will change based on temperature change, wind change, shade change, ...  All that said I've done enough cooks that once I get it started and temperature is rising to/over 200F, I leave 1.5 holes open and I could just come back hours later and it works fine.  But, being a good pitmaster (or pretending to be one), I'm always checking it and fussing a bit.  [Side note:  For a "standard" cook of e.g. pork roast the lid never comes off until the cook is done, like 6 hours later.  The bung hole at the top is conveniently large enough that one can peek at the meat, and poke meat thermometer right through the "chimney".]

 

So all the above works great, but now I have to fuss with it using an AVR of course.

 

===============================================

Background:  "Improved" method:  The new "plant" hasn't been run yet, but I speculate that given 1.5 intake holes naturally aspirated do the job now, a single intake hole ~1" diameter fitted with the 5VDC 25mm fan will provide more than enough air and at low duty cycle.  If not, no big deal--open another of the existing holes by moving the magnet half or full open.  Whatever will give proper temperature without being very near either end of duty cycle.  PT100 RTD is conditioned to give 0-5VDC to the AVR ADC for 0C-250C, or about 32F to 500F.  Highest typical cook is 300-350F for poultry so more than enough range.  4 ADC counts per degree C, so plenty of resolution--this isn't rocket science after all.

 

==============================================

Background:  PID.  I've done PID, on AVR8 and other.  I've got books and articles and such, but I'm definitely not a control engineer.  My implementations are generally "in the style of" PID, with lots of adjustments for practicalities.  E.g., in an '8535 app with limited speed and program space and SRAM, everything was scaled so that the gains were four bits.  (and obviously a P gain of 8 and I gain of 8 are on different "scales")

 

Like joey suggested, I won't really have a problem making a practical adjustment to get a usable value.  But I wanted to get more input.  And indeed I might well poke at the AVR221 code to make it 16-bit.  After all, the starting point is a 10 bit value so keeping in 15/16 bits still gives a pretty good range.  And the I term needs to be limited anyway, and so forth.  It seems to me that PID is [nearly?] never just calling the canned routine, but a lot of practical limits and adjustments for the particular situation.

 

==============================================

And then, after I've fussed with my perfectly good manual smoker and added the closed loop temperature control, will I be satisfied?  LOL--next projected phase is to add a wireless transmitter, and a base station in the house.  Control/monitor remotely; gather stats; graph on TFT colour display; ... ;)

 

==============================================

Now, on to responses to comments:

 

cpluscon wrote:

I'm curious how the fan effects temperature.  My guess is no flow means suffocation of the fire?  High flow acts like a bellows?

I'm curious as well. ;) Discussed a bit above; first experimental results will be interesting.  To snuff the fire, the intake will need to be capped -- the fan itself allows some natural aspiration through the vanes.  I don't think it will be like a bellows fanning the flame, just allowing more intake air. [Covering all the intake holes and replacing the top bung snuffs quickly.]

 

cpluscon wrote:
One thing I'm fairly sure about is that, if you intend to use integral gain, you need to slew the desired temperature according to the slope(s) of the heating capabilities of the plant.  Otherwise you will overshoot dramatically (where drama is proportional to I gain).

 

Most likely I would start by measuring the maximum rates (up and down) of temperature change based on full-off and full-on.  That would determine your slew rate(s).  Then it's just garden variety tuning of P gain (and I and/or D if required), right?  (Assuming fancy control techniques aren't required - e.g. gain scheduling.)

Indeed, nothing fancy needed.  I'm guessing I won't really "model the plant", but rather just start with a configuration and start tweaking the gains and limit integrator windup and such.

 

ignoramus wrote:

An interesting problem... measure temperature but control fan speed in the hope of modifying temperature.

 

Relationship between fan spped and air volume tends to be non linear. Problem.

 

Given the smoker structure how does the temperature change as a function of fanspeed ( PWM duty cycle)? Do you need to linearise it via a LUT?

I don't think that will be necessary.  Linear or not, when the temperature is below the target the fan speed is increased.

 

ignoramus wrote:

It might behoove you You to modify the PID algorithm to include some feed forward compensation. ...

 

Indeed, "feed forward" is probably the proper approach to heuristic "I need to add/offset/scale to make things come out right".

 

joeymorin wrote:

...

This treats the return value of pid() as a percentage by which to tweak the current fan speed.  ..  Modify with scaling and limits as required. ...
 

Exactly the way I'm viewing it.  When I go out and check on it manually, if way below temp or dropping fast open up more than a little -- proportional.  When temp rising nicely, start cutting back on the error a little -- derivative.  So, the simple fan duty cycle should be fine I'd think.

 

bobgardner wrote:

 So whats the analogy in the cooker to gravity? Wind blowing on it and making it cool faster?

Yes.  As described above, changes in wind/temperature/sun as well as the uncertain nature of the fire, with a few hot "discrete" briquets and wood chunks eating their way around the fuel supply.

 

Bignoob wrote:

...

In my experience its possible to get very good control with textbook responses just by playing around with a given setup and don't even try to model it! ...

Thanks much for the detailed response to study.  Indeed, as I described earlier I plan to just "make it work".

 

 

Bignoob wrote:

Thermal systems are very slow and this has to be reflected in your sampling interval, I have never had a thermal system where I sampled at more than once every ten seconds, over sampling just causes chaos and you have to allow a nice amount of time for a system to respond to a change before you decide to change again...

Also agreed.  My bench setup used Ts of one second to check things out.  But in practice that may well be too fast.  (Or I need to make the gains miniscule?)

 

Bignoob wrote:

... with thermal systems its very useful to find out how long it takes for your output to start to change, you can count it in your head! you change the input enough to create a change and get the delay in changing it to seeing it respond if you understand me this pure delay is important as its value is based on your systems dynamics with some of the complicated stuff added in and I have had the best results basing my sampling interval on a multiple of this value, try sampling at different multiples of this time period and get a feel for the response ...

Now you've gotten me a bit confused.  If I make a change in the input and the output starts to change 30 seconds later, are you saying my minimum Ts should be 30 seconds?  I thought it should be e.g. like 3 seconds in that case.

 

Bignoob wrote:

... if you want a set PID control loop then maybe some of your operating conditions could make the loop unstable and you can guard against this by using if statements to limit power, or even ramp up with a changing setpoint given whatever conditions you are presented with hell for the more advanced engineering systems a PID controller might not be good enough and you get all academic!

Yes, pragmatics and heuristics and defensive programming is my planned approach.  Yet I think that treating it like PID will help to formalize things a bit.  In a past thermal system (pellet stove) the "D" was imperative--as soon as temperature started to rise one had to start backing down on the fuel feed immediately or there was way overshoot.  Yet, "P" was important too--without it when the thermostat was changed from "night" to "day" one needed to be more aggressive.  BTW, that pellet stove is a perfect example of conditions you talked about right above.  Can't feed fuel too slow or the fire will go out.  Can't feed fuel too fast when trying to heat up, or the fire will be smothered under a pile of raw pellets.  Have to adapt somewhat, and the user may be using wood pellets or grain or other products in any combination.

 

Bignoob wrote:

...if we changed to a 16 bit PWM ...

 

If you think about it you could change that 8 bit PWM to 16 bit and if you increased the sampling time then in theory (under some circumstances) you could have the same response as before as you increase by less but more times in the same period!

 

I might indeed PWM the fan.  But I plan to do the initial implementation by using a period of about 30 seconds, and run the fan for "duty" seconds during the period.  As this is a cheap little fan, it is unknown how it might react at low voltage e.g. 1V for the 5V fan.  Might even stall and/or overheat.  And when actually in operation with fire burning, I want to size things so it is running at least 10% of the time in steady-state to avoid edge conditions.

 

===================================

Thanks again, all.  Pictures for reference to follow below...

 

Lee

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0