Improve temperature runaway, idle timeout (#19339)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									cf8316bfbb
								
							
						
					
					
						commit
						979876e958
					
				| @ -484,7 +484,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep | ||||
|   // Start the heater idle timers
 | ||||
|   const millis_t nozzle_timeout = SEC_TO_MS(PAUSE_PARK_NOZZLE_TIMEOUT); | ||||
| 
 | ||||
|   HOTEND_LOOP() thermalManager.hotend_idle[e].start(nozzle_timeout); | ||||
|   HOTEND_LOOP() thermalManager.heater_idle[e].start(nozzle_timeout); | ||||
| 
 | ||||
|   #if ENABLED(DUAL_X_CARRIAGE) | ||||
|     const int8_t saved_ext        = active_extruder; | ||||
| @ -503,7 +503,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep | ||||
| 
 | ||||
|     // If the nozzle has timed out...
 | ||||
|     if (!nozzle_timed_out) | ||||
|       HOTEND_LOOP() nozzle_timed_out |= thermalManager.hotend_idle[e].timed_out; | ||||
|       HOTEND_LOOP() nozzle_timed_out |= thermalManager.heater_idle[e].timed_out; | ||||
| 
 | ||||
|     // Wait for the user to press the button to re-heat the nozzle, then
 | ||||
|     // re-heat the nozzle, re-show the continue prompt, restart idle timers, start over
 | ||||
| @ -533,7 +533,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep | ||||
|       // Start the heater idle timers
 | ||||
|       const millis_t nozzle_timeout = SEC_TO_MS(PAUSE_PARK_NOZZLE_TIMEOUT); | ||||
| 
 | ||||
|       HOTEND_LOOP() thermalManager.hotend_idle[e].start(nozzle_timeout); | ||||
|       HOTEND_LOOP() thermalManager.heater_idle[e].start(nozzle_timeout); | ||||
|       TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Reheat Done"), CONTINUE_STR)); | ||||
|       TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Reheat finished."))); | ||||
|       wait_for_user = true; | ||||
| @ -588,7 +588,7 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le | ||||
|   // Re-enable the heaters if they timed out
 | ||||
|   bool nozzle_timed_out = false; | ||||
|   HOTEND_LOOP() { | ||||
|     nozzle_timed_out |= thermalManager.hotend_idle[e].timed_out; | ||||
|     nozzle_timed_out |= thermalManager.heater_idle[e].timed_out; | ||||
|     thermalManager.reset_hotend_idle_timer(e); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -56,6 +56,15 @@ | ||||
|   #undef SHOW_TEMP_ADC_VALUES | ||||
| #endif | ||||
| 
 | ||||
| #if TEMP_SENSOR_BED == 0 | ||||
|   #undef THERMAL_PROTECTION_BED | ||||
|   #undef THERMAL_PROTECTION_BED_PERIOD | ||||
| #endif  | ||||
| 
 | ||||
| #if TEMP_SENSOR_CHAMBER == 0 | ||||
|   #undef THERMAL_PROTECTION_CHAMBER | ||||
| #endif | ||||
| 
 | ||||
| #if ENABLED(MIXING_EXTRUDER) && (ENABLED(RETRACT_SYNC_MIXING) || BOTH(FILAMENT_LOAD_UNLOAD_GCODES, FILAMENT_UNLOAD_ALL_EXTRUDERS)) | ||||
|   #define HAS_MIXER_SYNC_CHANNEL 1 | ||||
| #endif | ||||
|  | ||||
| @ -521,7 +521,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const | ||||
| 
 | ||||
| FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char prefix, const bool blink) { | ||||
|   #if HAS_HEATED_BED | ||||
|     const bool isBed = heater_id < 0; | ||||
|     const bool isBed = TERN(HAS_HEATED_CHAMBER, heater_id == H_BED, heater_id < 0); | ||||
|     const float t1 = (isBed ? thermalManager.degBed()       : thermalManager.degHotend(heater_id)), | ||||
|                 t2 = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater_id)); | ||||
|   #else | ||||
| @ -536,14 +536,7 @@ FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char pr | ||||
|   #if !HEATER_IDLE_HANDLER | ||||
|     UNUSED(blink); | ||||
|   #else | ||||
|     const bool is_idle = ( | ||||
|       #if HAS_HEATED_BED | ||||
|         isBed ? thermalManager.bed_idle.timed_out : | ||||
|       #endif | ||||
|       thermalManager.hotend_idle[heater_id].timed_out | ||||
|     ); | ||||
| 
 | ||||
