|
@@ -196,6 +196,7 @@
|
196
|
196
|
Temperature thermalManager;
|
197
|
197
|
|
198
|
198
|
PGMSTR(str_t_thermal_runaway, STR_T_THERMAL_RUNAWAY);
|
|
199
|
+PGMSTR(str_t_temp_malfunction, STR_T_MALFUNCTION);
|
199
|
200
|
PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED);
|
200
|
201
|
|
201
|
202
|
/**
|
|
@@ -2570,14 +2571,30 @@ void Temperature::init() {
|
2570
|
2571
|
);
|
2571
|
2572
|
*/
|
2572
|
2573
|
|
2573
|
|
- // If the heater idle timeout expires, restart
|
2574
|
|
- if (TERN0(HEATER_IDLE_HANDLER, heater_idle[idle_index].timed_out)) {
|
2575
|
|
- state = TRInactive;
|
2576
|
|
- running_temp = 0;
|
2577
|
|
- }
|
2578
|
|
- else if (running_temp != target) { // If the target temperature changes, restart
|
2579
|
|
- running_temp = target;
|
2580
|
|
- state = target > 0 ? TRFirstHeating : TRInactive;
|
|
2574
|
+ #if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR)
|
|
2575
|
+ if (state == TRMalfunction) { // temperature invariance may continue, regardless of heater state
|
|
2576
|
+ variance += ABS(current - last_temp); // no need for detection window now, a single change in variance is enough
|
|
2577
|
+ last_temp = current;
|
|
2578
|
+ if (!NEAR_ZERO(variance)) {
|
|
2579
|
+ variance_timer = millis() + SEC_TO_MS(period_seconds);
|
|
2580
|
+ variance = 0.0;
|
|
2581
|
+ state = TRStable; // resume from where we detected the problem
|
|
2582
|
+ }
|
|
2583
|
+ }
|
|
2584
|
+ #endif
|
|
2585
|
+
|
|
2586
|
+ if (TERN1(THERMAL_PROTECTION_VARIANCE_MONITOR, state != TRMalfunction)) {
|
|
2587
|
+ // If the heater idle timeout expires, restart
|
|
2588
|
+ if (TERN0(HEATER_IDLE_HANDLER, heater_idle[idle_index].timed_out)) {
|
|
2589
|
+ state = TRInactive;
|
|
2590
|
+ running_temp = 0;
|
|
2591
|
+ TERN_(THERMAL_PROTECTION_VARIANCE_MONITOR, variance_timer = 0);
|
|
2592
|
+ }
|
|
2593
|
+ else if (running_temp != target) { // If the target temperature changes, restart
|
|
2594
|
+ running_temp = target;
|
|
2595
|
+ state = target > 0 ? TRFirstHeating : TRInactive;
|
|
2596
|
+ TERN_(THERMAL_PROTECTION_VARIANCE_MONITOR, variance_timer = 0);
|
|
2597
|
+ }
|
2581
|
2598
|
}
|
2582
|
2599
|
|
2583
|
2600
|
switch (state) {
|
|
@@ -2610,6 +2627,22 @@ void Temperature::init() {
|
2610
|
2627
|
|
2611
|
2628
|
const millis_t now = millis();
|
2612
|
2629
|
|
|
2630
|
+ #if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR)
|
|
2631
|
+ if (PENDING(now, variance_timer)) {
|
|
2632
|
+ variance += ABS(current - last_temp);
|
|
2633
|
+ last_temp = current;
|
|
2634
|
+ }
|
|
2635
|
+ else {
|
|
2636
|
+ if (NEAR_ZERO(variance) && variance_timer) { // valid variance monitoring window
|
|
2637
|
+ state = TRMalfunction;
|
|
2638
|
+ break;
|
|
2639
|
+ }
|
|
2640
|
+ variance_timer = now + SEC_TO_MS(period_seconds);
|
|
2641
|
+ variance = 0.0;
|
|
2642
|
+ last_temp = current;
|
|
2643
|
+ }
|
|
2644
|
+ #endif
|
|
2645
|
+
|
2613
|
2646
|
if (current >= running_temp - hysteresis_degc) {
|
2614
|
2647
|
timer = now + SEC_TO_MS(period_seconds);
|
2615
|
2648
|
break;
|
|
@@ -2622,6 +2655,12 @@ void Temperature::init() {
|
2622
|
2655
|
case TRRunaway:
|
2623
|
2656
|
TERN_(HAS_DWIN_E3V2_BASIC, DWIN_Popup_Temperature(0));
|
2624
|
2657
|
_temp_error(heater_id, FPSTR(str_t_thermal_runaway), GET_TEXT_F(MSG_THERMAL_RUNAWAY));
|
|
2658
|
+
|
|
2659
|
+ #if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR)
|
|
2660
|
+ case TRMalfunction:
|
|
2661
|
+ TERN_(HAS_DWIN_E3V2_BASIC, DWIN_Popup_Temperature(0));
|
|
2662
|
+ _temp_error(heater_id, FPSTR(str_t_temp_malfunction), GET_TEXT_F(MSG_TEMP_MALFUNCTION));
|
|
2663
|
+ #endif
|
2625
|
2664
|
}
|
2626
|
2665
|
}
|
2627
|
2666
|
|