brewco/pid.c

changeset 434
eb724767860d
child 435
4b1ed6897d80
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/brewco/pid.c	Wed Nov 25 22:49:35 2015 +0100
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * Copyright (C) 2015
+ *   
+ * Michiel Broek <mbroek at mbse dot eu>
+ *
+ * This file is part of the mbsePi-apps
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * mbsePi-apps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with ThermFerm; see the file COPYING.  If not, write to the Free
+ * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *****************************************************************************/
+
+#include "brewco.h"
+#include "pid.h"
+
+
+void InitPID(pid_var *pid)
+{
+    pid->Err = pid->ErrLast = pid->iState = 0.0;
+    pid->Input = pid->OutP = pid->SetP = 0.0;
+    pid->pGain = pid->iGain = pid->dGain = 0.0;
+    pid->Mode = PID_MODE_NONE;
+    pid->iMax = 100.0;
+}
+
+
+
+void UpdatePID(pid_var *pid)
+{
+    if (pid->Mode == PID_MODE_AUTO) {
+
+	double	pTerm, dTerm, iTerm;
+
+	pid->Err = pid->SetP - pid->Input;
+
+	/*
+	 * Calculate the integral state with appopriate limiting.
+	 * Use ErrLastLast as iState
+	 */
+	pid->iState += pid->Err;
+	if (pid->iState > PID_WINDUP_GUARD)
+	    pid->iState = PID_WINDUP_GUARD;
+	else if (pid->iState < -PID_WINDUP_GUARD)
+	    pid->iState = -PID_WINDUP_GUARD;
+
+	pTerm = pid->pGain * pid->Err;
+	iTerm = pid->iGain * pid->iState;
+	dTerm = pid->dGain * (pid->Err - pid->ErrLast);
+
+	pid->OutP = pTerm + dTerm + iTerm;
+	pid->ErrLast = pid->Err;
+
+    } else if (pid->Mode == PID_MODE_BOO) {
+	/*
+	 * Mode Bang On Off
+	 */
+	pid->ErrLast = pid->Err;
+	pid->Err = pid->SetP - pid->Input;
+
+	if (pid->OutP && (pid->Err <= 0.0))
+	    pid->OutP = 0.0;
+	else if ((pid->OutP == 0.0) && (pid->Err > 0.0))
+	    pid->OutP = pid->iMax;
+
+	pid->iState = 0.0;
+
+    } else {
+	/*
+	 * While in manual mode, stay ready for bumpless switch to
+	 * auto.
+	 */
+	pid->ErrLast = pid->Err = 0.0;
+	pid->OutP = pid->iState = 0.0;
+    }
+
+    if (pid->OutP > pid->iMax)
+	pid->OutP = pid->iMax;
+    if (pid->OutP < 0.0)
+	pid->OutP = 0.0;
+
+}
+
+

mercurial