Added Kp, Kd and Ki settings to the units. Bumped to version 0.2.9

Sun, 15 Feb 2015 20:38:54 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sun, 15 Feb 2015 20:38:54 +0100
changeset 310
53774295e14a
parent 309
c0dc3cd97fa4
child 311
f3b0e9ac9bcb

Added Kp, Kd and Ki settings to the units. Bumped to version 0.2.9

configure file | annotate | diff | comparison | revisions
configure.ac 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/units.php file | annotate | diff | comparison | revisions
--- a/configure	Sun Feb 15 18:21:20 2015 +0100
+++ b/configure	Sun Feb 15 20:38:54 2015 +0100
@@ -2034,7 +2034,7 @@
 
 
 PACKAGE="mbsePi-apps"
-VERSION="0.2.8"
+VERSION="0.2.9"
 COPYRIGHT="Copyright (C) 2014-2015 Michiel Broek, All Rights Reserved"
 CYEARS="2014-2015"
 
--- a/configure.ac	Sun Feb 15 18:21:20 2015 +0100
+++ b/configure.ac	Sun Feb 15 20:38:54 2015 +0100
@@ -8,7 +8,7 @@
 dnl General settings
 dnl After changeing the version number, run autoconf!
 PACKAGE="mbsePi-apps"
-VERSION="0.2.8"
+VERSION="0.2.9"
 COPYRIGHT="Copyright (C) 2014-2015 Michiel Broek, All Rights Reserved"
 CYEARS="2014-2015"
 AC_SUBST(PACKAGE)
--- a/thermferm/rdconfig.c	Sun Feb 15 18:21:20 2015 +0100
+++ b/thermferm/rdconfig.c	Sun Feb 15 20:38:54 2015 +0100
@@ -469,6 +469,18 @@
 		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
 		return 1;
 	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_KP", "%.2f", tmp3->PID_Kp)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_KD", "%.2f", tmp3->PID_Kd)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;
