PID theory can be very obscure. PID implementation is rather simple.
(And I hope I don't have _too_ many typos below; it is not code-checked,
but the basics are there.)
Note that in the pseudo-code below, Error terms are in units of the
controlled variable (e.g. degF or furlongsPerFortnight or PSIG); the
Correction and Output values are in per cent. Heaters usually only add
heat, so the output would range from 0% to 100%; something like a motor
might have a reversible controller and could use -100% to +100% as its
control, so the MIN_OUTPUT would be changed to be suitable.
The entire PID algorithm is fairly simple; most of the control should
usually be Proportional - bigger error -> bigger correction. The
Integral correction is to help correct for long-term errors, while the
Differential correction helps damp oscillations of the Proportional
correction and tends to reduce overshoot for quick changes.
To "tune" the PID, start with Ki and Kd set to 0.0, and set Kp to a
value that is equal to your maximum output error / 100. For example, if
you want the controlled variable to be no worse than 10F, Kp would be
0.1 to start. (This is probably way too large because it means the the
heaters will be on 100% if the temperature is more than 10F off, but
it's a place to start.) By increasing or decreasing Kp (I usually adjust
by a factor of 1.4 each time, so every two changes give a factor of 2),
you'll find a value that gives stable output, though the controlled
variable will probably not be very close to you desired set point. If Kp
is too large, the output (and your controlled variable) will oscillate
at the "natural frequency" of the system you are controlling.
Now comes a little magic - add some Ki (start with about 10% of Kp) and
watch the control. It will (eventually) get the controlled variable very
close to your set point, but it might be slow. If Ki is too large, you
will get slow oscillations - time to dial it back until those stop. If
it seems sluggish, increase Ki until you see the oscillations, then back
off again until it seems stable.
Do a similar tweaking with Kd, though if the Kd is too large, the output
will be "twitchy" - kind of like fast oscillations. This is harder to
describe, but I hope that gives you the concept.
============== pseudo code below ================
const double MAX_OUTPUT = 100.0; // output is in per cent
const double MIN_OUTPUT = 0.0; // reversible motors could use -100.0
const double tPeriod = 0.100; // we'll use 100ms for example
static double IntegratedError;
// Tuning settings:
double Kp; // = Proportional "gain" (a settable constant)
double Ki; // = Integral "gain" (another settable constant)
double Kd; // = Differential "gain" (one more settable constant)
// Initialise everything except the gains to 0.0 at the beginning
// of time, then get the SetPoint, and the ActualValue,
// call the PID_loop() function and send the return value to the output
double PID_loop (double SetPoint, double ActualValue)
{
// During the operation, the following calculations are performed at
// regular intervals (1sec or 100ms or faster, depending on how fast
// the system you are controlling)
double PreviousError = CurrentError;
double CurrentError = SetPoint - ActualValue;
IntegratedError = IntegratedError + CurrentError;
ProportionalCorrection = Kp * CurrentError;
IntegralCorrection = Ki * IntegralError;
// make sure the Integrator doesn't continue to + or -infinity!
// (IntegratedError is the only variable with long-term memory
// so it's the only one with this particular patchup)
if (IntegralCorrection > MAX_OUTPUT)
{
IntegralCorrection = MAX_OUTPUT;
IntegratedError = MAX_OUTPUT/Ki;
}
else if (IntegralCorrection < MIN_OUTPUT)
{
IntegralCorrection = MIN_OUTPUT;
IntegratedError = MIN_OUTPUT/Ki;
}
DifferentialError = CurrentError - PreviousError;
DifferentialCorrection = Kd * DifferentialError;
NetCorrection = ProportionalCorrection
+ IntegralCorrection
+ DifferentialCorrection;
// make sure we don't return invalid corrections
if (NetCorrection > MAX_OUTPUT) NetCorrection = MAX_OUTPUT;
if (NetCorrection < MIN_OUTPUT) NetCorrection = MIN_OUTPUT;
return NetCorrection; // this is the PID output
}
============== end of pseudo code ================
*Plain Text* email -- it's an accessibility issue
() no proprietary attachments; no html mail
/\ <https://www.georgedillon.com/web/html_email_is_evil.shtml>
On 2020-08-08 2:36 p.m., John Innis wrote:
> Sure be glad to have more info. I have done a lot of arduino projects,
> but have been finding the PID theory a bit of a tough nut to crack.
>
> On Sat, Aug 8, 2020 at 1:19 PM Jack Brooks <JIBrooks@live.com
> <mailto:JIBrooks@live.com>> wrote:
>
> John,____
>
> __Â __
>
> Agreed. I built a PID Controller setup for my smoker using a Inkjet
> 106-RL. Itâ??s a great way to go. Now I just need to find a kiln. I
> can provide some good info if you are still working on it. ____
>
> __Â __
>
> Yes, aware of issues opening a 900°F oven. ____
>
[snip]
_______________________________________________
Shop-talk@autox.team.net
Donate: http://www.team.net/donate.html
Suggested annual donation $12.96
Archive: http://www.team.net/pipermail/shop-talk http://autox.team.net/archive
Unsubscribe/Manage:
http://autox.team.net/mailman/options/shop-talk/mharc@autox.team.net
|