br3ttb / Arduino-PID-Library

1.93k stars 1.11k forks source link

How to limit output depending on another variable #98

Closed mikegleasonjr closed 4 years ago

mikegleasonjr commented 4 years ago

Hi, great library. I am using it to cool a box using 2 temperature probes (input / ouput) and a fan.

The fan is driven by the PID and the setpoint is input temp + 2 degrees celcius at the output.

I also record separately the rpm of the fan. I would like to tell the pid to stop increasing the speed of the fan past 1200 rpm (knowing the temp might continue to rise). It would keep the wife happy.

Thanks again for the great lib.

br3ttb commented 4 years ago

Use the SetOutputLimits function

On Sat, Feb 15, 2020, 8:49 PM Mike Gleason jr Couturier < notifications@github.com> wrote:

Hi, great library. I am using it to cool a box using 2 temperature probes (input / ouput) and a fan.

The fan is driven by the PID and the setpoint is input temp + 2 degrees celcius at the output.

I also record separately the rpm of the fan. I would like to tell the pid to stop increasing the speed of the fan past 1200 rpm (knowing the temp might continue to rise). It would keep the wife happy.

Thanks again for the great lib.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/br3ttb/Arduino-PID-Library/issues/98?email_source=notifications&email_token=AACYX4QOPA57UVZIAS67KA3RDCLRJA5CNFSM4KV6JGCKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4INZ7KHQ, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACYX4RUT5HOZPHNIQL7FMTRDCLRJANCNFSM4KV6JGCA .

mikegleasonjr commented 4 years ago

But I don't know for this particular fan or the next one if 137 in adc translates to 1200 rpm. Plus, for the same fan if you obstruct it, it's rpm will go down.

I wrote a separate PID controller to set the fan to a fixed rpm with your library. Works well. With different fans, the output is never the same.

I'm trying to come up with a generic solution.

Thanks

mikegleasonjr commented 4 years ago

The solution was actually quite simple. I used 2 PID controllers.

The first one is the temperature controlled one (ex.: pid1). Which drives the adc with its output. I set a target temperature as the setpoint and the current temperature as its input. Like in all your examples. Works well on its own.

Now to prevent a RPM going over a limit, I added a second one (pid2). The rpm as its input, the setpoint is set at the max rpm and the output don't drive the fan adc but the upper output limit of adc1. In other words, it is calling pid1.SetOutputLimits(0, pid2Output).

So when the rpm is below the max, the output limits of pid1 are usually [0, 255] because the pid2 tries to ramp up the rpm. But when the rpm goes over 1200, the output limit will be lowered.

There's a little bit of overshoot in my tests but since the temp will change more slowly In the real world, I won't really notice it.

Thanks