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++; |