317 } else { |
317 } else { |
318 syslog(LOG_NOTICE, "Starting unit %s in off state", unit->name); |
318 syslog(LOG_NOTICE, "Starting unit %s in off state", unit->name); |
319 } |
319 } |
320 } |
320 } |
321 |
321 |
322 #ifdef HAVE_WIRINGPI_H |
|
323 rc = piThreadCreate(my_units_loop); |
|
324 #else |
|
325 rc = pthread_create(&threads[t], NULL, my_units_loop, (void *)t ); |
|
326 #endif |
|
327 if (rc) { |
|
328 fprintf(stderr, "my_units_loop thread didn't start rc=%d\n", rc); |
|
329 syslog(LOG_NOTICE, "my_units_loop thread didn't start rc=%d", rc); |
|
330 #ifndef HAVE_WIRINGPI_H |
|
331 } else { |
|
332 t++; |
|
333 #endif |
|
334 } |
|
335 |
322 |
336 #ifdef HAVE_WIRINGPI_H |
323 #ifdef HAVE_WIRINGPI_H |
337 lcd_buf_write(1, (char *)" ThermFerm "); |
324 lcd_buf_write(1, (char *)" ThermFerm "); |
338 lcd_buf_write(2, (char *)" Version %s ", VERSION); |
325 lcd_buf_write(2, (char *)" Version %s ", VERSION); |
339 #endif |
326 #endif |
363 lcd_buf_write(row++, " %02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); |
350 lcd_buf_write(row++, " %02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); |
364 #endif |
351 #endif |
365 |
352 |
366 for (unit = Config.units; unit; unit = unit->next) { |
353 for (unit = Config.units; unit; unit = unit->next) { |
367 #ifdef HAVE_WIRINGPI_H |
354 #ifdef HAVE_WIRINGPI_H |
368 lcd_buf_write(row++, "Unit %s ", unit->name); |
355 lcd_buf_write(row++, "Unit %s ", unit->name); |
369 lcd_buf_write(row++, "Mode %s ", UNITMODE[unit->mode]); |
356 lcd_buf_write(row++, "Mode %s ", UNITMODE[unit->mode]); |
370 if (unit->air_address) { |
357 if (unit->air_address) { |
371 lcd_buf_write(row++, " Air %.3f %cC ", unit->air_temperature / 1000.0, 0xdf); |
358 lcd_buf_write(row++, " Air %.3f %cC ", unit->air_temperature / 1000.0, 0xdf); |
372 } |
359 } |
373 if (unit->beer_address) { |
360 if (unit->beer_address) { |
374 lcd_buf_write(row++, "Beer %.3f %cC ", unit->beer_temperature / 1000.0, 0xdf); |
361 lcd_buf_write(row++, "Beer %.3f %cC ", unit->beer_temperature / 1000.0, 0xdf); |
375 } |
362 } |
376 #endif |
363 #endif |
377 |
364 |
378 if (unit->air_address) { |
365 if (unit->air_address) { |
379 rc = read_w1_28(unit->air_address, &temp); |
366 rc = read_w1_28(unit->air_address, &temp); |
380 if (rc == DEVPRESENT_YES) { |
367 if (rc == DEVPRESENT_YES) { |
433 piddelay++; |
429 piddelay++; |
434 if (piddelay == 15) { |
430 if (piddelay == 15) { |
435 piddelay = 0; |
431 piddelay = 0; |
436 |
432 |
437 for (unit = Config.units; unit; unit = unit->next) { |
433 for (unit = Config.units; unit; unit = unit->next) { |
438 if (unit->mode != UNITMODE_OFF) { |
434 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE)) { |
439 |
435 /* |
440 if (unit->mode != UNITMODE_NONE) { |
436 * PID controller |
441 /* |
437 */ |
442 * PID controller |
438 sp = unit->beer_set; |
443 */ |
439 pv = unit->beer_temperature / 1000.0; |
444 sp = unit->beer_set; |
440 if (unit->mode == UNITMODE_FRIDGE) { |
445 pv = unit->beer_temperature / 1000.0; |
|
446 if (unit->mode == UNITMODE_FRIDGE) { |
|
447 sp = unit->fridge_set; |
441 sp = unit->fridge_set; |
448 pv = unit->air_temperature / 1000.0; |
442 pv = unit->air_temperature / 1000.0; |
449 } else if (unit->mode == UNITMODE_PROFILE) { |
443 } else if (unit->mode == UNITMODE_PROFILE) { |
450 sp = unit->prof_target; |
444 sp = unit->prof_target; |
451 } |
445 } |
452 |
446 |
453 unit->PID_err_old = err; |
447 unit->PID_err_old = err; |
454 err = sp - pv; |
448 err = sp - pv; |
455 if (err < unit->idle_rangeH && err > unit->idle_rangeL) |
449 if (err < unit->idle_rangeH && err > unit->idle_rangeL) |
456 err = 0; |
450 err = 0; |
457 P_err = err; |
451 P_err = err; |
458 I_err += unit->PID_err_old; |
452 I_err += unit->PID_err_old; |
459 D_err = err - unit->PID_err_old; |
453 D_err = err - unit->PID_err_old; |
460 |
454 |
461 /* |
455 /* |
462 * A postive value means heating, a negative value cooling. |
456 * A postive value means heating, a negative value cooling. |
463 */ |
457 */ |
464 Out = (5.0*P_err) + (0.25*I_err) + (1.5*D_err); |
458 Out = (5.0*P_err) + (0.25*I_err) + (1.5*D_err); |
465 // Kp 0.1 Ki 0.3 Kd 0.02 |
459 // Kp 0.1 Ki 0.3 Kd 0.02 |
466 if (debug) |
460 if (debug) |
467 fprintf(stdout, "sp=%.2f pv=%.2f err_old=%.2f err=%.2f P_err=%.2f I_err=%.2f D_err=%.2f Out=%.2f\n", |
461 fprintf(stdout, "sp=%.2f pv=%.2f err_old=%.2f err=%.2f P_err=%.2f I_err=%.2f D_err=%.2f Out=%.2f\n", |
468 sp, pv, unit->PID_err_old, err, P_err, I_err, D_err, Out); |
462 sp, pv, unit->PID_err_old, err, P_err, I_err, D_err, Out); |
469 if (unit->heater_address) { |
463 if (unit->heater_address) { |
470 if (Out >= 2) |
464 if (Out >= 2) |
471 unit->heater_state = 100; |
465 unit->heater_state = 100; |
472 else |
466 else |
473 unit->heater_state = 0; |
467 unit->heater_state = 0; |
474 device_out(unit->heater_address, unit->heater_state); |
468 device_out(unit->heater_address, unit->heater_state); |
475 } |
469 } |
476 if (unit->cooler_address) { |
470 if (unit->cooler_address) { |
477 if (Out <= -2) |
471 if (Out <= -2) |
478 unit->cooler_state = 100; |
472 unit->cooler_state = 100; |
479 else |
473 else |
480 unit->cooler_state = 0; |
474 unit->cooler_state = 0; |
481 device_out(unit->cooler_address, unit->cooler_state); |
475 device_out(unit->cooler_address, unit->cooler_state); |
482 } |
476 } |
483 } |
477 } else { |
|
478 err = 0.0; |
|
479 I_err = 0.0; |
|
480 unit->PID_err_old = 0.0; |
484 } |
481 } |
485 } |
482 } |
486 } |
483 } |
487 |
484 |
488 if (seconds == 60) { |
485 if (seconds == 60) { |