✨ Temperature variance monitor (#23373)
This commit is contained in:
committed by
Scott Lahteine
parent
b435487da7
commit
2ca1d844d7
@ -196,6 +196,7 @@
|
||||
Temperature thermalManager;
|
||||
|
||||
PGMSTR(str_t_thermal_runaway, STR_T_THERMAL_RUNAWAY);
|
||||
PGMSTR(str_t_temp_malfunction, STR_T_MALFUNCTION);
|
||||
PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED);
|
||||
|
||||
/**
|
||||
@ -2570,14 +2571,30 @@ void Temperature::init() {
|
||||
);
|
||||
*/
|
||||
|
||||
// If the heater idle timeout expires, restart
|
||||
if (TERN0(HEATER_IDLE_HANDLER, heater_idle[idle_index].timed_out)) {
|
||||
state = TRInactive;
|
||||
running_temp = 0;
|
||||
}
|
||||
else if (running_temp != target) { // If the target temperature changes, restart
|
||||
running_temp = target;
|
||||
state = target > 0 ? TRFirstHeating : TRInactive;
|
||||
#if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR)
|
||||
if (state == TRMalfunction) { // temperature invariance may continue, regardless of heater state
|
||||
variance += ABS(current - last_temp); // no need for detection window now, a single change in variance is enough
|
||||
last_temp = current;
|
||||
if (!NEAR_ZERO(variance)) {
|
||||
variance_timer = millis() + SEC_TO_MS(period_seconds);
|
||||
variance = 0.0;
|
||||
state = TRStable; // resume from where we detected the problem
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (TERN1(THERMAL_PROTECTION_VARIANCE_MONITOR, state != TRMalfunction)) {
|
||||
// If the heater idle timeout expires, restart
|
||||
if (TERN0(HEATER_IDLE_HANDLER, heater_idle[idle_index].timed_out)) {
|
||||
state = TRInactive;
|
||||
running_temp = 0;
|
||||
TERN_(THERMAL_PROTECTION_VARIANCE_MONITOR, variance_timer = 0);
|
||||
}
|
||||
else if (running_temp != target) { // If the target temperature changes, restart
|
||||
running_temp = target;
|
||||
state = target > 0 ? TRFirstHeating : TRInactive;
|
||||
TERN_(THERMAL_PROTECTION_VARIANCE_MONITOR, variance_timer = 0);
|
||||
}
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
@ -2610,6 +2627,22 @@ void Temperature::init() {
|
||||
|
||||
const millis_t now = millis();
|
||||
|
||||
#if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR)
|
||||
if (PENDING(now, variance_timer)) {
|
||||
variance += ABS(current - last_temp);
|
||||
last_temp = current;
|
||||
}
|
||||
else {
|
||||
if (NEAR_ZERO(variance) && variance_timer) { // valid variance monitoring window
|
||||
state = TRMalfunction;
|
||||
break;
|
||||
}
|
||||
variance_timer = now + SEC_TO_MS(period_seconds);
|
||||
variance = 0.0;
|
||||
last_temp = current;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (current >= running_temp - hysteresis_degc) {
|
||||
timer = now + SEC_TO_MS(period_seconds);
|
||||
break;
|
||||
@ -2622,6 +2655,12 @@ void Temperature::init() {
|
||||
case TRRunaway:
|
||||
TERN_(HAS_DWIN_E3V2_BASIC, DWIN_Popup_Temperature(0));
|
||||
_temp_error(heater_id, FPSTR(str_t_thermal_runaway), GET_TEXT_F(MSG_THERMAL_RUNAWAY));
|
||||
|
||||
#if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR)
|
||||
case TRMalfunction:
|
||||
TERN_(HAS_DWIN_E3V2_BASIC, DWIN_Popup_Temperature(0));
|
||||
_temp_error(heater_id, FPSTR(str_t_temp_malfunction), GET_TEXT_F(MSG_TEMP_MALFUNCTION));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1041,12 +1041,18 @@ class Temperature {
|
||||
return (RunawayIndex)_MAX(heater_id, 0);
|
||||
}
|
||||
|
||||
enum TRState : char { TRInactive, TRFirstHeating, TRStable, TRRunaway };
|
||||
enum TRState : char { TRInactive, TRFirstHeating, TRStable, TRRunaway
|
||||
OPTARG(THERMAL_PROTECTION_VARIANCE_MONITOR, TRMalfunction)
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
millis_t timer = 0;
|
||||
TRState state = TRInactive;
|
||||
float running_temp;
|
||||
#if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR)
|
||||
millis_t variance_timer = 0;
|
||||
celsius_float_t last_temp = 0.0, variance = 0.0;
|
||||
#endif
|
||||
void run(const_celsius_float_t current, const_celsius_float_t target, const heater_id_t heater_id, const uint16_t period_seconds, const celsius_t hysteresis_degc);
|
||||
} tr_state_machine_t;
|
||||
|
||||
|
Reference in New Issue
Block a user