From 775eb0a0f2244de7da6c1593edb9f0f97fd79dd4 Mon Sep 17 00:00:00 2001 From: Jason Bruce Date: Thu, 29 Apr 2021 15:08:53 -0400 Subject: [PATCH 1/3] fixing divide by zero bug when thermocouple read fails five times in a row --- lib/oven.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/oven.py b/lib/oven.py index 4a1f5b0..5d0f0ef 100644 --- a/lib/oven.py +++ b/lib/oven.py @@ -128,7 +128,8 @@ class TempSensorReal(TempSensor): except Exception: log.exception("problem reading temp") time.sleep(sleeptime) - self.temperature = sum(temps)/len(temps) + if len(temps) > 0: + self.temperature = sum(temps)/len(temps) class Oven(threading.Thread): '''parent oven class. this has all the common code From ba05052c1c1e6f866ba9faa94c6ce613e38948d3 Mon Sep 17 00:00:00 2001 From: Jason Bruce Date: Thu, 29 Apr 2021 15:23:41 -0400 Subject: [PATCH 2/3] fixed bug about integral. it should now be reduced to get more integral action --- docs/pid_tuning.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pid_tuning.md b/docs/pid_tuning.md index 1a0f613..c90ad9f 100644 --- a/docs/pid_tuning.md +++ b/docs/pid_tuning.md @@ -50,5 +50,5 @@ Now, run the test schedule again and see how well it works. Expect some oversho * only change one value at a time, then test it. * If there is too much overshoot, decrease pid_kp. -* If the temp is always below the set point, increase pid_ki. +* If the temp is always below the set point, decrease pid_ki (which increases the integral action). * if the above does not work, try the Ziegler / Nichols method https://blog.opticontrols.com/archives/477 From d60cc535d0b18d66b0ae8f4784e5bde4e74d82c9 Mon Sep 17 00:00:00 2001 From: Jason Bruce Date: Fri, 30 Apr 2021 20:27:19 -0400 Subject: [PATCH 3/3] adding support to prevent integral windup --- config.py | 13 +++++++++++++ lib/oven.py | 22 ++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/config.py b/config.py index 293aed7..10d3a24 100644 --- a/config.py +++ b/config.py @@ -62,6 +62,19 @@ pid_ki = 200 # Integral pid_kd = 200 # Derivative +######################################################################## +# +# Initial heating and Integral Windup +# +# During initial heating, if the temperature is constantly under the +# setpoint,large amounts of Integral can accumulate. This accumulation +# causes the kiln to run above the setpoint for potentially a long +# period of time. These settings allow integral accumulation only when +# the temperature is within stop_integral_windup_margin percent below +# or above the setpoint. This applies only to the integral. +stop_integral_windup = True +stop_integral_windup_margin = 10 + ######################################################################## # # Simulation parameters diff --git a/lib/oven.py b/lib/oven.py index 5d0f0ef..da6f2d4 100644 --- a/lib/oven.py +++ b/lib/oven.py @@ -410,7 +410,12 @@ class PID(): error = float(setpoint - ispoint) if self.ki > 0: - self.iterm += (error * timeDelta * (1/self.ki)) + if config.stop_integral_windup == True: + margin = setpoint * config.stop_integral_windup_margin/100 + if (abs(error) <= abs(margin)): + self.iterm += (error * timeDelta * (1/self.ki)) + else: + self.iterm += (error * timeDelta * (1/self.ki)) dErr = (error - self.lastErr) / timeDelta output = self.kp * error + self.iterm + self.kd * dErr @@ -423,15 +428,16 @@ class PID(): if output < 0: output = 0 - #if output > 1: - # output = 1 - output = float(output / window_size) if out4logs > 0: - log.info("pid percents pid=%0.2f p=%0.2f i=%0.2f d=%0.2f" % (out4logs, - ((self.kp * error)/out4logs)*100, - (self.iterm/out4logs)*100, - ((self.kd * dErr)/out4logs)*100)) +# log.info("pid percents pid=%0.2f p=%0.2f i=%0.2f d=%0.2f" % (out4logs, +# ((self.kp * error)/out4logs)*100, +# (self.iterm/out4logs)*100, +# ((self.kd * dErr)/out4logs)*100)) + log.info("pid actuals pid=%0.2f p=%0.2f i=%0.2f d=%0.2f" % (out4logs, + self.kp * error, + self.iterm, + self.kd * dErr)) return output