+	    }
+	    if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PID_KI", "%.2f", tmp3->PID_Ki)) < 0) {
+		syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
+		return 1;
+	    }
 	    if (tmp3->profile) {
 		if ((rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PROFILE", "%s", tmp3->profile)) < 0) {
 		    syslog(LOG_NOTICE, "wrconfig: error at xmlTextWriterWriteFormatElement");
@@ -921,7 +933,7 @@
     unit->idle_rangeL = -1.0;
     unit->prof_started = unit->prof_paused = unit->prof_primary_done = (time_t)0;
     unit->prof_percent = 0;
-    unit->PID_err_old = unit->PID_I_err = 0.0;
+    unit->PID_err_old = unit->PID_I_err = unit->PID_Kp = unit->PID_Kd = unit->PID_Ki = 0.0;
 
     cur = cur->xmlChildrenNode;
     while (cur != NULL) {
@@ -1088,6 +1100,24 @@
 		unit->idle_rangeH = val;
 	    xmlFree(key);
 	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_KP"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		unit->PID_Kp = val;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_KD"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		unit->PID_Kd = val;
+	    xmlFree(key);
+	}
+	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PID_KI"))) {
+	    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+	    if (sscanf((const char *)key, "%f", &val) == 1)
+		unit->PID_Ki = val;
+	    xmlFree(key);
+	}
 	if ((!xmlStrcmp(cur->name, (const xmlChar *)"PROFILE"))) {
 	    unit->profile = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	}
--- a/thermferm/server.c	Sun Feb 15 18:21:20 2015 +0100
+++ b/thermferm/server.c	Sun Feb 15 20:38:54 2015 +0100
@@ -1505,7 +1505,7 @@
 	unit->idle_rangeL = -1.0;
 	unit->prof_started = unit->prof_paused = unit->prof_primary_done = (time_t)0;
 	unit->prof_percent = 0;
-	unit->PID_err_old = unit->PID_I_err = 0.0;
+	unit->PID_err_old = unit->PID_I_err = unit->PID_Kp = unit->PID_Kd = unit->PID_Ki = 0.0;
 
 	/*
 	 * Block main process
@@ -1615,6 +1615,9 @@
 		srv_send((char *)"TEMP_SET_MAX,%.1f", unit->temp_set_max);
 		srv_send((char *)"IDLE_RANGE_L,%.1f", unit->idle_rangeL);
 		srv_send((char *)"IDLE_RANGE_H,%.1f", unit->idle_rangeH);
+		srv_send((char *)"PID_KP,%.2f", unit->PID_Kp);
+		srv_send((char *)"PID_KD,%.2f", unit->PID_Kd);
+		srv_send((char *)"PID_KI,%.2f", unit->PID_Ki);
 		srv_send((char *)".");
 		return 1;
 	    }
@@ -1875,11 +1878,32 @@
 
 			    } else if (val && (strcmp(kwd, (char *)"BEER_SET") == 0)) {
 				if ((sscanf(val, "%f", &fval) == 1) && (fval >= unit->temp_set_min) && (fval <= unit->temp_set_max)) {
-				    if (unit->fridge_set != fval)
+				    if (unit->beer_set != fval)
 				    	syslog(LOG_NOTICE, "Fermenter unit %s beer temperature %.1f to %.1f", unit->uuid, unit->beer_set, fval);
 				    unit->beer_set = fval;
 				}
 
+			    } else if (val && (strcmp(kwd, (char *)"PID_KP") == 0)) {
+				if ((sscanf(val, "%f", &fval) == 1) && (fval >= 0.0)) {
+				    if (unit->PID_Kp != fval)
+					syslog(LOG_NOTICE, "Fermenter unit %s PID Kp %.2f to %.2f", unit->uuid, unit->PID_Kp, fval);
+				    unit->PID_Kp = fval;
+				}
+
+			    } else if (val && (strcmp(kwd, (char *)"PID_KD") == 0)) {
+				if ((sscanf(val, "%f", &fval) == 1) && (fval >= 0.0)) {
+				    if (unit->PID_Kd != fval)
+					syslog(LOG_NOTICE, "Fermenter unit %s PID Kd %.2f to %.2f", unit->uuid, unit->PID_Kd, fval);
+				    unit->PID_Kd = fval;
+				}
+	
+			    } else if (val && (strcmp(kwd, (char *)"PID_KI") == 0)) {
+				if ((sscanf(val, "%f", &fval) == 1) && (fval >= 0.0)) {
+				    if (unit->PID_Ki != fval)
+					syslog(LOG_NOTICE, "Fermenter unit %s PID Ki %.2f to %.2f", unit->uuid, unit->PID_Ki, fval);
+				    unit->PID_Ki = fval;
+				}
+
 			    } else if (strcmp(kwd, (char *)"PROFILE") == 0) {
 				if (unit->prof_state == PROFILE_OFF) {
 				    /*
--- a/thermferm/thermferm.c	Sun Feb 15 18:21:20 2015 +0100
+++ b/thermferm/thermferm.c	Sun Feb 15 20:38:54 2015 +0100
@@ -1338,8 +1338,13 @@
 
 			/*
 			 * A postive value means heating, a negative value cooling.
+			 * Start with Kp, Kd and Ki set to 0.
+			 * Increase Kp until small oscillation.
+			 * Increase Kd until a little damping.
+			 * Increase Ki after Kp and Kd are set until longterm convergence.
 			 */
-			Out = (10.0*P_err) + (0.1*unit->PID_I_err) + (5*D_err);
+			Out = (10.0*P_err) + (0.0*unit->PID_I_err) + (0.0*D_err);
+			//Out = (10.0*P_err) + (0.1*unit->PID_I_err) + (5*D_err);
 			//     Kp 0.1        Ki 0.3                   Kd 0.02
 			if (err != 0.0) {
 			    if (debug)
--- a/thermferm/thermferm.h	Sun Feb 15 18:21:20 2015 +0100
+++ b/thermferm/thermferm.h	Sun Feb 15 20:38:54 2015 +0100
@@ -151,8 +151,11 @@
     float		prof_peak_abs;		/* Profile absolute peak temp	*/
     float		prof_peak_rel;		/* Profile relative peak temp	*/
     time_t		prof_primary_done;	/* Profile primary is done	*/
-    float		PID_I_err;		/* PID Intergal error		*/
+    float		PID_I_err;		/* PID Integral error		*/
     float		PID_err_old;		/* PID old error value		*/
+    float		PID_Kp;			/* PID Kp setting		*/
+    float		PID_Kd;			/* PID Kd setting		*/
+    float		PID_Ki;			/* PID Ki setting		*/
 } units_list;
 
 #define	UNITMODE_OFF		0		/* Unit turned off		*/
--- a/www-thermferm/units.php	Sun Feb 15 18:21:20 2015 +0100
+++ b/www-thermferm/units.php	Sun Feb 15 20:38:54 2015 +0100
@@ -107,6 +107,9 @@
 	$cmd[] = "TEMP_SET_MAX,".$_POST['TempSetMax'];
 	$cmd[] = "IDLE_RANGE_L,".$_POST['IdleRangeL'];
 	$cmd[] = "IDLE_RANGE_H,".$_POST['IdleRangeH'];
+	$cmd[] = "PID_KP,".$_POST['PID_Kp'];
+	$cmd[] = "PID_KD,".$_POST['PID_Kd'];
+	$cmd[] = "PID_KI,".$_POST['PID_Ki'];
 	$cmd[] = ".";
 	send_array($cmd);
     }
@@ -131,6 +134,9 @@
     unset($_POST['TempSetMax']);
     unset($_POST['IdleRangeL']);
     unset($_POST['IdleRangeH']);
+    unset($_POST['PID_Kp']);
+    unset($_POST['PID_Kd']);
+    unset($_POST['PID_Ki']);
     load('units.php');
 }
 
