230 { |
230 { |
231 char buf[1024], *filename, target[40], heater[40], cooler[40], fan[40], door[40]; |
231 char buf[1024], *filename, target[40], heater[40], cooler[40], fan[40], door[40]; |
232 time_t now, last = (time_t)0; |
232 time_t now, last = (time_t)0; |
233 units_list *unit; |
233 units_list *unit; |
234 int rc, run = 1, seconds = 0, minutes = 0; |
234 int rc, run = 1, seconds = 0, minutes = 0; |
235 float err = 0.0, sp, pv, P_err, I_err, D_err, Out; |
235 float err = 0.0, sp, pv, P_err, I_err = 0.0, D_err, Out; |
236 #ifdef HAVE_WIRINGPI_H |
236 #ifdef HAVE_WIRINGPI_H |
237 struct tm *tm; |
237 struct tm *tm; |
238 int row; |
238 int row; |
239 #else |
239 #else |
240 long t = 0; |
240 long t = 0; |
344 seconds = 0; |
344 seconds = 0; |
345 |
345 |
346 for (unit = Config.units; unit; unit = unit->next) { |
346 for (unit = Config.units; unit; unit = unit->next) { |
347 if (unit->mode != UNITMODE_OFF) { |
347 if (unit->mode != UNITMODE_OFF) { |
348 |
348 |
349 if (0) { |
349 if (unit->mode != UNITMODE_NONE) { |
350 /* |
350 /* |
351 * PID controller |
351 * PID controller |
352 */ |
352 */ |
353 sp = unit->beer_set; |
353 sp = unit->beer_set; |
354 pv = unit->beer_temperature; |
354 pv = unit->beer_temperature / 1000.0; |
355 if (unit->mode == UNITMODE_FRIDGE) { |
355 if (unit->mode == UNITMODE_FRIDGE) { |
356 sp = unit->fridge_set; |
356 sp = unit->fridge_set; |
357 pv = unit->air_temperature; |
357 pv = unit->air_temperature / 1000.0; |
358 } else if (unit->mode == UNITMODE_PROFILE) { |
358 } else if (unit->mode == UNITMODE_PROFILE) { |
359 sp = unit->prof_target; |
359 sp = unit->prof_target; |
360 } |
360 } |
361 |
361 |
362 unit->PID_err_old = err; |
362 unit->PID_err_old = err; |
365 err = 0; |
365 err = 0; |
366 P_err = err; |
366 P_err = err; |
367 I_err += unit->PID_err_old; |
367 I_err += unit->PID_err_old; |
368 D_err = err - unit->PID_err_old; |
368 D_err = err - unit->PID_err_old; |
369 |
369 |
370 Out = (0.1*P_err) + (0.3*I_err) + (0.02*D_err); |
370 /* |
371 // Kp Ki Kd |
371 * A postive value means heating, a negative value cooling. |
|
372 */ |
|
373 Out = (5.0*P_err) + (0.25*I_err) + (-1.5*D_err); |
|
374 // Kp 0.1 Ki 0.3 Kd 0.02 |
372 if (debug) |
375 if (debug) |
373 fprintf(stdout, "sp=%.2f pv=%.2f err_old=%.2f err=%.2f P_err=%.2f I_err=%.2f D_err=%.2f Out=%.2f\n", |
376 fprintf(stdout, "sp=%.2f pv=%.2f err_old=%.2f err=%.2f P_err=%.2f I_err=%.2f D_err=%.2f Out=%.2f\n", |
374 sp, pv, unit->PID_err_old, err, P_err, I_err, D_err, Out); |
377 sp, pv, unit->PID_err_old, err, P_err, I_err, D_err, Out); |
|
378 if (unit->heater_address) { |
|
379 if (Out >= 2) |
|
380 unit->heater_state = 100; |
|
381 else |
|
382 unit->heater_state = 0; |
|
383 device_out(unit->heater_address, unit->heater_state); |
|
384 } |
|
385 if (unit->cooler_address) { |
|
386 if (Out <= -2) |
|
387 unit->cooler_state = 100; |
|
388 else |
|
389 unit->cooler_state = 0; |
|
390 device_out(unit->cooler_address, unit->cooler_state); |
|
391 } |
375 } |
392 } |
376 |
393 |
377 snprintf(target, 39, "NA"); |
394 snprintf(target, 39, "NA"); |
378 snprintf(heater, 39, "NA"); |
395 snprintf(heater, 39, "NA"); |
379 snprintf(cooler, 39, "NA"); |
396 snprintf(cooler, 39, "NA"); |