PID finetuning

Tue, 05 Aug 2014 21:33:06 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Tue, 05 Aug 2014 21:33:06 +0200
changeset 185
4f34271cf1e7
parent 184
db997a04fde3
child 186
7c44b11a10b0

PID finetuning

thermferm/devices.c file | annotate | diff | comparison | revisions
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
www-thermferm/liveview.php file | annotate | diff | comparison | revisions
--- a/thermferm/devices.c	Tue Aug 05 16:24:17 2014 +0200
+++ b/thermferm/devices.c	Tue Aug 05 21:33:06 2014 +0200
@@ -38,16 +38,21 @@
     devices_list	*device;
     char		buf[40];
     int			i, rc;
+    time_t		now;
 
     if (uuid == NULL)
 	return 0;
 
-    if (debug)
-	fprintf(stdout, "device_out(%s, %d)\n", uuid, value);
+    now = time(NULL);
 
     for (device = Config.devices; device; device = device->next) {
 	if (strcmp(uuid, device->uuid) == 0) {
-	    if (value != device->value) {
+	    /*
+	     * Execute command if different then the old value. But also
+	     * every 2 minutes because commands can get lost of devices were
+	     * disconnected, or with radio problems.
+	     */
+	    if ((value != device->value) || (((int)now - (int)device->timestamp) > 120)) {
 
 #ifdef HAVE_WIRINGPI_H
 		rc = 0;
@@ -81,6 +86,7 @@
 	    }
 	}
     }
+
     return 0;
 }	   
 
--- a/thermferm/rdconfig.c	Tue Aug 05 16:24:17 2014 +0200
+++ b/thermferm/rdconfig.c	Tue Aug 05 21:33:06 2014 +0200
@@ -680,7 +680,7 @@
     unit->idle_rangeH = 1.0;
     unit->idle_rangeL = -1.0;
     unit->prof_started = (time_t)0;
-    unit->PID_err_old = 0.0;
+    unit->PID_err_old = unit->PID_I_err = 0.0;
 
     cur = cur->xmlChildrenNode;
     while (cur != NULL) {
--- a/thermferm/server.c	Tue Aug 05 16:24:17 2014 +0200
+++ b/thermferm/server.c	Tue Aug 05 21:33:06 2014 +0200
@@ -1028,7 +1028,7 @@
 	unit->idle_rangeH = 1.0;
 	unit->idle_rangeL = -1.0;
 	unit->prof_started = (time_t)0;
-	unit->PID_err_old = 0.0;
+	unit->PID_err_old = unit->PID_I_err = 0.0;
 
 	if (Config.units == NULL) {
 	    Config.units = unit;
--- a/thermferm/thermferm.c	Tue Aug 05 16:24:17 2014 +0200
+++ b/thermferm/thermferm.c	Tue Aug 05 21:33:06 2014 +0200
@@ -249,7 +249,7 @@
     time_t		now, last = (time_t)0;
     units_list		*unit;
     int			rc, run = 1, seconds = 0, minutes = 0, piddelay = 0, temp, deviation;
-    float		err = 0.0, sp, pv, P_err, I_err = 0.0, D_err, Out;
+    float		err = 0.0, sp, pv, P_err, D_err, Out;
 #ifdef HAVE_WIRINGPI_H
     struct tm		*tm;
     int			row;
@@ -446,20 +446,28 @@
 
 			unit->PID_err_old = err;
 			err = sp - pv;
-			if (err < unit->idle_rangeH && err > unit->idle_rangeL)
+			if (err < unit->idle_rangeH && err > unit->idle_rangeL) {
 			    err = 0;
+			    unit->PID_I_err -= unit->PID_err_old;
+			} else {
+			    unit->PID_I_err += unit->PID_err_old;
+			}
+			/* Limit intergral error */
+			if (unit->PID_I_err < -10.0)
+			    unit->PID_I_err = -10.0;
+			if (unit->PID_I_err > 10.0)
+			    unit->PID_I_err = 10.0;
 			P_err = err;
-			I_err += unit->PID_err_old;
 			D_err = err - unit->PID_err_old;
 
 			/*
 			 * A postive value means heating, a negative value cooling.
 			 */
-			Out = (5.0*P_err) + (0.25*I_err) + (1.5*D_err);
-			//     Kp 0.1        Ki 0.3        Kd 0.02
+			Out = (10.0*P_err) + (0.1*unit->PID_I_err) + (5*D_err);
+			//     Kp 0.1        Ki 0.3                   Kd 0.02
 			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);
+						sp, pv, unit->PID_err_old, err, P_err, unit->PID_I_err, D_err, Out);
 			if (unit->heater_address) {
 			    if (Out >= 2)
 				unit->heater_state = 100;
@@ -476,7 +484,7 @@
 			}
 		    } else {
 			err = 0.0;
-			I_err = 0.0;
+			unit->PID_I_err = 0.0;
 			unit->PID_err_old = 0.0;
 		    }
 		}
