heater.c: Enable more anti-windup with PID_CONDITIONAL_INTEGRATION.

This commit is contained in:
David Forrest 2014-03-23 14:14:10 -04:00 committed by Markus Hitter
parent 707c4f35de
commit 23679855a0
2 changed files with 18 additions and 6 deletions

View File

@ -481,6 +481,14 @@ BANG_BANG_OFF
PWM value for 'off' PWM value for 'off'
*/ */
// #define BANG_BANG_OFF 45 // #define BANG_BANG_OFF 45
/** \def PID_CONDITIONAL_INTEGRATION
PID_CONDITIONAL_INTEGRATION
Controls 'integral windup' by preventing the integral term from accumulating error if the heater output is saturated high/low by
the other terms in the PID calculation. This is in addition to M133/I_LIMIT mechanism, and can help prevent overshoot in cases of
large setpoint changes which may overfill the integral term.
Costs 50 bytes.
*/
//#define PID_CONDITIONAL_INTEGRATION
/** /**
move buffer size, in number of moves move buffer size, in number of moves

View File

@ -321,22 +321,26 @@ void heater_tick(heater_t h, temp_type_t type, uint16_t current_temp, uint16_t t
// combine factors // combine factors
int32_t pid_output_intermed = ( // Units: counts int32_t pid_output_intermed = ( // Units: counts
( (
(((int32_t) heater_p) * heaters_pid[h].p_factor) + (((int32_t) heater_p) * heaters_pid[h].p_factor) +
(((int32_t) heaters_runtime[h].heater_i) * heaters_pid[h].i_factor) + (((int32_t) heaters_runtime[h].heater_i) * heaters_pid[h].i_factor) +
(((int32_t) heater_d) * heaters_pid[h].d_factor) (((int32_t) heater_d) * heaters_pid[h].d_factor)
) / PID_SCALE ) / PID_SCALE
); );
// rebase and limit factors // rebase and limit factors
if (pid_output_intermed > 255) { if (pid_output_intermed > 255) {
#ifdef PID_CONDITIONAL_INTEGRATION
if (t_error > 0) if (t_error > 0)
heaters_runtime[h].heater_i -= t_error; // un-integrate heaters_runtime[h].heater_i -= t_error; // un-integrate
#endif
pid_output = 255; pid_output = 255;
} }
else if (pid_output_intermed < 0) { else if (pid_output_intermed < 0) {
#ifdef PID_CONDITIONAL_INTEGRATION
if (t_error < 0) if (t_error < 0)
heaters_runtime[h].heater_i -= t_error; // un-integrate heaters_runtime[h].heater_i -= t_error; // un-integrate
#endif
pid_output = 0; pid_output = 0;
} }
else else