thermferm/thermferm.c

changeset 316
73cd31dc6ce1
parent 315
198f3b4bd0d8
child 317
18dd6eadba31
equal deleted inserted replaced
315:198f3b4bd0d8 316:73cd31dc6ce1
30 #include "lcd-pcf8574.h" 30 #include "lcd-pcf8574.h"
31 #include "lcd-buffer.h" 31 #include "lcd-buffer.h"
32 #include "panel.h" 32 #include "panel.h"
33 #include "futil.h" 33 #include "futil.h"
34 #include "xutil.h" 34 #include "xutil.h"
35 #include "pid.h"
35 36
36 37
37 int my_shutdown = FALSE; 38 int my_shutdown = FALSE;
38 static pid_t pgrp, mypid; 39 static pid_t pgrp, mypid;
39 int run_pause = FALSE; 40 int run_pause = FALSE;
843 #else 844 #else
844 long t = 0; 845 long t = 0;
845 #endif 846 #endif
846 int current_step, valid_step, time_until_now; 847 int current_step, valid_step, time_until_now;
847 float previous_target; 848 float previous_target;
849 pid_var *pid;
850
848 851
849 if (lockprog((char *)"thermferm")) { 852 if (lockprog((char *)"thermferm")) {
850 syslog(LOG_NOTICE, "Can't lock"); 853 syslog(LOG_NOTICE, "Can't lock");
851 return 1; 854 return 1;
852 } 855 }
1305 /* 1308 /*
1306 * PID controller per unit, each second 1309 * PID controller per unit, each second
1307 */ 1310 */
1308 for (unit = Config.units; unit; unit = unit->next) { 1311 for (unit = Config.units; unit; unit = unit->next) {
1309 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE)) { 1312 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE)) {
1310 double pTerm, dTerm, iTerm; 1313 // double pTerm, dTerm, iTerm;
1311 1314
1312 sp = unit->beer_set; 1315 sp = unit->beer_set;
1313 pv = unit->beer_temperature / 1000.0; 1316 pv = unit->beer_temperature / 1000.0;
1314 if (unit->mode == UNITMODE_FRIDGE) { 1317 if (unit->mode == UNITMODE_FRIDGE) {
1315 sp = unit->fridge_set; 1318 sp = unit->fridge_set;
1323 */ 1326 */
1324 P_err = sp - pv; 1327 P_err = sp - pv;
1325 if (P_err < unit->idle_rangeH && P_err > unit->idle_rangeL) { 1328 if (P_err < unit->idle_rangeH && P_err > unit->idle_rangeL) {
1326 P_err = 0.0; 1329 P_err = 0.0;
1327 } 1330 }
1328 pTerm = unit->PID_Kp * P_err; 1331
1332 pid = (pid_var *)malloc(sizeof(pid_var));
1333 pid->dState = unit->PID_dState;
1334 pid->iState = unit->PID_iState;
1335 pid->iMax = 100.0;
1336 pid->iMin = -100.0;
1337 pid->pGain = unit->PID_Kp;
1338 pid->iGain = unit->PID_Ki;
1339 pid->dGain = unit->PID_Kd;
1340
1341 Out = UpdatePID(pid, P_err, pv);
1342
1343 if (Out > 100.0)
1344 Out = 100.0;
1345 if (Out < -100.0)
1346 Out = -100.0;
1347
1348 if (debug)
1349 fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n",
1350 sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out);
1351 if ((Out >= 1) || (Out <= -1) || (seconds == 60) || unit->heater_state || unit->cooler_state) {
1352 syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f Out=%.2f",
1353 sp, pv, P_err, unit->PID_dState, unit->PID_iState, Out);
1354 }
1355
1356 unit->PID_iState = pid->iState;
1357 unit->PID_dState = pid->dState;
1358
1359 // pTerm = unit->PID_Kp * P_err;
1329 1360
1330 /* 1361 /*
1331 * Calculate the intergral state with appropriate limiting 1362 * Calculate the intergral state with appropriate limiting
1332 */ 1363 */
1333 unit->PID_iState += P_err; 1364 // unit->PID_iState += P_err;
1334 /* Limit integral error */ 1365 /* Limit integral error */
1335 if (unit->PID_iState < -100.0) 1366 // if (unit->PID_iState < -100.0)
1336 unit->PID_iState = -100.0; 1367 // unit->PID_iState = -100.0;
1337 if (unit->PID_iState > 100.0) 1368 // if (unit->PID_iState > 100.0)
1338 unit->PID_iState = 100.0; 1369 // unit->PID_iState = 100.0;
1339 iTerm = unit->PID_iState * unit->PID_Ki; 1370 // iTerm = unit->PID_iState * unit->PID_Ki;
1340 dTerm = (unit->PID_dState - pv) * unit->PID_Kd; 1371 // dTerm = (unit->PID_dState - pv) * unit->PID_Kd;
1341 1372
1342 /* 1373 /*
1343 * A postive value means heating, a negative value cooling. 1374 * A postive value means heating, a negative value cooling.
1344 * Start with Kp, Kd and Ki set to 0. 1375 * Start with Kp, Kd and Ki set to 0.
1345 * Increase Kp until small oscillation. 1376 * Increase Kp until small oscillation.
1346 * Increase Kd until a little damping. 1377 * Increase Kd until a little damping.
1347 * Increase Ki after Kp and Kd are set until longterm convergence. 1378 * Increase Ki after Kp and Kd are set until longterm convergence.
1348 */ 1379 */
1349 Out = pTerm + dTerm + iTerm; 1380 // Out = pTerm + dTerm + iTerm;
1350 if (Out > 100.0) 1381 // if (Out > 100.0)
1351 Out = 100.0; 1382 // Out = 100.0;
1352 if (Out < -100.0) 1383 // if (Out < -100.0)
1353 Out = -100.0; 1384 // Out = -100.0;
1354 if (debug) 1385 // if (debug)
1355 fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n", 1386 // fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n",
1356 sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out); 1387 // sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out);
1357 if ((Out >= 1) || (Out <= -1) || (seconds == 60) || unit->heater_state || unit->cooler_state) { 1388 // if ((Out >= 1) || (Out <= -1) || (seconds == 60) || unit->heater_state || unit->cooler_state) {
1358 syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f pTerm=%.2f iTerm=%.2f dTerm=%.2f Out=%.2f", 1389 // syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f pTerm=%.2f iTerm=%.2f dTerm=%.2f Out=%.2f",
1359 sp, pv, P_err, unit->PID_dState, unit->PID_iState, pTerm, iTerm, dTerm, Out); 1390 // sp, pv, P_err, unit->PID_dState, unit->PID_iState, pTerm, iTerm, dTerm, Out);
1360 } 1391 // }
1361 unit->PID_dState = pv; 1392 // unit->PID_dState = pv;
1362 1393
1363 if (unit->heater_address) { 1394 if (unit->heater_address) {
1364 if (Out >= 1) { 1395 if (Out >= 1) {
1365 if (unit->heater_wait < unit->heater_delay) { 1396 if (unit->heater_wait < unit->heater_delay) {
1366 unit->heater_wait++; 1397 unit->heater_wait++;

mercurial