thermferm/pid.c

changeset 362
c92651a54969
parent 316
73cd31dc6ce1
child 363
468ec0d96cce
--- a/thermferm/pid.c	Thu May 14 22:03:35 2015 +0200
+++ b/thermferm/pid.c	Sat May 16 17:39:30 2015 +0200
@@ -24,27 +24,63 @@
 #include "pid.h"
 
 
-double UpdatePID(pid_var *pid, double error, double position)
+void InitPID(pid_var *pid, int type)
 {
-    double	pTerm, dTerm, iTerm;
-
-    pTerm = pid->pGain * error;
-
-    /*
-     * Calculate the integral state with appopriate limiting
-     */
-    pid->iState += error;
-    if (pid->iState > pid->iMax)
-	pid->iState = pid->iMax;
-    else if (pid->iState < pid->iMin)
-	pid->iState = pid->iMin;
-
-    iTerm = pid->iGain * pid->iState;
-
-    dTerm = pid->dGain * (pid->dState - position);
-    pid->dState = position;
-
-    return pTerm + dTerm + iTerm;
+    pid->Err = pid->ErrLast = pid->ErrLastLast = 0.0;
+    pid->Input = pid->InputD = pid->OutP = pid->InputLast = pid->SetP = 0.0;
+    pid->pGain = pid->iGain = pid->dGain = 0.0;
+    pid->idleRange = 0.4;
+    pid->Mode = PID_MODE_NONE;
+    pid->Type = type;
+    pid->iMax = 100.0;
 }
 
 
+
+void UpdatePID(pid_var *pid)
+{
+    if (pid->Mode == PID_MODE_AUTO) {
+
+	pid->InputD = pid->Input + (pid->Input - pid->InputLast) * pid->dGain * PID_TIMES;
+	pid->InputLast = pid->Input;
+	if (pid->Type == PID_TYPE_HEAT)
+	    pid->Err = pid->InputD - pid->SetP;
+	else
+	    pid->Err = pid->SetP - pid->InputD;
+
+	pid->OutP = pid->OutP + pid->pGain * (pid->Err - pid->ErrLast + pid->iGain * pid->Err + pid->dGain * (pid->Err - pid->ErrLast * 2 + pid->ErrLastLast));
+	pid->ErrLastLast = pid->ErrLast;
+	pid->ErrLast = pid->Err;
+
+    } if (pid->Mode == PID_MODE_BOO) {
+	/*
+	 * Mode Bang On Off
+	 */
+	pid->InputLast = pid->Input;
+	if (pid->Type == PID_TYPE_HEAT)
+	    pid->ErrLastLast = pid->ErrLast = pid->Err = pid->SetP - pid->Input;
+	else
+	    pid->ErrLastLast = pid->ErrLast = pid->Err = pid->Input - pid->SetP;
+
+	if (pid->Err > 0.0)
+	    pid->OutP = pid->iMax;
+	else
+	    pid->OutP = 0.0;
+
+    } else {
+	/*
+	 * While in manual mode, stay ready for bumpless switch to
+	 * auto.
+	 */
+	pid->InputLast = pid->Input;
+	pid->ErrLastLast = pid->ErrLast = pid->Err;
+    }
+
+    if (pid->OutP > pid->iMax)
+	pid->OutP = pid->iMax;
+    if (pid->OutP < 0.0)
+	pid->OutP = 0.0;
+
+}
+
+

mercurial