@@ -166,6 +172,7 @@
 	isset($_POST['BeerAddress']) && isset($_POST['HeaterAddress']) && isset($_POST['CoolerAddress']) && isset($_POST['LightAddress']) &&
 	isset($_POST['HeaterDelay']) && isset($_POST['CoolerDelay']) && isset($_POST['LightDelay']) && isset($_POST['PSUAddress']) &&
 	isset($_POST['FanAddress']) && isset($_POST['DoorAddress']) && isset($_POST['TempSetMin']) && isset($_POST['TempSetMax']) &&
+	isset($_POST['PID_Kp']) && isset($_POST['PID_Kd']) && isset($_POST['PID_Li']) &&
 	isset($_POST['IdleRangeL']) && isset($_POST['IdleRangeH']) && isset($_POST['key']) && isset($_POST['command'])) {
 
 	if ($_POST['key'] == 'Cancel')
@@ -534,6 +541,24 @@
 		$outstr .= '        <td class="editfield"><input type="text" name="IdleRangeH" size="5" value="'.$f[1].'"> &deg;C (Heater margin)</td>'.PHP_EOL;
 		$outstr .= '       </tr>'.PHP_EOL;
 	    }
+	    if ($f[0] == "PID_KP") {
+		$outstr .= '       <tr class="editor">'.PHP_EOL;
+		$outstr .= '        <td class="editname">PID Kp</td>'.PHP_EOL;
+		$outstr .= '        <td class="editfield"><input type="text" name="PID_Kp" size="6" value="'.$f[1].'"> Proportional</td>'.PHP_EOL;
+		$outstr .= '       </tr>'.PHP_EOL;
+	    }
+	    if ($f[0] == "PID_KI") {
+		$outstr .= '       <tr class="editor">'.PHP_EOL;
+		$outstr .= '        <td class="editname">PID Ki</td>'.PHP_EOL;
+		$outstr .= '        <td class="editfield"><input type="text" name="PID_Ki" size="6" value="'.$f[1].'"> Intergral</td>'.PHP_EOL;
+		$outstr .= '       </tr>'.PHP_EOL;
+	    }
+	    if ($f[0] == "PID_KD") {
+		$outstr .= '       <tr class="editor">'.PHP_EOL;
+		$outstr .= '        <td class="editname">PID Kd</td>'.PHP_EOL;
+		$outstr .= '        <td class="editfield"><input type="text" name="PID_Kd" size="6" value="'.$f[1].'"> Derivative</td>'.PHP_EOL;
+		$outstr .= '       </tr>'.PHP_EOL;
+	    }
 	    $i++;
 	}
     }
@@ -638,6 +663,9 @@
     $outstr .= '<input type="hidden" value="30.0" name="TempSetMax">';
     $outstr .= '<input type="hidden" value="-1.0" name="IdleRangeL">';
     $outstr .= '<input type="hidden" value="1.0" name="IdleRangeH">';
+    $outstr .= '<input type="hidden" value="0.0" name="PID_Kp">';
+    $outstr .= '<input type="hidden" value="0.0" name="PID_Kd">';
+    $outstr .= '<input type="hidden" value="0.0" name="PID_Ki">';
     $outstr .= '<input type="hidden" value="testdata" name="action">';
     $outstr .= '<input type="hidden" value="add" name="command">';
     $outstr .= '<input type="hidden" value="00000000-0000-0000-0000-000000000000" name="UUID">';

mercurial