thermferm/thermferm.c

changeset 362
c92651a54969
parent 361
308f6a436779
child 363
468ec0d96cce
equal deleted inserted replaced
361:308f6a436779 362:c92651a54969
839 units_list *unit; 839 units_list *unit;
840 profiles_list *profile; 840 profiles_list *profile;
841 prof_step *step; 841 prof_step *step;
842 int rc, run = 1, seconds = 0, minutes = 0, temp, deviation; 842 int rc, run = 1, seconds = 0, minutes = 0, temp, deviation;
843 int run_seconds, run_minutes, run_hours, tot_minutes; 843 int run_seconds, run_minutes, run_hours, tot_minutes;
844 float sp, pv, P_err = 0.0, Out;
845 #ifdef HAVE_WIRINGPI_H 844 #ifdef HAVE_WIRINGPI_H
846 struct tm *tm; 845 struct tm *tm;
847 int row, key; 846 int row, key;
848 #else 847 #else
849 long t = 0; 848 long t = 0;
850 #endif 849 #endif
851 int current_step, valid_step, time_until_now; 850 int current_step, valid_step, time_until_now;
852 float previous_target; 851 float previous_target;
853 pid_var *pid;
854 852
855 853
856 if (lockprog((char *)"thermferm")) { 854 if (lockprog((char *)"thermferm")) {
857 syslog(LOG_NOTICE, "Can't lock"); 855 syslog(LOG_NOTICE, "Can't lock");
858 return 1; 856 return 1;
924 */ 922 */
925 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0; 923 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0;
926 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0; 924 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
927 if (unit->mode == UNITMODE_PROFILE) { 925 if (unit->mode == UNITMODE_PROFILE) {
928 if (!unit->profile) 926 if (!unit->profile)
929 syslog(LOG_NOTICE, "Starting unit %s in profile mode, no profile defined.", unit->name); 927 syslog(LOG_NOTICE, "Starting unit `%s' in profile mode, no profile defined.", unit->name);
930 else 928 else
931 syslog(LOG_NOTICE, "Starting unit %s in profile state %s.", unit->name, PROFSTATE[unit->prof_state]); 929 syslog(LOG_NOTICE, "Starting unit `%s' in profile state %s.", unit->name, PROFSTATE[unit->prof_state]);
932 } else if (unit->mode == UNITMODE_BEER) { 930 } else if (unit->mode == UNITMODE_BEER) {
933 syslog(LOG_NOTICE, "Starting unit %s beer cooler at %.1f degrees", unit->name, unit->beer_set); 931 syslog(LOG_NOTICE, "Starting unit `%s' beer cooler at %.1f degrees", unit->name, unit->beer_set);
934 } else if (unit->mode == UNITMODE_FRIDGE) { 932 } else if (unit->mode == UNITMODE_FRIDGE) {
935 syslog(LOG_NOTICE, "Starting unit %s as refridgerator at %.1f degrees", unit->name, unit->fridge_set); 933 syslog(LOG_NOTICE, "Starting unit `%s' as refridgerator at %.1f degrees", unit->name, unit->fridge_set);
936 } else if (unit->mode == UNITMODE_NONE) { 934 } else if (unit->mode == UNITMODE_NONE) {
937 syslog(LOG_NOTICE, "Starting unit %s in inactive state", unit->name); 935 syslog(LOG_NOTICE, "Starting unit `%s' in inactive state", unit->name);
938 } else { 936 } else {
939 syslog(LOG_NOTICE, "Starting unit %s in off state", unit->name); 937 syslog(LOG_NOTICE, "Starting unit `%s' in off state", unit->name);
940 } 938 }
941 } 939 }
942 940
943 #ifdef HAVE_WIRINGPI_H 941 #ifdef HAVE_WIRINGPI_H
944 piLock(LOCK_LCD); 942 piLock(LOCK_LCD);
1377 1375
1378 /* 1376 /*
1379 * Temperature control in this unit 1377 * Temperature control in this unit
1380 */ 1378 */
1381 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE)) { 1379 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE)) {
1382 int usePid = TRUE; 1380
1383 1381 /*
1384 sp = unit->beer_set; 1382 * Set both PID's to their input values.
1385 pv = unit->beer_temperature / 1000.0; 1383 */
1384 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_NONE;
1386 if (unit->mode == UNITMODE_FRIDGE) { 1385 if (unit->mode == UNITMODE_FRIDGE) {
1387 sp = unit->fridge_set; 1386 unit->PID_cool->SetP = unit->PID_heat->SetP = unit->fridge_set;
1388 pv = unit->air_temperature / 1000.0; 1387 unit->PID_cool->Input = unit->PID_heat->Input = unit->air_temperature / 1000.0;
1389 usePid = FALSE; 1388 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_BOO;
1389 } else if (unit->mode == UNITMODE_BEER) {
1390 unit->PID_cool->SetP = unit->PID_heat->SetP = unit->beer_set;
1391 unit->PID_cool->Input = unit->PID_heat->Input = unit->beer_temperature / 1000.0;
1392 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_AUTO;
1390 } else if (unit->mode == UNITMODE_PROFILE) { 1393 } else if (unit->mode == UNITMODE_PROFILE) {
1391 sp = unit->prof_target; 1394 unit->PID_cool->SetP = unit->PID_heat->SetP = unit->prof_target;
1392 } 1395 unit->PID_cool->Input = unit->PID_heat->Input = unit->beer_temperature / 1000.0;
1393 1396 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_AUTO;
1394 P_err = sp - pv; 1397 }
1395 if (P_err < unit->idle_rangeH && P_err > unit->idle_rangeL && usePid == FALSE) { 1398
1396 P_err = 0.0; 1399 /*
1397 } 1400 * PID controller compute
1398 1401 */
1399 if (usePid) { 1402 if (unit->heater_address) {
1400 /* 1403 UpdatePID(unit->PID_heat);
1401 * PID controller compute 1404
1402 */ 1405 if (debug)
1403 pid = (pid_var *)malloc(sizeof(pid_var)); 1406 fprintf(stdout, "Heat: sp=%.2f Input=%.2f InputD=%.2f Err=%.2f Out=%.2f\n",
1404 pid->dState = unit->PID_dState; 1407 unit->PID_heat->SetP, unit->PID_heat->Input, unit->PID_heat->InputD, unit->PID_heat->Err, unit->PID_heat->OutP);
1405 pid->iState = unit->PID_iState; 1408 if (((unit->PID_heat->OutP >= 1) && unit->heater_address) || (seconds == 60) || unit->heater_state) {
1406 pid->iMax = 100.0; 1409 syslog(LOG_NOTICE, "Heat: sp=%.2f Input=%.2f InputD=%.2f Err=%.2f Out=%.2f",
1407 pid->iMin = -100.0; 1410 unit->PID_heat->SetP, unit->PID_heat->Input, unit->PID_heat->InputD, unit->PID_heat->Err, unit->PID_heat->OutP);
1408 pid->pGain = unit->PID_Kp; 1411 }
1409 pid->iGain = unit->PID_Ki; 1412 }
1410 pid->dGain = unit->PID_Kd; 1413 if (unit->cooler_address) {
1411 1414 UpdatePID(unit->PID_cool);
1412 Out = UpdatePID(pid, P_err, pv);
1413
1414 if (Out > 100.0)
1415 Out = 100.0;
1416 if (Out < -100.0)
1417 Out = -100.0;
1418 1415
1419 if (debug) 1416 if (debug)
1420 fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n", 1417 fprintf(stdout, "Cool: sp=%.2f Input=%.2f InputD=%.2f Err=%.2f Out=%.2f\n",
1421 sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out); 1418 unit->PID_cool->SetP, unit->PID_cool->Input, unit->PID_cool->InputD, unit->PID_cool->Err, unit->PID_cool->OutP);
1422 if (((Out >= 1) && unit->heater_address) || ((Out <= -1) && unit->cooler_address) || 1419 if (((unit->PID_cool->OutP >= 1) && unit->cooler_address) || (seconds == 60) || unit->cooler_state) {
1423 (seconds == 60) || unit->heater_state || unit->cooler_state) { 1420 syslog(LOG_NOTICE, "Cool: sp=%.2f Input=%.2f InputD=%.2f Err=%.2f Out=%.2f",
1424 syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f Out=%.2f", 1421 unit->PID_cool->SetP, unit->PID_cool->Input, unit->PID_cool->InputD, unit->PID_cool->Err, unit->PID_cool->OutP);
1425 sp, pv, P_err, unit->PID_dState, unit->PID_iState, Out);
1426 } 1422 }
1427 1423 }
1428 unit->PID_iState = pid->iState; 1424
1429 unit->PID_dState = pid->dState; 1425 if (unit->PID_cool->OutP && unit->PID_heat->OutP) {
1430 free(pid); 1426 syslog(LOG_NOTICE, "Heat and Cool lockdown");
1431 pid = NULL; 1427 unit->PID_cool->OutP = unit->PID_heat->OutP = 0.0;
1432 } else {
1433 /*
1434 * Simple temperature control
1435 */
1436 if (P_err > 0) {
1437 Out = 100.0;
1438 } else if (P_err < 0) {
1439 Out = -100.0;
1440 } else {
1441 Out = 0.0;
1442 }
1443 // if (((Out >= 1) && unit->heater_address) || ((Out <= -1) && unit->cooler_address) ||
1444 // (seconds == 60) || unit->heater_state || unit->cooler_state) {
1445 // syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f Out=%.2f", sp, pv, P_err, Out);
1446 // }
1447 } 1428 }
1448 1429
1449 if (unit->heater_address && ! unit->cooler_state) { 1430 if (unit->heater_address && ! unit->cooler_state) {
1450 if (Out >= 1) { 1431 if (unit->PID_heat->OutP >= 1) {
1451 if (unit->heater_wait < unit->heater_delay) { 1432 if (unit->heater_wait < unit->heater_delay) {
1452 unit->heater_wait++; 1433 unit->heater_wait++;
1453 // syslog(LOG_NOTICE, "heater_wait + %d/%d", unit->heater_wait, unit->heater_delay); 1434 // syslog(LOG_NOTICE, "heater_wait + %d/%d", unit->heater_wait, unit->heater_delay);
1454 } else { 1435 } else {
1455 int power = round(Out); 1436 int power = round(unit->PID_heat->OutP);
1456 if (unit->heater_state != power) { 1437 if (unit->heater_state != power) {
1457 syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->name, unit->heater_state, power); 1438 syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->name, unit->heater_state, power);
1458 unit->heater_state = power; 1439 unit->heater_state = power;
1459 } 1440 }
1460 } 1441 }
1474 else 1455 else
1475 device_out(unit->heater_address, 0); 1456 device_out(unit->heater_address, 0);
1476 } 1457 }
1477 1458
1478 if (unit->cooler_address && ! unit->heater_state) { 1459 if (unit->cooler_address && ! unit->heater_state) {
1479 if (Out <= -1) { 1460 if (unit->PID_cool->OutP >= 1) {
1480 if (unit->cooler_wait < unit->cooler_delay) { 1461 if (unit->cooler_wait < unit->cooler_delay) {
1481 unit->cooler_wait++; 1462 unit->cooler_wait++;
1482 // syslog(LOG_NOTICE, "cooler_wait + %d/%d", unit->cooler_wait, unit->cooler_delay); 1463 // syslog(LOG_NOTICE, "cooler_wait + %d/%d", unit->cooler_wait, unit->cooler_delay);
1483 } else { 1464 } else {
1484 int power = round(0 - Out); 1465 int power = round(unit->PID_cool->OutP);
1485 if (unit->cooler_state != power) { 1466 if (unit->cooler_state != power) {
1486 syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->name, unit->cooler_state, power); 1467 syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->name, unit->cooler_state, power);
1487 unit->cooler_state = power; 1468 unit->cooler_state = power;
1488 } 1469 }
1489 } 1470 }
1531 if (unit->door_state) 1512 if (unit->door_state)
1532 device_out(unit->fan_address, unit->fan_state); 1513 device_out(unit->fan_address, unit->fan_state);
1533 else 1514 else
1534 device_out(unit->fan_address, 0); 1515 device_out(unit->fan_address, 0);
1535 } 1516 }
1536
1537 } else { 1517 } else {
1538 P_err = 0.0; 1518 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_NONE;
1539 unit->PID_iState = 0.0;
1540 unit->PID_dState = 0.0;
1541 } /* fridge beer or profile mode */ 1519 } /* fridge beer or profile mode */
1542 } /* for units */ 1520 } /* for units */
1543 1521
1544 #ifdef HAVE_WIRINGPI_H 1522 #ifdef HAVE_WIRINGPI_H
1545 piLock(LOCK_MENU); 1523 piLock(LOCK_MENU);

mercurial