# HG changeset patch # User Michiel Broek # Date 1424029134 -3600 # Node ID 53774295e14af9fe30dc22ead57af15c85345d08 # Parent c0dc3cd97fa4d7602572b51b44853765346a069e Added Kp, Kd and Ki settings to the units. Bumped to version 0.2.9 diff -r c0dc3cd97fa4 -r 53774295e14a configure --- 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" diff -r c0dc3cd97fa4 -r 53774295e14a configure.ac --- 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) diff -r c0dc3cd97fa4 -r 53774295e14a thermferm/rdconfig.c --- 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); } diff -r c0dc3cd97fa4 -r 53774295e14a thermferm/server.c --- 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) { /* diff -r c0dc3cd97fa4 -r 53774295e14a thermferm/thermferm.c --- 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) diff -r c0dc3cd97fa4 -r 53774295e14a thermferm/thermferm.h --- 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 */ diff -r c0dc3cd97fa4 -r 53774295e14a www-thermferm/units.php --- 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 .= ' °C (Heater margin)'.PHP_EOL; $outstr .= ' '.PHP_EOL; } + if ($f[0] == "PID_KP") { + $outstr .= ' '.PHP_EOL; + $outstr .= ' PID Kp'.PHP_EOL; + $outstr .= ' Proportional'.PHP_EOL; + $outstr .= ' '.PHP_EOL; + } + if ($f[0] == "PID_KI") { + $outstr .= ' '.PHP_EOL; + $outstr .= ' PID Ki'.PHP_EOL; + $outstr .= ' Intergral'.PHP_EOL; + $outstr .= ' '.PHP_EOL; + } + if ($f[0] == "PID_KD") { + $outstr .= ' '.PHP_EOL; + $outstr .= ' PID Kd'.PHP_EOL; + $outstr .= ' Derivative'.PHP_EOL; + $outstr .= ' '.PHP_EOL; + } $i++; } } @@ -638,6 +663,9 @@ $outstr .= ''; $outstr .= ''; $outstr .= ''; + $outstr .= ''; + $outstr .= ''; + $outstr .= ''; $outstr .= ''; $outstr .= ''; $outstr .= '';