CapnBry / HeaterMeter

HeaterMeter and LinkMeter Arduino BBQ Controller
https://tvwbb.com/forums/heatermeter-diy-bbq-controller.85/
MIT License
502 stars 83 forks source link

[hm] Int & Deriv Patch redone #12

Closed R-Burk closed 9 years ago

R-Burk commented 9 years ago

Decided that Integrators job was to help get to the setpoint. As such limited the error it can see. Feed rate is currently a #define but have pondered using the lid reset percentage as being the limit of a "control zone" and going for half that value

Derivative I found that just a simple filter on the output provided extreme smoothing which is apparently how some commercial controllers deal with it.

Deriv filter also enables the ability to for the controller to automatically choose when to come out of lid open time. (not in this patch)

With this change can eliminate the halfing of Integrator at setpoint(not in this patch)

CapnBry commented 9 years ago

I can sort of agree with not resetting the PID[I] value on change although I don't know how often that's an issue. I am in favor of removing code that doesn't do anything but I'm wondering if there isn't a reason to leave it just so you can reset it. It can probably be safely removed.

The _derivFilt I am against because if there's a big change in temperature that's exactly what the D is supposed to do, jump up. The whole idea is to react to a change in temperature! If the temperature is bobbing up and down by 1x 10-bit LSB of an amount then amplified by the D constant I don't think that's an issue either. 1 LSB is less than half a degree across the whole range so even with a giant 20 D constant that's only 10% and with a constant that large you're asking for a small temperature change to create a large output swing. If this were implemented it would also be preferable to have a "fast average" (added) and "slow average" (current) of the temperature then use the difference between them as your D basis. Mathematically isn't that the same thing and more direct? I'd still be concerned about adding that much lag to the controller to smooth it out. Still I may try it.

Chopping the I error at 20 degrees max seems pretty arbitrary to me. The value you choose here is dependent on your P and D terms. If your P is set so high that you're inside "controllable range" so far out that the I sum jumps up, that's working as intended. I don't think it is right to arbitrarily say "20 degrees is the most error any constants could ever reasonably tolerate". I will also test this though and maybe it just works better in which case I will shut my mouth.

CapnBry commented 9 years ago

I tested the derivFilt and also just calculating the D term based on a fast moving average. Both these changes effectively filter the D output so that it doesn't bounce all over the place as the temperature changes. However, it also defeats a lot of the purpose of the D term. The D's job is to gauge the trend over time. Our interval is basically 60 seconds so we are looking at where the temperature was 60 seconds ago vs now. If you start looking at the temperature 15 seconds ago versus 60 seconds ago, you're throwing out what is happening now. Imagine a sine wave, where the 60 second ago is at the peak, the 15 second is on a large slope but the now is on the other side of the opposite peak. The slope is reversing and you should be dialing back the output, but looking back 15 seconds you're not going to see that. This is definitely doing the wrong thing.

Given that this double filtering of the D term is the wrong way to run the control algorithm, I question the purpose of doing it. If the idea is to reduce the quick spikes caused by changing temperatures, isn't this also potentially created by the I term? If you want less jumpy output changes, then the solution is to filter the PID output value not just the D value.

The other thing I looked at was your I error limit and the claim it can reduce integral windup during startup. Setpoint 225F. -- Controller came out of saturation (because of D term) at 190F meaning your code would be in effect from 190F to 205F. -- During this time the I sum was increased at a rate of 0.7%/sec max (at 190F) down to 0.5%/sec minimum (at 205F). -- Over the time the code would be in effect the I sum grew to roughly 30% at an average of 0.6%/sec over 50 seconds. -- Your code would have reduced the I sum to 25% during this period. This represents a 16% decrease in I sum compared to a 50% decrease by the straight cut method.

Therefore I conclude that while I appreciate the concept of the code, it is in't effective enough, and the selection of the I sum control range is arbitrary and doesn't account for temperature units which makes it unsuitable for general use.