|     if (!blink && is_idle) { | ||||
|     if (!blink && thermalManager.heater_idle[thermalManager.idle_index_for_id(heater_id)].timed_out) { | ||||
|       lcd_put_wchar(' '); | ||||
|       if (t2 >= 10) lcd_put_wchar(' '); | ||||
|       if (t2 >= 100) lcd_put_wchar(' '); | ||||
| @ -560,27 +553,14 @@ FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char pr | ||||
| } | ||||
| 
 | ||||
| FORCE_INLINE void _draw_bed_status(const bool blink) { | ||||
|   _draw_heater_status(H_BED, ( | ||||
|       #if HAS_LEVELING | ||||
|         planner.leveling_active && blink ? '_' : | ||||
|       #endif | ||||
|       LCD_STR_BEDTEMP[0] | ||||
|     ), | ||||
|     blink | ||||
|   ); | ||||
|   _draw_heater_status(H_BED, TERN0(HAS_LEVELING, blink && planner.leveling_active) ? '_' : LCD_STR_BEDTEMP[0], blink); | ||||
| } | ||||
| 
 | ||||
| #if HAS_PRINT_PROGRESS | ||||
| 
 | ||||
|   FORCE_INLINE void _draw_print_progress() { | ||||
|     const uint8_t progress = ui.get_progress_percent(); | ||||
|     lcd_put_u8str_P(PSTR( | ||||
|       #if ENABLED(SDSUPPORT) | ||||
|         "SD" | ||||
|       #elif ENABLED(LCD_SET_PROGRESS_MANUALLY) | ||||
|         "P:" | ||||
|       #endif | ||||
|     )); | ||||
|     lcd_put_u8str_P(PSTR(TERN(SDSUPPORT, "SD", "P:"))); | ||||
|     if (progress) | ||||
|       lcd_put_u8str(ui8tostr3rj(progress)); | ||||
|     else | ||||
|  | ||||
| @ -254,7 +254,7 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, cons | ||||
| 
 | ||||
|     if (PAGE_UNDER(7)) { | ||||
|       #if HEATER_IDLE_HANDLER | ||||
|         const bool dodraw = (blink || !thermalManager.hotend_idle[heater_id].timed_out); | ||||
|         const bool dodraw = (blink || !thermalManager.heater_idle[heater_id].timed_out); | ||||
|       #else | ||||
|         constexpr bool dodraw = true; | ||||
|       #endif | ||||
| @ -327,7 +327,7 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, cons | ||||
| 
 | ||||
|     if (PAGE_UNDER(7)) { | ||||
|       #if HEATER_IDLE_HANDLER | ||||
|         const bool dodraw = (blink || !thermalManager.bed_idle.timed_out); | ||||
|         const bool dodraw = (blink || !thermalManager.heater_idle[thermalManager.IDLE_INDEX_BED].timed_out); | ||||
|       #else | ||||
|         constexpr bool dodraw = true; | ||||
|       #endif | ||||
|  | ||||
| @ -308,7 +308,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop | ||||
|       lcd_put_u8str(i16tostr3rj(thermalManager.degHotend(extruder))); | ||||
|       lcd_put_wchar('/'); | ||||
| 
 | ||||
|       if (get_blink() || !thermalManager.hotend_idle[extruder].timed_out) | ||||
|       if (get_blink() || !thermalManager.heater_idle[extruder].timed_out) | ||||
|         lcd_put_u8str(i16tostr3rj(thermalManager.degTargetHotend(extruder))); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -223,7 +223,7 @@ namespace ExtUI { | ||||
| 
 | ||||
|   bool isHeaterIdle(const extruder_t extruder) { | ||||
|     #if HAS_HOTEND && HEATER_IDLE_HANDLER | ||||
|       return thermalManager.hotend_idle[extruder - E0].timed_out; | ||||
|       return thermalManager.heater_idle[extruder - E0].timed_out; | ||||
|     #else | ||||
|       UNUSED(extruder); | ||||
|       return false; | ||||
| @ -233,10 +233,10 @@ namespace ExtUI { | ||||
|   bool isHeaterIdle(const heater_t heater) { | ||||
|     #if HEATER_IDLE_HANDLER | ||||
|       switch (heater) { | ||||
|         TERN_(HAS_HEATED_BED, case BED: return thermalManager.bed_idle.timed_out); | ||||
|         TERN_(HAS_HEATED_BED, case BED: return thermalManager.heater_idle[thermalManager.IDLE_INDEX_BED].timed_out); | ||||
|         TERN_(HAS_HEATED_CHAMBER, case CHAMBER: return false); // Chamber has no idle timer
 | ||||
|         default: | ||||
|           return TERN0(HAS_HOTEND, thermalManager.hotend_idle[heater - H0].timed_out); | ||||
|           return TERN0(HAS_HOTEND, thermalManager.heater_idle[heater - H0].timed_out); | ||||
|       } | ||||
|     #else | ||||
|       UNUSED(heater); | ||||
|  | ||||
| @ -410,10 +410,6 @@ namespace Language_cz { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("TEPL. ÚNIK KOMORA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("VYSOKÁ TEPLOTA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("NÍZKA TEPLOTA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("VYS. TEPL. PODL."); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("NÍZ. TEPL. PODL."); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Err: MAXTEMP KOMORA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Err: MINTEMP KOMORA"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("TISK. ZASTAVENA"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Proveďte reset"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); | ||||
|  | ||||
| @ -142,8 +142,6 @@ namespace Language_da { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY                 = _UxGT("Temp løber løbsk"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Fejl: Maks temp"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Fejl: Min temp"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Fejl: Maks Plade temp"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Fejl: Min Plade temp"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("PRINTER STOPPET"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Reset Venligst"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); // Kun et bogstav
 | ||||
|  | ||||
| @ -452,10 +452,6 @@ namespace Language_de { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("GEH.") " " LCD_STR_THERMOMETER _UxGT(" NICHT ERREICHT"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = " " LCD_STR_THERMOMETER _UxGT(" ÜBERSCHRITTEN"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = " " LCD_STR_THERMOMETER _UxGT(" UNTERSCHRITTEN"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("BETT ") LCD_STR_THERMOMETER _UxGT(" ÜBERSCHRITTEN"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("BETT ") LCD_STR_THERMOMETER _UxGT(" UNTERSCHRITTEN"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Err:Gehäuse max Temp"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Err:Gehäuse min Temp"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("DRUCKER GESTOPPT"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Bitte neustarten"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("t"); // One character only
 | ||||
|  | ||||
| @ -180,8 +180,6 @@ namespace Language_el { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY                 = _UxGT("ΔΙΑΦΥΓΗ ΘΕΡΜΟΚΡΑΣΙΑΣ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("ΠΕΡΙΤΗ ΘΕΡΜΟΚΡΑΣΙΑ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("ΜΗ ΕΠΑΡΚΗΣ ΘΕΡΜΟΚΡΑΣΙΑΣ"); //SHORTEN
 | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("ΜΕΓΙΣΤΗ ΘΕΡΜΟΚΡΑΣΙΑΣ ΕΠ. ΕΚΤΥΠΩΣΗΣ"); //SHORTEN
 | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΚΡΑΣΙΑΣ ΕΠ. ΕΚΤΥΠΩΣΗΣ"); //SHORTEN
 | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("H εκτύπωση διακόπηκε"); | ||||
|   PROGMEM Language_Str MSG_HEATING                         = _UxGT("Θερμαίνεται…"); | ||||
|   PROGMEM Language_Str MSG_BED_HEATING                     = _UxGT("Θέρμανση ΕΠ. Εκτύπωσης"); //SHORTEN
 | ||||
|  | ||||
| @ -182,8 +182,6 @@ namespace Language_el_gr { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY                 = _UxGT("ΔΙΑΦΥΓΗ ΘΕΡΜΟΤΗΤΑΣ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Λάθος: ΜΕΓΙΣΤΗ ΘΕΡΜΟΤΗΤΑ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Λάθος: ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΤΗΤΑ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Λάθος: ΜΕΓΙΣΤΗ ΘΕΡΜΟΤΗΤΑ ΚΛΙΝΗΣ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Λάθος: ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΤΗΤΑ ΚΛΙΝΗΣ"); | ||||
|   PROGMEM Language_Str MSG_HEATING                         = _UxGT("Θερμαίνεται…"); | ||||
|   PROGMEM Language_Str MSG_BED_HEATING                     = _UxGT("Θέρμανση κλίνης…"); | ||||
|   PROGMEM Language_Str MSG_DELTA_CALIBRATE                 = _UxGT("Βαθμονόμηση Delta"); | ||||
|  | ||||
| @ -457,10 +457,6 @@ namespace Language_en { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("CHAMBER T. RUNAWAY"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Err: MAXTEMP"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Err: MINTEMP"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Err: MAXTEMP BED"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Err: MINTEMP BED"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Err: MAXTEMP CHAMBER"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Err: MINTEMP CHAMBER"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("PRINTER HALTED"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Please Reset"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); // One character only
 | ||||
|  | ||||
| @ -421,10 +421,6 @@ namespace Language_es { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("FUGA TÉRMICA CAMARA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Err:TEMP. MÁX"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Err:TEMP. MIN"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Err:TEMP. MÁX CAMA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Err:TEMP. MIN CAMA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Err:TEMP. MÁX CÁMARA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Err:TEMP. MIN CÁMARA"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("IMPRESORA DETENIDA"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Por favor, reinicie"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); // One character only
 | ||||
|  | ||||
| @ -244,8 +244,6 @@ namespace Language_eu { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY                 = _UxGT("TENP. KONTROL EZA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Err: Tenp Maximoa"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Err: Tenp Minimoa"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Err: Ohe Tenp Max"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Err: Ohe Tenp Min"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("INPRIMA. GELDIRIK"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Berrabia. Mesedez"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); // One character only
 | ||||
|  | ||||
| @ -443,10 +443,6 @@ namespace Language_gl { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("FUGA TÉRMICA CÁMARA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Erro:TEMP MÁX"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Erro:TEMP MÍN"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Erro:TEMP MÁX CAMA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Erro:TEMP MÍN CAMA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Erro:TEMP MÁX CÁMARA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Erro:TEMP MÍN CÁMARA"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("IMPRESORA DETIDA"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Debe reiniciar!"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); // One character only
 | ||||
|  | ||||
| @ -445,10 +445,6 @@ namespace Language_hu { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("KAMRA FÜTÉS KIMARADÁS"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Hiba: MAX Höfok"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Hiba: MIN Höfok"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Hiba: MAX ÁGY HÖFOK"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Hiba: MIN ÁGY HÖFOK"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Hiba: MAX KAMRA HÖFOK"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Hiba: MIN KAMRA HÖFOK"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("A NYOMTATÓ LEFAGYOTT"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Indítsd újra!"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("n"); // Csak egy karakter
 | ||||
|  | ||||
| @ -457,10 +457,6 @@ namespace Language_it { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("T.CAMERA FUORI CTRL"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Err: TEMP MASSIMA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Err: TEMP MINIMA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Err: TEMP MAX PIATTO"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Err: TEMP MIN PIATTO"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Err: TEMP MAX CAMERA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Err: TEMP MIN CAMERA"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("STAMPANTE FERMATA"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Riavviare prego"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("g"); // Un solo carattere
 | ||||
|  | ||||
| @ -184,8 +184,6 @@ namespace Language_jp_kana { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY                 = _UxGT("ネツボウソウ");                   // "THERMAL RUNAWAY"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("エラー:サイコウオンチョウカ");         // "Err: MAXTEMP"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("エラー:サイテイオンミマン");          // "Err: MINTEMP"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("エラー:ベッド サイコウオンチョウカ");    // "Err: MAXTEMP BED"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("エラー:ベッド サイテイオンミマン");     // "Err: MINTEMP BED"
 | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("プリンターハテイシシマシタ");         // "PRINTER HALTED"
 | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("リセットシテクダサイ");              // "Please reset"
 | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d");                          // One character only
 | ||||
|  | ||||
| @ -164,8 +164,6 @@ namespace Language_nl { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY                 = _UxGT("Therm. wegloop"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Err: Max. temp"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Err: Min. temp"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Err: Max.tmp bed"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Err: Min.tmp bed"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("PRINTER GESTOPT"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Reset A.U.B."); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); //  One character only. Keep English standard
 | ||||
|  | ||||
| @ -391,10 +391,6 @@ namespace Language_pl { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("ZANIK TEMP.KOMORY"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Błąd: MAXTEMP"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Błąd: MINTEMP"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Błąd: MAXTEMP STÓŁ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Błąd: MINTEMP STÓŁ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Błąd: MAXTEMP KOMORA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Błąd: MINTEMP KOMORA"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("Drukarka zatrzym."); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Proszę zresetować"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); // One character only
 | ||||
|  | ||||
| @ -150,8 +150,6 @@ namespace Language_pt { | ||||
|   PROGMEM Language_Str MSG_HEATING_FAILED_LCD              = _UxGT("Aquecimento falhou"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Err: T Máxima"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Err: T Mínima"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Err: T Base Máxima"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Err: T Base Mínima"); | ||||
|   PROGMEM Language_Str MSG_HEATING                         = _UxGT("Aquecendo..."); | ||||
|   PROGMEM Language_Str MSG_BED_HEATING                     = _UxGT("Aquecendo base..."); | ||||
|   PROGMEM Language_Str MSG_DELTA_CALIBRATE                 = _UxGT("Calibração Delta"); | ||||
|  | ||||
| @ -357,10 +357,6 @@ namespace Language_pt_br { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("ESCAPE TÉRMICO CAMARA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Erro:Temp Máxima"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Erro:Temp Mínima"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Erro:Temp Mesa Máx"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Erro:Temp Mesa Mín"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Erro:Temp Câmara Máx"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Erro:Temp Câmara Min"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("IMPRESSORA PAROU"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Favor resetar"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); | ||||
|  | ||||
| @ -448,10 +448,6 @@ namespace Language_ro { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("CHAMBER T. RUNAWAY"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Err: MAXTEMP"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Err: MINTEMP"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Err: MAXTEMP BED"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Err: MINTEMP BED"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Err: MAXTEMP CHAMBER"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Err: MINTEMP CHAMBER"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("PRINTER HALTED"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Please Reset"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); // One character only
 | ||||
|  | ||||
| @ -536,10 +536,6 @@ namespace Language_ru { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("УТЕЧКА ТЕПЛА КАМЕРЫ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Ошибка: Т макс."); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Ошибка: Т мин."); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Ошибка: Т стола макс"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Ошибка: Т стола мин."); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Ошибка:Т камеры макс"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Ошибка:Т камеры мин."); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("ПРИНТЕР ОСТАНОВЛЕН"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Сделайте сброс"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("д"); // One character only
 | ||||
|  | ||||
| @ -441,10 +441,6 @@ namespace Language_sk { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("TEPLOTNÝ SKOK KOMO."); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Chyba: MAXTEMP"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Chyba: MINTEMP"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Chyba: MAXTEMP PODL."); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Chyba: MINTEMP PODL."); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Chyba: MAXTEMP KOMO."); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Chyba: MINTEMP KOMO."); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("TLAČIAREŇ ZASTAVENÁ"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Reštartuje ju"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("d"); | ||||
|  | ||||
| @ -420,10 +420,6 @@ namespace Language_tr { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("ODA TERMAL PROBLEM"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Hata: MAX.SICAKLIK"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Hata: MIN.SICAKLIK"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Hata: MAX.SIC. TABLA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Hata: MIN.SIC. TABLA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("Hata: MAX.SIC ODA"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("Hata: MIN.SIC ODA"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("YAZICI DURDURULDU"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Lütfen Resetleyin"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("G"); // One character only
 | ||||
|  | ||||
| @ -530,10 +530,6 @@ namespace Language_uk { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("ВИТІК ТЕПЛА КАМЕРИ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("ПЕРЕГРІВ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("МІНІМАЛЬНА Т") LCD_STR_DEGREE; | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("ПЕРЕГРІВ СТОЛУ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("МІНІМАЛЬНА Т") LCD_STR_DEGREE _UxGT(" СТОЛУ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("ПЕРЕГРІВ КАМЕРИ"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("МІНІМАЛЬНА Т") LCD_STR_DEGREE _UxGT(" КАМЕРИ"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("ПРИНТЕР ЗУПИНЕНО"); | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Перезавантажте"); | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("д"); // One character only
 | ||||
|  | ||||
| @ -335,8 +335,6 @@ namespace Language_vi { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_BED             = _UxGT("Vấn đề nhiệt bàn");                     // BED THERMAL RUNAWAY
 | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("Điều sai: nhiệt độ tối đa");            // Err: MAXTEMP
 | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("Điều sai: nhiệt độ tối thiểu");         // Err: MINTEMP
 | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("Điều sai: nhiệt độ bàn tối đa");        // Err: MAXTEMP BED
 | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("Điều sai: nhiệt độ bàn tối thiểu");     // Err: MINTEMP BED
 | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("MÁY IN ĐÃ DỪNG LẠI");                   // PRINTER HALTED
 | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("Xin bặt lại");                          // Please reset
 | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("n");                                    // d - ngày - One character only
 | ||||
|  | ||||
| @ -447,10 +447,6 @@ namespace Language_zh_CN { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("机箱热量失控"); | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("错误:最高温度");     //"Err: MAXTEMP"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("错误:最低温度");     //"Err: MINTEMP"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("错误:最高热床温度");     //"Err: MAXTEMP BED"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("错误:最低热床温度");     //"Err: MINTEMP BED"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("错误:最高机箱温度"); | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("错误:最低机箱温度"); | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("打印停机");     //"PRINTER HALTED"
 | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("请重置");     //"Please reset"
 | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("天");     //"d" // One character only
 | ||||
|  | ||||
| @ -388,10 +388,6 @@ namespace Language_zh_TW { | ||||
|   PROGMEM Language_Str MSG_THERMAL_RUNAWAY_CHAMBER         = _UxGT("機箱溫度失控");   //"CHAMBER T. RUNAWAY"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP                     = _UxGT("錯誤:最高溫度");     //"Err: MAXTEMP"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP                     = _UxGT("錯誤:最低溫度");     //"Err: MINTEMP"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_BED                 = _UxGT("錯誤:最高熱床溫度");     //"Err: MAXTEMP BED"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_BED                 = _UxGT("錯誤:最低熱床溫度");     //"Err: MINTEMP BED"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MAXTEMP_CHAMBER             = _UxGT("錯誤:最高機箱溫度");   //"Err: MAXTEMP CHAMBER"
 | ||||
|   PROGMEM Language_Str MSG_ERR_MINTEMP_CHAMBER             = _UxGT("錯誤:最低機箱溫度");   //"Err: MINTEMP CHAMBER"
 | ||||
|   PROGMEM Language_Str MSG_HALTED                          = _UxGT("印表機停機");     //"PRINTER HALTED"
 | ||||
|   PROGMEM Language_Str MSG_PLEASE_RESET                    = _UxGT("請重置");     //"Please reset"
 | ||||
|   PROGMEM Language_Str MSG_SHORT_DAY                       = _UxGT("天");     //"d" // One character only
 | ||||
|  | ||||
| @ -34,10 +34,6 @@ | ||||
|   #include "../../libs/buzzer.h" | ||||
| #endif | ||||
| 
 | ||||
| #if WATCH_HOTENDS || WATCH_BED | ||||
|   #include "../../module/temperature.h" | ||||
| #endif | ||||
| 
 | ||||
| #if ENABLED(BABYSTEP_ZPROBE_OFFSET) | ||||
|   #include "../../module/probe.h" | ||||
| #endif | ||||
|  | ||||
| @ -252,7 +252,7 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, | ||||
|   hotend_watch_t Temperature::watch_hotend[HOTENDS]; // = { { 0 } }
 | ||||
| #endif | ||||
| #if HEATER_IDLE_HANDLER | ||||
|   hotend_idle_t Temperature::hotend_idle[HOTENDS]; // = { { 0 } }
 | ||||
|   Temperature::heater_idle_t Temperature::heater_idle[NR_HEATER_IDLE]; // = { { 0 } }
 | ||||
| #endif | ||||
| 
 | ||||
| #if HAS_HEATED_BED | ||||
| @ -266,7 +266,6 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, | ||||
|   #endif | ||||
|   TERN_(WATCH_BED, bed_watch_t Temperature::watch_bed); // = { 0 }
 | ||||
|   TERN(PIDTEMPBED,, millis_t Temperature::next_bed_check_ms); | ||||
|   TERN_(HEATER_IDLE_HANDLER, hotend_idle_t Temperature::bed_idle); // = { 0 }
 | ||||
| #endif // HAS_HEATED_BED
 | ||||
| 
 | ||||
| #if HAS_TEMP_CHAMBER | ||||
| @ -841,7 +840,7 @@ void Temperature::min_temp_error(const heater_id_t heater_id) { | ||||
| 
 | ||||
|         if (temp_hotend[ee].target == 0 | ||||
|           || pid_error < -(PID_FUNCTIONAL_RANGE) | ||||
|           || TERN0(HEATER_IDLE_HANDLER, hotend_idle[ee].timed_out) | ||||
|           || TERN0(HEATER_IDLE_HANDLER, heater_idle[ee].timed_out) | ||||
|         ) { | ||||
|           pid_output = 0; | ||||
|           pid_reset[ee] = true; | ||||
| @ -926,7 +925,7 @@ void Temperature::min_temp_error(const heater_id_t heater_id) { | ||||
| 
 | ||||
|     #else // No PID enabled
 | ||||
| 
 | ||||
|       const bool is_idling = TERN0(HEATER_IDLE_HANDLER, hotend_idle[ee].timed_out); | ||||
|       const bool is_idling = TERN0(HEATER_IDLE_HANDLER, heater_idle[ee].timed_out); | ||||
|       const float pid_output = (!is_idling && temp_hotend[ee].celsius < temp_hotend[ee].target) ? BANG_MAX : 0; | ||||
| 
 | ||||
|     #endif | ||||
| @ -1040,15 +1039,14 @@ void Temperature::manage_heater() { | ||||
| 
 | ||||
|     HOTEND_LOOP() { | ||||
|       #if ENABLED(THERMAL_PROTECTION_HOTENDS) | ||||
|         if (degHotend(e) > temp_range[e].maxtemp) | ||||
|           _temp_error((heater_id_t)e, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); | ||||
|         if (degHotend(e) > temp_range[e].maxtemp) max_temp_error((heater_id_t)e); | ||||
|       #endif | ||||
| 
 | ||||
|       TERN_(HEATER_IDLE_HANDLER, hotend_idle[e].update(ms)); | ||||
|       TERN_(HEATER_IDLE_HANDLER, heater_idle[e].update(ms)); | ||||
| 
 | ||||
|       #if ENABLED(THERMAL_PROTECTION_HOTENDS) | ||||
|         // Check for thermal runaway
 | ||||
|         thermal_runaway_protection(tr_state_machine[e], temp_hotend[e].celsius, temp_hotend[e].target, (heater_id_t)e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); | ||||
|         tr_state_machine[e].run(temp_hotend[e].celsius, temp_hotend[e].target, (heater_id_t)e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); | ||||
|       #endif | ||||
| 
 | ||||
|       temp_hotend[e].soft_pwm_amount = (temp_hotend[e].celsius > temp_range[e].mintemp || is_preheating(e)) && temp_hotend[e].celsius < temp_range[e].maxtemp ? (int)get_pid_output_hotend(e) >> 1 : 0; | ||||
| @ -1093,8 +1091,7 @@ void Temperature::manage_heater() { | ||||
|   #if HAS_HEATED_BED | ||||
| 
 | ||||
|     #if ENABLED(THERMAL_PROTECTION_BED) | ||||
|       if (degBed() > BED_MAXTEMP) | ||||
|         _temp_error(H_BED, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); | ||||
|       if (degBed() > BED_MAXTEMP) max_temp_error(H_BED); | ||||
|     #endif | ||||
| 
 | ||||
|     #if WATCH_BED | ||||
| @ -1127,12 +1124,14 @@ void Temperature::manage_heater() { | ||||
|         TERN_(PAUSE_CHANGE_REQD, last_pause_state = paused); | ||||
|       #endif | ||||
| 
 | ||||
|       TERN_(HEATER_IDLE_HANDLER, bed_idle.update(ms)); | ||||
|       TERN_(HEATER_IDLE_HANDLER, heater_idle[IDLE_INDEX_BED].update(ms)); | ||||
| 
 | ||||
|       TERN_(HAS_THERMALLY_PROTECTED_BED, thermal_runaway_protection(tr_state_machine_bed, temp_bed.celsius, temp_bed.target, H_BED, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS)); | ||||
|       #if HAS_THERMALLY_PROTECTED_BED | ||||
|         tr_state_machine[RUNAWAY_IND_BED].run(temp_bed.celsius, temp_bed.target, H_BED, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS); | ||||
|       #endif | ||||
| 
 | ||||
|       #if HEATER_IDLE_HANDLER | ||||
|         if (bed_idle.timed_out) { | ||||
|         if (heater_idle[IDLE_INDEX_BED].timed_out) { | ||||
|           temp_bed.soft_pwm_amount = 0; | ||||
|           #if DISABLED(PIDTEMPBED) | ||||
|             WRITE_HEATER_BED(LOW); | ||||
| @ -1173,8 +1172,7 @@ void Temperature::manage_heater() { | ||||
|     #endif | ||||
| 
 | ||||
|     #if ENABLED(THERMAL_PROTECTION_CHAMBER) | ||||
|       if (degChamber() > CHAMBER_MAXTEMP) | ||||
|         _temp_error(H_CHAMBER, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); | ||||
|       if (degChamber() > CHAMBER_MAXTEMP) max_temp_error(H_CHAMBER); | ||||
|     #endif | ||||
| 
 | ||||
|     #if WATCH_CHAMBER | ||||
| @ -1205,7 +1203,9 @@ void Temperature::manage_heater() { | ||||
|         WRITE_HEATER_CHAMBER(LOW); | ||||
|       } | ||||
| 
 | ||||
|       TERN_(THERMAL_PROTECTION_CHAMBER, thermal_runaway_protection(tr_state_machine_chamber, temp_chamber.celsius, temp_chamber.target, H_CHAMBER, THERMAL_PROTECTION_CHAMBER_PERIOD, THERMAL_PROTECTION_CHAMBER_HYSTERESIS)); | ||||
|       #if ENABLED(THERMAL_PROTECTION_CHAMBER) | ||||
|         tr_state_machine[RUNAWAY_IND_CHAMBER].run(temp_chamber.celsius, temp_chamber.target, H_CHAMBER, THERMAL_PROTECTION_CHAMBER_PERIOD, THERMAL_PROTECTION_CHAMBER_HYSTERESIS); | ||||
|       #endif | ||||
|     } | ||||
| 
 | ||||
|     // TODO: Implement true PID pwm
 | ||||
| @ -1935,61 +1935,66 @@ void Temperature::init() { | ||||
| 
 | ||||
| #if HAS_THERMAL_PROTECTION | ||||
| 
 | ||||
|   #if ENABLED(THERMAL_PROTECTION_HOTENDS) | ||||
|     Temperature::tr_state_machine_t Temperature::tr_state_machine[HOTENDS]; // = { { TRInactive, 0 } };
 | ||||
|   #endif | ||||
|   #if HAS_THERMALLY_PROTECTED_BED | ||||
|     Temperature::tr_state_machine_t Temperature::tr_state_machine_bed; // = { TRInactive, 0 };
 | ||||
|   #endif | ||||
|   #if ENABLED(THERMAL_PROTECTION_CHAMBER) | ||||
|     Temperature::tr_state_machine_t Temperature::tr_state_machine_chamber; // = { TRInactive, 0 };
 | ||||
|   #endif | ||||
|   Temperature::tr_state_machine_t Temperature::tr_state_machine[NR_HEATER_RUNAWAY]; // = { { TRInactive, 0 } };
 | ||||
| 
 | ||||
|   void Temperature::thermal_runaway_protection(Temperature::tr_state_machine_t &sm, const float ¤t, const float &target, const heater_id_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) { | ||||
|   /**
 | ||||
|    * @brief Thermal Runaway state machine for a single heater | ||||
|    * @param current          current measured temperature | ||||
|    * @param target           current target temperature | ||||
|    * @param heater_id        extruder index | ||||
|    * @param period_seconds   missed temperature allowed time | ||||
|    * @param hysteresis_degc  allowed distance from target | ||||
|    * | ||||
|    * TODO: Embed the last 3 parameters during init, if not less optimal | ||||
|    */ | ||||
|   void Temperature::tr_state_machine_t::run(const float ¤t, const float &target, const heater_id_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) { | ||||
| 
 | ||||
|     static float tr_target_temperature[HOTENDS + 1] = { 0.0 }; | ||||
|     #if HEATER_IDLE_HANDLER | ||||
|       // Convert the given heater_id_t to an idle array index
 | ||||
|       const IdleIndex idle_index = idle_index_for_id(heater_id); | ||||
|     #endif | ||||
| 
 | ||||
|     /**
 | ||||
|       SERIAL_ECHO_START(); | ||||
|       SERIAL_ECHOPGM("Thermal Runaway Running. Heater ID: "); | ||||
|       if (heater_id == H_CHAMBER) SERIAL_ECHOPGM("chamber"); | ||||
|       if (heater_id < 0) SERIAL_ECHOPGM("bed"); else SERIAL_ECHO(heater_id); | ||||
|       SERIAL_ECHOPAIR(" ;  State:", sm.state, " ;  Timer:", sm.timer, " ;  Temperature:", current, " ;  Target Temp:", target); | ||||
|       if (heater_id >= 0) | ||||
|         SERIAL_ECHOPAIR(" ;  Idle Timeout:", hotend_idle[heater_id].timed_out); | ||||
|       else | ||||
|         SERIAL_ECHOPAIR(" ;  Idle Timeout:", bed_idle.timed_out); | ||||
|       SERIAL_EOL(); | ||||
|       switch (heater_id) { | ||||
|         case H_BED:     SERIAL_ECHOPGM("bed"); break; | ||||
|         case H_CHAMBER: SERIAL_ECHOPGM("chamber"); break; | ||||
|         default:        SERIAL_ECHO(heater_id); | ||||
|       } | ||||
|       SERIAL_ECHOLNPAIR( | ||||
|         " ; sizeof(running_temp):", sizeof(running_temp), | ||||
|         " ;  State:", state, " ;  Timer:", timer, " ;  Temperature:", current, " ;  Target Temp:", target | ||||
|         #if HEATER_IDLE_HANDLER | ||||
|           , " ;  Idle Timeout:", heater_idle[idle_index].timed_out | ||||
|         #endif | ||||
|       ); | ||||
|     //*/
 | ||||
| 
 | ||||
|     const int heater_index = heater_id >= 0 ? heater_id : HOTENDS; | ||||
| 
 | ||||
|     #if HEATER_IDLE_HANDLER | ||||
|       // If the heater idle timeout expires, restart
 | ||||
|       if ((heater_id >= 0 && hotend_idle[heater_id].timed_out) | ||||
|         || TERN0(HAS_HEATED_BED, (heater_id < 0 && bed_idle.timed_out)) | ||||
|       ) { | ||||
|         sm.state = TRInactive; | ||||
|         tr_target_temperature[heater_index] = 0; | ||||
|       if (heater_idle[idle_index].timed_out) { | ||||
|         state = TRInactive; | ||||
|         running_temp = 0; | ||||
|       } | ||||
|       else | ||||
|     #endif | ||||
|     { | ||||
|       // If the target temperature changes, restart
 | ||||
|       if (tr_target_temperature[heater_index] != target) { | ||||
|         tr_target_temperature[heater_index] = target; | ||||
|         sm.state = target > 0 ? TRFirstHeating : TRInactive; | ||||
|       if (running_temp != target) { | ||||
|         running_temp = target; | ||||
|         state = target > 0 ? TRFirstHeating : TRInactive; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     switch (sm.state) { | ||||
|     switch (state) { | ||||
|       // Inactive state waits for a target temperature to be set
 | ||||
|       case TRInactive: break; | ||||
| 
 | ||||
|       // When first heating, wait for the temperature to be reached then go to Stable state
 | ||||
|       case TRFirstHeating: | ||||
|         if (current < tr_target_temperature[heater_index]) break; | ||||
|         sm.state = TRStable; | ||||
|         if (current < running_temp) break; | ||||
|         state = TRStable; | ||||
| 
 | ||||
|       // While the temperature is stable watch for a bad temperature
 | ||||
|       case TRStable: | ||||
| @ -1997,25 +2002,25 @@ void Temperature::init() { | ||||
|         #if ENABLED(ADAPTIVE_FAN_SLOWING) | ||||
|           if (adaptive_fan_slowing && heater_id >= 0) { | ||||
|             const int fan_index = _MIN(heater_id, FAN_COUNT - 1); | ||||
|             if (fan_speed[fan_index] == 0 || current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.25f)) | ||||
|             if (fan_speed[fan_index] == 0 || current >= running_temp - (hysteresis_degc * 0.25f)) | ||||
|               fan_speed_scaler[fan_index] = 128; | ||||
|             else if (current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.3335f)) | ||||
|             else if (current >= running_temp - (hysteresis_degc * 0.3335f)) | ||||
|               fan_speed_scaler[fan_index] = 96; | ||||
|             else if (current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.5f)) | ||||
|             else if (current >= running_temp - (hysteresis_degc * 0.5f)) | ||||
|               fan_speed_scaler[fan_index] = 64; | ||||
|             else if (current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.8f)) | ||||
|             else if (current >= running_temp - (hysteresis_degc * 0.8f)) | ||||
|               fan_speed_scaler[fan_index] = 32; | ||||
|             else | ||||
|               fan_speed_scaler[fan_index] = 0; | ||||
|           } | ||||
|         #endif | ||||
| 
 | ||||
|         if (current >= tr_target_temperature[heater_index] - hysteresis_degc) { | ||||
|           sm.timer = millis() + SEC_TO_MS(period_seconds); | ||||
|         if (current >= running_temp - hysteresis_degc) { | ||||
|           timer = millis() + SEC_TO_MS(period_seconds); | ||||
|           break; | ||||
|         } | ||||
|         else if (PENDING(millis(), sm.timer)) break; | ||||
|         sm.state = TRRunaway; | ||||
|         else if (PENDING(millis(), timer)) break; | ||||
|         state = TRRunaway; | ||||
| 
 | ||||
|       case TRRunaway: | ||||
|         TERN_(DWIN_CREALITY_LCD, Popup_Window_Temperature(0)); | ||||
| @ -2086,8 +2091,8 @@ void Temperature::disable_all_heaters() { | ||||
|     if (p != paused) { | ||||
|       paused = p; | ||||
|       if (p) { | ||||
|         HOTEND_LOOP() hotend_idle[e].expire();    // Timeout immediately
 | ||||
|         TERN_(HAS_HEATED_BED, bed_idle.expire()); // Timeout immediately
 | ||||
|         HOTEND_LOOP() heater_idle[e].expire();    // Timeout immediately
 | ||||
|         TERN_(HAS_HEATED_BED, heater_idle[IDLE_INDEX_BED].expire()); // Timeout immediately
 | ||||
|       } | ||||
|       else { | ||||
|         HOTEND_LOOP() reset_hotend_idle_timer(e); | ||||
| @ -2333,9 +2338,7 @@ void Temperature::readings_ready() { | ||||
|     #else | ||||
|       #define BEDCMP(A,B) ((A)>(B)) | ||||
|     #endif | ||||
|     const bool bed_on = temp_bed.target > 0 | ||||
|       || TERN0(PIDTEMPBED, temp_bed.soft_pwm_amount) > 0 | ||||
|     ; | ||||
|     const bool bed_on = (temp_bed.target > 0) || TERN0(PIDTEMPBED, temp_bed.soft_pwm_amount > 0); | ||||
|     if (BEDCMP(temp_bed.raw, maxtemp_raw_BED)) max_temp_error(H_BED); | ||||
|     if (bed_on && BEDCMP(mintemp_raw_BED, temp_bed.raw)) min_temp_error(H_BED); | ||||
|   #endif | ||||
|  | ||||
| @ -40,7 +40,7 @@ | ||||
| #define HOTEND_INDEX TERN(HAS_MULTI_HOTEND, e, 0) | ||||
| #define E_NAME TERN_(HAS_MULTI_HOTEND, e) | ||||
| 
 | ||||
| // Identifiers for other heaters
 | ||||
| // Heater identifiers. Positive values are hotends. Negative values are other heaters.
 | ||||
| typedef enum : int8_t { | ||||
|   INDEX_NONE = -5, | ||||
|   H_PROBE, H_REDUNDANT, H_CHAMBER, H_BED, | ||||
| @ -211,16 +211,6 @@ struct PIDHeaterInfo : public HeaterInfo { | ||||
|   typedef temp_info_t chamber_info_t; | ||||
| #endif | ||||
| 
 | ||||
| // Heater idle handling
 | ||||
| typedef struct { | ||||
|   millis_t timeout_ms; | ||||
|   bool timed_out; | ||||
|   inline void update(const millis_t &ms) { if (!timed_out && timeout_ms && ELAPSED(ms, timeout_ms)) timed_out = true; } | ||||
|   inline void start(const millis_t &ms) { timeout_ms = millis() + ms; timed_out = false; } | ||||
|   inline void reset() { timeout_ms = 0; timed_out = false; } | ||||
|   inline void expire() { start(0); } | ||||
| } hotend_idle_t; | ||||
| 
 | ||||
| // Heater watch handling
 | ||||
| template <int INCREASE, int HYSTERESIS, millis_t PERIOD> | ||||
| struct HeaterWatch { | ||||
| @ -346,9 +336,38 @@ class Temperature { | ||||
|     FORCE_INLINE static bool targetHotEnoughToExtrude(const uint8_t e) { return !targetTooColdToExtrude(e); } | ||||
| 
 | ||||
|     #if HEATER_IDLE_HANDLER | ||||
|       static hotend_idle_t hotend_idle[HOTENDS]; | ||||
|       TERN_(HAS_HEATED_BED, static hotend_idle_t bed_idle); | ||||
|       TERN_(HAS_HEATED_CHAMBER, static hotend_idle_t chamber_idle); | ||||
| 
 | ||||
|       // Heater idle handling. Marlin creates one per hotend and one for the heated bed.
 | ||||
|       typedef struct { | ||||
|         millis_t timeout_ms; | ||||
|         bool timed_out; | ||||
|         inline void update(const millis_t &ms) { if (!timed_out && timeout_ms && ELAPSED(ms, timeout_ms)) timed_out = true; } | ||||
|         inline void start(const millis_t &ms) { timeout_ms = millis() + ms; timed_out = false; } | ||||
|         inline void reset() { timeout_ms = 0; timed_out = false; } | ||||
|         inline void expire() { start(0); } | ||||
|       } heater_idle_t; | ||||
| 
 | ||||
|       // Indices and size for the heater_idle array
 | ||||
|       #define _ENUM_FOR_E(N) IDLE_INDEX_E##N, | ||||
|       enum IdleIndex : uint8_t { | ||||
|         REPEAT(HOTENDS, _ENUM_FOR_E) | ||||
|         #if ENABLED(HAS_HEATED_BED) | ||||
|           IDLE_INDEX_BED, | ||||
|         #endif | ||||
|         NR_HEATER_IDLE | ||||
|       }; | ||||
|       #undef _ENUM_FOR_E | ||||
| 
 | ||||
|       // Convert the given heater_id_t to idle array index
 | ||||
|       static inline IdleIndex idle_index_for_id(const int8_t heater_id) { | ||||
|         #if HAS_HEATED_BED | ||||
|           if (heater_id == H_BED) return IDLE_INDEX_BED; | ||||
|         #endif | ||||
|         return (IdleIndex)_MAX(heater_id, 0); | ||||
|       } | ||||
| 
 | ||||
|       static heater_idle_t heater_idle[NR_HEATER_IDLE]; | ||||
| 
 | ||||
|     #endif | ||||
| 
 | ||||
|   private: | ||||
| @ -747,13 +766,13 @@ class Temperature { | ||||
|     #if HEATER_IDLE_HANDLER | ||||
| 
 | ||||
|       static void reset_hotend_idle_timer(const uint8_t E_NAME) { | ||||
|         hotend_idle[HOTEND_INDEX].reset(); | ||||
|         heater_idle[HOTEND_INDEX].reset(); | ||||
|         start_watching_hotend(HOTEND_INDEX); | ||||
|       } | ||||
| 
 | ||||
|       #if HAS_HEATED_BED | ||||
|         static void reset_bed_idle_timer() { | ||||
|           bed_idle.reset(); | ||||
|           heater_idle[IDLE_INDEX_BED].reset(); | ||||
|           start_watching_bed(); | ||||
|         } | ||||
|       #endif | ||||
| @ -815,22 +834,47 @@ class Temperature { | ||||
|     static void min_temp_error(const heater_id_t e); | ||||
|     static void max_temp_error(const heater_id_t e); | ||||
| 
 | ||||
|     #define HAS_THERMAL_PROTECTION (EITHER(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_CHAMBER) || HAS_THERMALLY_PROTECTED_BED) | ||||
|     #define HAS_THERMAL_PROTECTION ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_CHAMBER, HAS_THERMALLY_PROTECTED_BED) | ||||
| 
 | ||||
|     #if HAS_THERMAL_PROTECTION | ||||
| 
 | ||||
|       // Indices and size for the tr_state_machine array. One for each protected heater.
 | ||||
|       #define _ENUM_FOR_E(N) RUNAWAY_IND_E##N, | ||||
|       enum RunawayIndex : uint8_t { | ||||
|         #if ENABLED(THERMAL_PROTECTION_HOTENDS) | ||||
|           REPEAT(HOTENDS, _ENUM_FOR_E) | ||||
|         #endif | ||||
|         #if ENABLED(HAS_THERMALLY_PROTECTED_BED) | ||||
|           RUNAWAY_IND_BED, | ||||
|         #endif | ||||
|         #if ENABLED(THERMAL_PROTECTION_CHAMBER) | ||||
|           RUNAWAY_IND_CHAMBER, | ||||
|         #endif | ||||
|         NR_HEATER_RUNAWAY | ||||
|       }; | ||||
|       #undef _ENUM_FOR_E | ||||
| 
 | ||||
|       // Convert the given heater_id_t to runaway state array index
 | ||||
|       static inline RunawayIndex runaway_index_for_id(const int8_t heater_id) { | ||||
|         #if HAS_THERMALLY_PROTECTED_CHAMBER | ||||
|           if (heater_id == H_CHAMBER) return RUNAWAY_IND_CHAMBER; | ||||
|         #endif | ||||
|         #if HAS_THERMALLY_PROTECTED_BED | ||||
|           if (heater_id == H_BED) return RUNAWAY_IND_BED; | ||||
|         #endif | ||||
|         return (RunawayIndex)_MAX(heater_id, 0); | ||||
|       } | ||||
| 
 | ||||
|       enum TRState : char { TRInactive, TRFirstHeating, TRStable, TRRunaway }; | ||||
| 
 | ||||
|       typedef struct { | ||||
|         millis_t timer = 0; | ||||
|         TRState state = TRInactive; | ||||
|         float running_temp; | ||||
|         void run(const float ¤t, const float &target, const heater_id_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc); | ||||
|       } tr_state_machine_t; | ||||
| 
 | ||||
|       TERN_(THERMAL_PROTECTION_HOTENDS, static tr_state_machine_t tr_state_machine[HOTENDS]); | ||||
|       TERN_(HAS_THERMALLY_PROTECTED_BED, static tr_state_machine_t tr_state_machine_bed); | ||||
|       TERN_(THERMAL_PROTECTION_CHAMBER, static tr_state_machine_t tr_state_machine_chamber); | ||||
| 
 | ||||
|       static void thermal_runaway_protection(tr_state_machine_t &state, const float ¤t, const float &target, const heater_id_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc); | ||||
|       static tr_state_machine_t tr_state_machine[NR_HEATER_RUNAWAY]; | ||||
| 
 | ||||
|     #endif // HAS_THERMAL_PROTECTION
 | ||||
| }; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user