heater.c: add a hysteresis when using BANG_BANG.

Before, the heater would turn off and on at each tiny temperature
fluctuation. Or better: at every tiny analog voltage fluctuation.
This commit is contained in:
Markus Hitter 2014-08-25 19:51:33 +02:00
parent f26623d173
commit e0ee76b54e
2 changed files with 13 additions and 7 deletions

View File

@ -283,7 +283,8 @@ void heater_init() {
\param target_temp the temperature we're trying to achieve \param target_temp the temperature we're trying to achieve
*/ */
void heater_tick(heater_t h, temp_type_t type, uint16_t current_temp, uint16_t target_temp) { void heater_tick(heater_t h, temp_type_t type, uint16_t current_temp, uint16_t target_temp) {
uint8_t pid_output; // Static, so it's not mandatory to calculate a new value, see BANG_BANG.
static uint8_t pid_output;
#ifndef BANG_BANG #ifndef BANG_BANG
int16_t heater_p; int16_t heater_p;
@ -347,10 +348,11 @@ void heater_tick(heater_t h, temp_type_t type, uint16_t current_temp, uint16_t t
sersendf_P(PSTR("T{E:%d, P:%d * %ld = %ld / I:%d * %ld = %ld / D:%d * %ld = %ld # O: %ld = %u}\n"), t_error, heater_p, heaters_pid[h].p_factor, (int32_t) heater_p * heaters_pid[h].p_factor / PID_SCALE, heaters_runtime[h].heater_i, heaters_pid[h].i_factor, (int32_t) heaters_runtime[h].heater_i * heaters_pid[h].i_factor / PID_SCALE, heater_d, heaters_pid[h].d_factor, (int32_t) heater_d * heaters_pid[h].d_factor / PID_SCALE, pid_output_intermed, pid_output); sersendf_P(PSTR("T{E:%d, P:%d * %ld = %ld / I:%d * %ld = %ld / D:%d * %ld = %ld # O: %ld = %u}\n"), t_error, heater_p, heaters_pid[h].p_factor, (int32_t) heater_p * heaters_pid[h].p_factor / PID_SCALE, heaters_runtime[h].heater_i, heaters_pid[h].i_factor, (int32_t) heaters_runtime[h].heater_i * heaters_pid[h].i_factor / PID_SCALE, heater_d, heaters_pid[h].d_factor, (int32_t) heater_d * heaters_pid[h].d_factor / PID_SCALE, pid_output_intermed, pid_output);
#endif #endif
#else #else
if (current_temp >= target_temp) if (current_temp >= target_temp + (TEMP_HYSTERESIS))
pid_output = BANG_BANG_OFF; pid_output = BANG_BANG_OFF;
else //BANG_BANG else if (current_temp <= target_temp - (TEMP_HYSTERESIS))
pid_output = BANG_BANG_ON; pid_output = BANG_BANG_ON;
// else keep pid_output
#endif #endif
#ifdef HEATER_SANITY_CHECK #ifdef HEATER_SANITY_CHECK

View File

@ -320,11 +320,15 @@
* * * *
\***************************************************************************/ \***************************************************************************/
/** /** \def TEMP_HYSTERESIS
TEMP_HYSTERESIS: actual temperature must be target +/- hysteresis before target temperature can be achieved.
Unit is degree Celsius. Actual temperature must be target +/- this hysteresis before target
temperature is considered to be achieved. Also, BANG_BANG tries to stay
within half of this hysteresis.
Unit: degree Celsius
*/ */
#define TEMP_HYSTERESIS 20 #define TEMP_HYSTERESIS 10
/** /**
TEMP_RESIDENCY_TIME: actual temperature must be close to target (within TEMP_RESIDENCY_TIME: actual temperature must be close to target (within