diff -r 308f6a436779 -r c92651a54969 thermferm/thermferm.c --- a/thermferm/thermferm.c Thu May 14 22:03:35 2015 +0200 +++ b/thermferm/thermferm.c Sat May 16 17:39:30 2015 +0200 @@ -841,7 +841,6 @@ prof_step *step; int rc, run = 1, seconds = 0, minutes = 0, temp, deviation; int run_seconds, run_minutes, run_hours, tot_minutes; - float sp, pv, P_err = 0.0, Out; #ifdef HAVE_WIRINGPI_H struct tm *tm; int row, key; @@ -850,7 +849,6 @@ #endif int current_step, valid_step, time_until_now; float previous_target; - pid_var *pid; if (lockprog((char *)"thermferm")) { @@ -926,17 +924,17 @@ unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0; if (unit->mode == UNITMODE_PROFILE) { if (!unit->profile) - syslog(LOG_NOTICE, "Starting unit %s in profile mode, no profile defined.", unit->name); + syslog(LOG_NOTICE, "Starting unit `%s' in profile mode, no profile defined.", unit->name); else - syslog(LOG_NOTICE, "Starting unit %s in profile state %s.", unit->name, PROFSTATE[unit->prof_state]); + syslog(LOG_NOTICE, "Starting unit `%s' in profile state %s.", unit->name, PROFSTATE[unit->prof_state]); } else if (unit->mode == UNITMODE_BEER) { - syslog(LOG_NOTICE, "Starting unit %s beer cooler at %.1f degrees", unit->name, unit->beer_set); + syslog(LOG_NOTICE, "Starting unit `%s' beer cooler at %.1f degrees", unit->name, unit->beer_set); } else if (unit->mode == UNITMODE_FRIDGE) { - syslog(LOG_NOTICE, "Starting unit %s as refridgerator at %.1f degrees", unit->name, unit->fridge_set); + syslog(LOG_NOTICE, "Starting unit `%s' as refridgerator at %.1f degrees", unit->name, unit->fridge_set); } else if (unit->mode == UNITMODE_NONE) { - syslog(LOG_NOTICE, "Starting unit %s in inactive state", unit->name); + syslog(LOG_NOTICE, "Starting unit `%s' in inactive state", unit->name); } else { - syslog(LOG_NOTICE, "Starting unit %s in off state", unit->name); + syslog(LOG_NOTICE, "Starting unit `%s' in off state", unit->name); } } @@ -1379,80 +1377,63 @@ * Temperature control in this unit */ if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE)) { - int usePid = TRUE; - sp = unit->beer_set; - pv = unit->beer_temperature / 1000.0; + /* + * Set both PID's to their input values. + */ + unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_NONE; if (unit->mode == UNITMODE_FRIDGE) { - sp = unit->fridge_set; - pv = unit->air_temperature / 1000.0; - usePid = FALSE; + unit->PID_cool->SetP = unit->PID_heat->SetP = unit->fridge_set; + unit->PID_cool->Input = unit->PID_heat->Input = unit->air_temperature / 1000.0; + unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_BOO; + } else if (unit->mode == UNITMODE_BEER) { + unit->PID_cool->SetP = unit->PID_heat->SetP = unit->beer_set; + unit->PID_cool->Input = unit->PID_heat->Input = unit->beer_temperature / 1000.0; + unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_AUTO; } else if (unit->mode == UNITMODE_PROFILE) { - sp = unit->prof_target; - } - - P_err = sp - pv; - if (P_err < unit->idle_rangeH && P_err > unit->idle_rangeL && usePid == FALSE) { - P_err = 0.0; + unit->PID_cool->SetP = unit->PID_heat->SetP = unit->prof_target; + unit->PID_cool->Input = unit->PID_heat->Input = unit->beer_temperature / 1000.0; + unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_AUTO; } - if (usePid) { - /* - * PID controller compute - */ - pid = (pid_var *)malloc(sizeof(pid_var)); - pid->dState = unit->PID_dState; - pid->iState = unit->PID_iState; - pid->iMax = 100.0; - pid->iMin = -100.0; - pid->pGain = unit->PID_Kp; - pid->iGain = unit->PID_Ki; - pid->dGain = unit->PID_Kd; + /* + * PID controller compute + */ + if (unit->heater_address) { + UpdatePID(unit->PID_heat); - Out = UpdatePID(pid, P_err, pv); - - if (Out > 100.0) - Out = 100.0; - if (Out < -100.0) - Out = -100.0; + if (debug) + fprintf(stdout, "Heat: sp=%.2f Input=%.2f InputD=%.2f Err=%.2f Out=%.2f\n", + unit->PID_heat->SetP, unit->PID_heat->Input, unit->PID_heat->InputD, unit->PID_heat->Err, unit->PID_heat->OutP); + if (((unit->PID_heat->OutP >= 1) && unit->heater_address) || (seconds == 60) || unit->heater_state) { + syslog(LOG_NOTICE, "Heat: sp=%.2f Input=%.2f InputD=%.2f Err=%.2f Out=%.2f", + unit->PID_heat->SetP, unit->PID_heat->Input, unit->PID_heat->InputD, unit->PID_heat->Err, unit->PID_heat->OutP); + } + } + if (unit->cooler_address) { + UpdatePID(unit->PID_cool); if (debug) - fprintf(stdout, "sp=%.2f pv=%.2f dState=%.2f P_err=%.2f iState=%.2f Out=%.2f\n", - sp, pv, unit->PID_dState, P_err, unit->PID_iState, Out); - if (((Out >= 1) && unit->heater_address) || ((Out <= -1) && unit->cooler_address) || - (seconds == 60) || unit->heater_state || unit->cooler_state) { - syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f dState=%.2f iState=%.2f Out=%.2f", - sp, pv, P_err, unit->PID_dState, unit->PID_iState, Out); + fprintf(stdout, "Cool: sp=%.2f Input=%.2f InputD=%.2f Err=%.2f Out=%.2f\n", + unit->PID_cool->SetP, unit->PID_cool->Input, unit->PID_cool->InputD, unit->PID_cool->Err, unit->PID_cool->OutP); + if (((unit->PID_cool->OutP >= 1) && unit->cooler_address) || (seconds == 60) || unit->cooler_state) { + syslog(LOG_NOTICE, "Cool: sp=%.2f Input=%.2f InputD=%.2f Err=%.2f Out=%.2f", + unit->PID_cool->SetP, unit->PID_cool->Input, unit->PID_cool->InputD, unit->PID_cool->Err, unit->PID_cool->OutP); } + } - unit->PID_iState = pid->iState; - unit->PID_dState = pid->dState; - free(pid); - pid = NULL; - } else { - /* - * Simple temperature control - */ - if (P_err > 0) { - Out = 100.0; - } else if (P_err < 0) { - Out = -100.0; - } else { - Out = 0.0; - } -// if (((Out >= 1) && unit->heater_address) || ((Out <= -1) && unit->cooler_address) || -// (seconds == 60) || unit->heater_state || unit->cooler_state) { -// syslog(LOG_NOTICE, "sp=%.2f pv=%.2f P_err=%.2f Out=%.2f", sp, pv, P_err, Out); -// } + if (unit->PID_cool->OutP && unit->PID_heat->OutP) { + syslog(LOG_NOTICE, "Heat and Cool lockdown"); + unit->PID_cool->OutP = unit->PID_heat->OutP = 0.0; } if (unit->heater_address && ! unit->cooler_state) { - if (Out >= 1) { + if (unit->PID_heat->OutP >= 1) { if (unit->heater_wait < unit->heater_delay) { unit->heater_wait++; // syslog(LOG_NOTICE, "heater_wait + %d/%d", unit->heater_wait, unit->heater_delay); } else { - int power = round(Out); + int power = round(unit->PID_heat->OutP); if (unit->heater_state != power) { syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->name, unit->heater_state, power); unit->heater_state = power; @@ -1476,12 +1457,12 @@ } if (unit->cooler_address && ! unit->heater_state) { - if (Out <= -1) { + if (unit->PID_cool->OutP >= 1) { if (unit->cooler_wait < unit->cooler_delay) { unit->cooler_wait++; // syslog(LOG_NOTICE, "cooler_wait + %d/%d", unit->cooler_wait, unit->cooler_delay); } else { - int power = round(0 - Out); + int power = round(unit->PID_cool->OutP); if (unit->cooler_state != power) { syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->name, unit->cooler_state, power); unit->cooler_state = power; @@ -1533,11 +1514,8 @@ else device_out(unit->fan_address, 0); } - } else { - P_err = 0.0; - unit->PID_iState = 0.0; - unit->PID_dState = 0.0; + unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_NONE; } /* fridge beer or profile mode */ } /* for units */