1304 } |
1304 } |
1305 #endif |
1305 #endif |
1306 } |
1306 } |
1307 |
1307 |
1308 /* |
1308 /* |
1309 * PID controller per unit, each second |
1309 * Temperature control per unit, each second |
1310 */ |
1310 */ |
1311 for (unit = Config.units; unit; unit = unit->next) { |
1311 for (unit = Config.units; unit; unit = unit->next) { |
1312 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)) { |
1313 // double pTerm, dTerm, iTerm; |
|
1314 int usePid = TRUE; |
1313 int usePid = TRUE; |
1315 |
1314 |
1316 sp = unit->beer_set; |
1315 sp = unit->beer_set; |
1317 pv = unit->beer_temperature / 1000.0; |
1316 pv = unit->beer_temperature / 1000.0; |
1318 if (unit->mode == UNITMODE_FRIDGE) { |
1317 if (unit->mode == UNITMODE_FRIDGE) { |
1349 Out = -100.0; |
1348 Out = -100.0; |
1350 |
1349 |
1351 if (debug) |
1350 if (debug) |
1352 fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n", |
1351 fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n", |
1353 sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out); |
1352 sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out); |
1354 if ((Out >= 1) || (Out <= -1) || (seconds == 60) || unit->heater_state || unit->cooler_state) { |
1353 if (((Out >= 1) && unit->heater_address) || ((Out <= -1) && unit->cooler_address) || |
|
1354 (seconds == 60) || unit->heater_state || unit->cooler_state) { |
1355 syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f Out=%.2f", |
1355 syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f Out=%.2f", |
1356 sp, pv, P_err, unit->PID_dState, unit->PID_iState, Out); |
1356 sp, pv, P_err, unit->PID_dState, unit->PID_iState, Out); |
1357 } |
1357 } |
1358 |
1358 |
1359 unit->PID_iState = pid->iState; |
1359 unit->PID_iState = pid->iState; |
1369 } else if (P_err < 0) { |
1369 } else if (P_err < 0) { |
1370 Out = -100.0; |
1370 Out = -100.0; |
1371 } else { |
1371 } else { |
1372 Out = 0.0; |
1372 Out = 0.0; |
1373 } |
1373 } |
1374 if ((Out >= 1) || (Out <= -1) || (seconds == 60) || unit->heater_state || unit->cooler_state) { |
1374 if (((Out >= 1) && unit->heater_address) || ((Out <= -1) && unit->cooler_address) || |
|
1375 (seconds == 60) || unit->heater_state || unit->cooler_state) { |
1375 syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f Out=%.2f", |
1376 syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f Out=%.2f", |
1376 sp, pv, P_err, Out); |
1377 sp, pv, P_err, Out); |
1377 } |
1378 } |
1378 } |
1379 } |
1379 |
|
1380 // pTerm = unit->PID_Kp * P_err; |
|
1381 |
|
1382 /* |
|
1383 * Calculate the intergral state with appropriate limiting |
|
1384 */ |
|
1385 // unit->PID_iState += P_err; |
|
1386 /* Limit integral error */ |
|
1387 // if (unit->PID_iState < -100.0) |
|
1388 // unit->PID_iState = -100.0; |
|
1389 // if (unit->PID_iState > 100.0) |
|
1390 // unit->PID_iState = 100.0; |
|
1391 // iTerm = unit->PID_iState * unit->PID_Ki; |
|
1392 // dTerm = (unit->PID_dState - pv) * unit->PID_Kd; |
|
1393 |
|
1394 /* |
|
1395 * A postive value means heating, a negative value cooling. |
|
1396 * Start with Kp, Kd and Ki set to 0. |
|
1397 * Increase Kp until small oscillation. |
|
1398 * Increase Kd until a little damping. |
|
1399 * Increase Ki after Kp and Kd are set until longterm convergence. |
|
1400 */ |
|
1401 // Out = pTerm + dTerm + iTerm; |
|
1402 // if (Out > 100.0) |
|
1403 // Out = 100.0; |
|
1404 // if (Out < -100.0) |
|
1405 // Out = -100.0; |
|
1406 // if (debug) |
|
1407 // fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n", |
|
1408 // sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out); |
|
1409 // if ((Out >= 1) || (Out <= -1) || (seconds == 60) || unit->heater_state || unit->cooler_state) { |
|
1410 // syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f pTerm=%.2f iTerm=%.2f dTerm=%.2f Out=%.2f", |
|
1411 // sp, pv, P_err, unit->PID_dState, unit->PID_iState, pTerm, iTerm, dTerm, Out); |
|
1412 // } |
|
1413 // unit->PID_dState = pv; |
|
1414 |
1380 |
1415 if (unit->heater_address && ! unit->cooler_state) { |
1381 if (unit->heater_address && ! unit->cooler_state) { |
1416 if (Out >= 1) { |
1382 if (Out >= 1) { |
1417 if (unit->heater_wait < unit->heater_delay) { |
1383 if (unit->heater_wait < unit->heater_delay) { |
1418 unit->heater_wait++; |
1384 unit->heater_wait++; |