thermferm/thermferm.c

changeset 311
f3b0e9ac9bcb
parent 310
53774295e14a
child 312
7b0f819a3805
equal deleted inserted replaced
310:53774295e14a 311:f3b0e9ac9bcb
834 units_list *unit; 834 units_list *unit;
835 profiles_list *profile; 835 profiles_list *profile;
836 prof_step *step; 836 prof_step *step;
837 int rc, run = 1, seconds = 0, minutes = 0, piddelay = 0, temp, deviation; 837 int rc, run = 1, seconds = 0, minutes = 0, piddelay = 0, temp, deviation;
838 int run_seconds, run_minutes, run_hours, tot_minutes; 838 int run_seconds, run_minutes, run_hours, tot_minutes;
839 float err = 0.0, sp, pv, P_err, D_err, Out; 839 float sp, pv, P_err = 0.0, D_err, Out;
840 #ifdef HAVE_WIRINGPI_H 840 #ifdef HAVE_WIRINGPI_H
841 struct tm *tm; 841 struct tm *tm;
842 int row, key; 842 int row, key;
843 #else 843 #else
844 long t = 0; 844 long t = 0;
1301 } 1301 }
1302 #endif 1302 #endif
1303 } 1303 }
1304 1304
1305 piddelay++; 1305 piddelay++;
1306 if (piddelay == 15) { 1306 if (piddelay == 5) {
1307 piddelay = 0; 1307 piddelay = 0;
1308 1308
1309 for (unit = Config.units; unit; unit = unit->next) { 1309 for (unit = Config.units; unit; unit = unit->next) {
1310 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE)) { 1310 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE)) {
1311 /* 1311 /*
1318 pv = unit->air_temperature / 1000.0; 1318 pv = unit->air_temperature / 1000.0;
1319 } else if (unit->mode == UNITMODE_PROFILE) { 1319 } else if (unit->mode == UNITMODE_PROFILE) {
1320 sp = unit->prof_target; 1320 sp = unit->prof_target;
1321 } 1321 }
1322 1322
1323 // unit->PID_err_old = err; 1323 P_err = sp - pv;
1324 err = sp - pv; 1324 if (P_err < unit->idle_rangeH && P_err > unit->idle_rangeL) {
1325 if (err < unit->idle_rangeH && err > unit->idle_rangeL) { 1325 P_err = 0.0;
1326 err = 0; 1326 }
1327 unit->PID_I_err -= unit->PID_err_old; 1327 unit->PID_I_err += (unit->PID_Ki * P_err);
1328 } else { 1328 // unit->PID_I_err -= unit->PID_err_old;
1329 unit->PID_I_err += unit->PID_err_old; 1329 // } else {
1330 } 1330 // unit->PID_I_err += unit->PID_err_old;
1331 /* Limit intergral error */ 1331 // }
1332 if (unit->PID_I_err < -10.0) 1332 /* Limit integral error */
1333 unit->PID_I_err = -10.0; 1333 if (unit->PID_I_err < -100.0)
1334 if (unit->PID_I_err > 10.0) 1334 unit->PID_I_err = -100.0;
1335 unit->PID_I_err = 10.0; 1335 if (unit->PID_I_err > 100.0)
1336 P_err = err; 1336 unit->PID_I_err = 100.0;
1337 D_err = err - unit->PID_err_old; 1337 D_err = P_err - unit->PID_err_old;
1338 1338
1339 /* 1339 /*
1340 * A postive value means heating, a negative value cooling. 1340 * A postive value means heating, a negative value cooling.
1341 * Start with Kp, Kd and Ki set to 0. 1341 * Start with Kp, Kd and Ki set to 0.
1342 * Increase Kp until small oscillation. 1342 * Increase Kp until small oscillation.
1343 * Increase Kd until a little damping. 1343 * Increase Kd until a little damping.
1344 * Increase Ki after Kp and Kd are set until longterm convergence. 1344 * Increase Ki after Kp and Kd are set until longterm convergence.
1345 */ 1345 */
1346 Out = (10.0*P_err) + (0.0*unit->PID_I_err) + (0.0*D_err); 1346 Out = (unit->PID_Kp * P_err) + unit->PID_I_err - (unit->PID_Kd * D_err);
1347 //Out = (10.0*P_err) + (0.1*unit->PID_I_err) + (5*D_err); 1347 if (Out > 100.0)
1348 // Kp 0.1 Ki 0.3 Kd 0.02 1348 Out = 100.0;
1349 if (err != 0.0) { 1349 if (Out < -100.0)
1350 Out = -100.0;
1351 // if (P_err != 0.0) {
1350 if (debug) 1352 if (debug)
1351 fprintf(stdout, "sp=%.2f pv=%.2f err_old=%.2f err=%.2f P_err=%.2f I_err=%.2f D_err=%.2f Out=%.2f\n", 1353 fprintf(stdout, "sp=%.2f pv=%.2f err_old=%.2f P_err=%.2f I_err=%.2f D_err=%.2f Out=%.2f\n",
1352 sp, pv, unit->PID_err_old, err, P_err, unit->PID_I_err, D_err, Out); 1354 sp, pv, unit->PID_err_old, P_err, unit->PID_I_err, D_err, Out);
1353 syslog(LOG_NOTICE, "sp=%.2f pv=%.2f err_old=%.2f err=%.2f P_err=%.2f I_err=%.2f D_err=%.2f Out=%.2f", 1355 syslog(LOG_NOTICE, "sp=%.2f pv=%.2f err_old=%.2f P_err=%.2f I_err=%.2f D_err=%.2f Out=%.2f",
1354 sp, pv, unit->PID_err_old, err, P_err, unit->PID_I_err, D_err, Out); 1356 sp, pv, unit->PID_err_old, P_err, unit->PID_I_err, D_err, Out);
1355 } 1357 // }
1356 unit->PID_err_old = err; 1358 unit->PID_err_old = P_err;
1357 1359
1358 if (unit->heater_address) { 1360 if (unit->heater_address) {
1359 if (Out >= 2) { 1361 if (Out >= 1) {
1360 if (unit->heater_wait < unit->heater_delay) { 1362 if (unit->heater_wait < unit->heater_delay) {
1361 unit->heater_wait++; 1363 unit->heater_wait++;
1362 syslog(LOG_NOTICE, "heater_wait + %d/%d", unit->heater_wait, unit->heater_delay); 1364 syslog(LOG_NOTICE, "heater_wait + %d/%d", unit->heater_wait, unit->heater_delay);
1363 } else { 1365 } else {
1364 if (! unit->heater_state && ! unit->cooler_state) { 1366 if (! unit->heater_state && ! unit->cooler_state) {
1378 } 1380 }
1379 } 1381 }
1380 device_out(unit->heater_address, unit->heater_state); 1382 device_out(unit->heater_address, unit->heater_state);
1381 } 1383 }
1382 if (unit->cooler_address) { 1384 if (unit->cooler_address) {
1383 if (Out <= -2) { 1385 if (Out <= -1) {
1384 if (unit->cooler_wait < unit->cooler_delay) { 1386 if (unit->cooler_wait < unit->cooler_delay) {
1385 unit->cooler_wait++; 1387 unit->cooler_wait++;
1386 syslog(LOG_NOTICE, "cooler_wait + %d/%d", unit->cooler_wait, unit->cooler_delay); 1388 syslog(LOG_NOTICE, "cooler_wait + %d/%d", unit->cooler_wait, unit->cooler_delay);
1387 } else { 1389 } else {
1388 if (! unit->cooler_state && ! unit->heater_state) { 1390 if (! unit->cooler_state && ! unit->heater_state) {
1422 unit->fan_state = 0; 1424 unit->fan_state = 0;
1423 } 1425 }
1424 device_out(unit->fan_address, unit->fan_state); 1426 device_out(unit->fan_address, unit->fan_state);
1425 } 1427 }
1426 } else { 1428 } else {
1427 err = 0.0; 1429 P_err = 0.0;
1428 unit->PID_I_err = 0.0; 1430 unit->PID_I_err = 0.0;
1429 unit->PID_err_old = 0.0; 1431 unit->PID_err_old = 0.0;
1430 } 1432 }
1431 } 1433 }
1432 } 1434 }

mercurial