--- a/thermferm/thermferm.h	Tue Aug 05 16:24:17 2014 +0200
+++ b/thermferm/thermferm.h	Tue Aug 05 21:33:06 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_I_err;		/* PID Intergal error		*/
     float		PID_err_old;		/* PID old error value		*/
 } units_list;
 
--- a/www-thermferm/liveview.php	Tue Aug 05 16:24:17 2014 +0200
+++ b/www-thermferm/liveview.php	Tue Aug 05 21:33:06 2014 +0200
@@ -110,9 +110,9 @@
 	$outstr .= '             { name: \'Beer\', type: \'float\' },'.PHP_EOL;
 	$outstr .= '             { name: \'Target\', type: \'float\' },'.PHP_EOL;
 	$outstr .= '             { name: \'Heater\' },'.PHP_EOL;
-	$outstr .= '             { name: \'Cooler\' },'.PHP_EOL;
+	$outstr .= '             { name: \'Cooler\', type: \'int\' },'.PHP_EOL;
 	$outstr .= '             { name: \'Fan\' },'.PHP_EOL;
-	$outstr .= '             { name: \'Door\' }'.PHP_EOL;
+	$outstr .= '             { name: \'Door\', type: \'bool\' }'.PHP_EOL;
 	$outstr .= '          ],'.PHP_EOL;
 	$outstr .= '          url: \'getlog.php?unit='.$unit.'\''.PHP_EOL;
 	$outstr .= '       };'.PHP_EOL;
@@ -150,18 +150,25 @@
 	$outstr .= '             },'.PHP_EOL;
 	$outstr .= '             series: ['.PHP_EOL;
 	$outstr .= '               { dataField: \'Air\', displayText: \'Air\' },'.PHP_EOL;
-	$outstr .= '               { dataField: \'Beer\', displayText: \'Beer\' }'.PHP_EOL;
+	$outstr .= '               { dataField: \'Beer\', displayText: \'Beer\' },'.PHP_EOL;
+	$outstr .= '               { dataField: \'Target\', displayText: \'Target\' }'.PHP_EOL;
 	$outstr .= '             ]'.PHP_EOL;
 	$outstr .= '           }]'.PHP_EOL;
 	$outstr .= '       };'.PHP_EOL;
+	/* Direct draw for the first time */
 	$outstr .= '       $("#fermentor_chart_'.$unit.'").jqxChart(settings'.$unr.');'.PHP_EOL;
+	/* Regular updates of the chart */
+//	$outstr .= '       setInterval(function(){'.PHP_EOL;
+//	$outstr .= '         $("#fermentor_chart_'.$unit.'").jqxChart("update");'.PHP_EOL;
+//	$outstr .= '       }, 3000);'.PHP_EOL;
+
 	$outstr .= '       setInterval(function(){'.PHP_EOL;
-	$outstr .= '           $.getJSON("getstate.php?uuid='.$unit.'", function(data) {'.PHP_EOL;
-	$outstr .= '             $("#load_air_'.$unr.'").html(data.air_temperature);'.PHP_EOL;
-	$outstr .= '             $("#load_beer_'.$unr.'").html(data.beer_temperature);'.PHP_EOL;
-	$outstr .= '             $("#load_target_'.$unr.'").html(data.target_temperature);'.PHP_EOL;
-        $outstr .= '           });'.PHP_EOL;
-	$outstr .= '         }, 10000);'.PHP_EOL;
+	$outstr .= '         $.getJSON("getstate.php?uuid='.$unit.'", function(data) {'.PHP_EOL;
+	$outstr .= '           $("#load_air_'.$unr.'").html(data.air_temperature);'.PHP_EOL;
+	$outstr .= '           $("#load_beer_'.$unr.'").html(data.beer_temperature);'.PHP_EOL;
+	$outstr .= '           $("#load_target_'.$unr.'").html(data.target_temperature);'.PHP_EOL;
+        $outstr .= '         });'.PHP_EOL;
+	$outstr .= '       }, 10000);'.PHP_EOL;
 	$outstr .= '     });'.PHP_EOL;
 	$outstr .= '    </script>'.PHP_EOL;
 	$outstr .= '    <div id="fermentor">'.PHP_EOL;

mercurial