Initial code for a simple PID controller.

Mon, 04 Aug 2014 15:18:29 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Mon, 04 Aug 2014 15:18:29 +0200
changeset 176
8c7d87a2c094
parent 175
b73490398368
child 177
48d19ec83a49

Initial code for a simple PID controller.

thermferm/rdconfig.c file | annotate | diff | comparison | revisions
thermferm/server.c file | annotate | diff | comparison | revisions
thermferm/thermferm.c file | annotate | diff | comparison | revisions
thermferm/thermferm.h file | annotate | diff | comparison | revisions
--- a/thermferm/rdconfig.c	Sun Aug 03 22:49:33 2014 +0200
+++ b/thermferm/rdconfig.c	Mon Aug 04 15:18:29 2014 +0200
@@ -680,6 +680,7 @@
     unit->idle_rangeH = 1.0;
     unit->idle_rangeL = -1.0;
     unit->prof_started = (time_t)0;
+    unit->PID_err_old = 0.0;
 
     cur = cur->xmlChildrenNode;
     while (cur != NULL) {
--- a/thermferm/server.c	Sun Aug 03 22:49:33 2014 +0200
+++ b/thermferm/server.c	Mon Aug 04 15:18:29 2014 +0200
@@ -1067,6 +1067,7 @@
 	unit->idle_rangeH = 1.0;
 	unit->idle_rangeL = -1.0;
 	unit->prof_started = (time_t)0;
+	unit->PID_err_old = 0.0;
 
 	if (Config.units == NULL) {
 	    Config.units = unit;
--- a/thermferm/thermferm.c	Sun Aug 03 22:49:33 2014 +0200
+++ b/thermferm/thermferm.c	Mon Aug 04 15:18:29 2014 +0200
@@ -232,6 +232,7 @@
     time_t		now, last = (time_t)0;
     units_list		*unit;
     int			rc, run = 1, seconds = 0, minutes = 0;
+    float		err = 0.0, sp, pv, P_err, I_err, D_err, Out;
 #ifdef HAVE_WIRINGPI_H
     struct tm		*tm;
     int			row;
@@ -345,6 +346,33 @@
 		for (unit = Config.units; unit; unit = unit->next) {
 		    if (unit->mode != UNITMODE_OFF) {
 
+			if (0) {
+			    /*
+			     * PID controller
+			     */
+			    sp = unit->beer_set;
+			    pv = unit->beer_temperature;
+			    if (unit->mode == UNITMODE_FRIDGE) {
+				sp = unit->fridge_set;
+				pv = unit->air_temperature;
+			    } else if (unit->mode == UNITMODE_PROFILE) {
+				sp = unit->prof_target;
+			    }
+
+			    unit->PID_err_old = err;
+			    err = sp - pv;
+			    if (err < unit->idle_rangeH && err > unit->idle_rangeL)
+				err = 0;
+			    P_err = err;
+			    I_err += unit->PID_err_old;
+			    D_err = err - unit->PID_err_old;
+
+			    Out = 0.1*P_err + 0.3*I_err + 0.02*D_err;
+			    if (debug)
+				fprintf(stdout, "sp=%.2f pv=%.2f err_old=%.2f err=%.2f P_err=%.2f I_err=%.2f D_err=%.2f Out=%.2f\n",
+						sp, pv, unit->PID_err_old, err, P_err, I_err, D_err, Out);
+			}
+
 			snprintf(target, 39, "NA");
 			snprintf(heater, 39, "NA");
 			snprintf(cooler, 39, "NA");
--- a/thermferm/thermferm.h	Sun Aug 03 22:49:33 2014 +0200
+++ b/thermferm/thermferm.h	Mon Aug 04 15:18:29 2014 +0200
@@ -91,6 +91,7 @@
     time_t		prof_started;		/* Profile start time		*/
     int			prof_state;		/* Profile OFF|PAUSE|RUN|DONE	*/
     float		prof_target;		/* Profile current target temp	*/
+    float		PID_err_old;		/* PID old error value		*/
 } units_list;
 
 #define	UNITMODE_OFF		0		/* Unit turned off		*/

mercurial