From 820d2b58b3cfe16affd421f4925ae924cb60826f Mon Sep 17 00:00:00 2001 From: Martin Turski Date: Fri, 4 Aug 2023 04:40:38 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=B8=20Option=20to=20report=20temperatu?= =?UTF-8?q?re=20on=20error=20(#25341)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/src/core/language.h | 2 + Marlin/src/module/temperature.cpp | 137 +++++++++++++++++++----------- Marlin/src/module/temperature.h | 12 ++- 3 files changed, 100 insertions(+), 51 deletions(-) diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index b76a3d301c..649f05cf69 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -249,6 +249,8 @@ #define STR_LASER_TEMP "laser temperature" #define STR_STOPPED_HEATER ", system stopped! Heater_ID: " +#define STR_DETECTED_TEMP_B " (temp: " +#define STR_DETECTED_TEMP_E ")" #define STR_REDUNDANCY "Heater switched off. Temperature difference between temp sensors is too high !" #define STR_T_HEATING_FAILED "Heating failed" #define STR_T_THERMAL_RUNAWAY "Thermal Runaway" diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index d7c764540b..1f9928f88e 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -839,10 +839,10 @@ volatile bool Temperature::raw_temps_ready = false; if (current_temp > watch_temp_target) heated = true; // - Flag if target temperature reached } else if (ELAPSED(ms, temp_change_ms)) // Watch timer expired - _temp_error(heater_id, FPSTR(str_t_heating_failed), GET_TEXT_F(MSG_HEATING_FAILED_LCD)); + _TEMP_ERROR(heater_id, FPSTR(str_t_heating_failed), MSG_HEATING_FAILED_LCD, current_temp); } else if (current_temp < target - (MAX_OVERSHOOT_PID_AUTOTUNE)) // Heated, then temperature fell too far? - _temp_error(heater_id, FPSTR(str_t_thermal_runaway), GET_TEXT_F(MSG_THERMAL_RUNAWAY)); + _TEMP_ERROR(heater_id, FPSTR(str_t_thermal_runaway), MSG_THERMAL_RUNAWAY, current_temp); } #endif } // every 2 seconds @@ -1467,8 +1467,10 @@ inline void loud_kill(FSTR_P const lcd_msg, const heater_id_t heater_id) { kill(lcd_msg, HEATER_FSTR(heater_id)); } -void Temperature::_temp_error(const heater_id_t heater_id, FSTR_P const serial_msg, FSTR_P const lcd_msg) { - +void Temperature::_temp_error( + const heater_id_t heater_id, FSTR_P const serial_msg, FSTR_P const lcd_msg + OPTARG(ERR_INCLUDE_TEMP, const celsius_float_t deg) +) { static uint8_t killed = 0; if (IsRunning() && TERN1(BOGUS_TEMPERATURE_GRACE_PERIOD, killed == 2)) { @@ -1493,10 +1495,13 @@ void Temperature::_temp_error(const heater_id_t heater_id, FSTR_P const serial_m OPTCODE(HAS_TEMP_CHAMBER, case H_CHAMBER: SERIAL_ECHOPGM(STR_HEATER_CHAMBER); break) OPTCODE(HAS_TEMP_BED, case H_BED: SERIAL_ECHOPGM(STR_HEATER_BED); break) default: - if (real_heater_id >= 0) - SERIAL_ECHOLNPGM("E", real_heater_id); + if (real_heater_id >= 0) SERIAL_ECHO('E', real_heater_id); } - SERIAL_EOL(); + #if ENABLED(ERR_INCLUDE_TEMP) + SERIAL_ECHOLNPGM(STR_DETECTED_TEMP_B, deg, STR_DETECTED_TEMP_E); + #else + SERIAL_EOL(); + #endif } disable_all_heaters(); // always disable (even for bogus temp) @@ -1525,18 +1530,18 @@ void Temperature::_temp_error(const heater_id_t heater_id, FSTR_P const serial_m #endif } -void Temperature::maxtemp_error(const heater_id_t heater_id) { +void Temperature::maxtemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_TEMP, const celsius_float_t deg)) { #if HAS_DWIN_E3V2_BASIC && (HAS_HOTEND || HAS_HEATED_BED) dwinPopupTemperature(1); #endif - _temp_error(heater_id, F(STR_T_MAXTEMP), GET_TEXT_F(MSG_ERR_MAXTEMP)); + _TEMP_ERROR(heater_id, F(STR_T_MAXTEMP), MSG_ERR_MAXTEMP, deg); } -void Temperature::mintemp_error(const heater_id_t heater_id) { +void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_TEMP, const celsius_float_t deg)) { #if HAS_DWIN_E3V2_BASIC && (HAS_HOTEND || HAS_HEATED_BED) dwinPopupTemperature(0); #endif - _temp_error(heater_id, F(STR_T_MINTEMP), GET_TEXT_F(MSG_ERR_MINTEMP)); + _TEMP_ERROR(heater_id, F(STR_T_MINTEMP), MSG_ERR_MINTEMP, deg); } #if HAS_PID_DEBUG @@ -1736,7 +1741,10 @@ void Temperature::mintemp_error(const heater_id_t heater_id) { void Temperature::manage_hotends(const millis_t &ms) { HOTEND_LOOP() { #if ENABLED(THERMAL_PROTECTION_HOTENDS) - if (degHotend(e) > temp_range[e].maxtemp) maxtemp_error((heater_id_t)e); + { + const auto deg = degHotend(e); + if (deg > temp_range[e].maxtemp) MAXTEMP_ERROR(e, deg); + } #endif TERN_(HEATER_IDLE_HANDLER, heater_idle[e].update(ms)); @@ -1746,16 +1754,18 @@ void Temperature::mintemp_error(const heater_id_t heater_id) { 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_hotend_preheating(e)) && temp_hotend[e].celsius < temp_range[e].maxtemp ? (int)get_pid_output_hotend(e) >> 1 : 0; + temp_hotend[e].soft_pwm_amount = (temp_hotend[e].celsius > temp_range[e].mintemp || is_hotend_preheating(e)) + && temp_hotend[e].celsius < temp_range[e].maxtemp ? (int)get_pid_output_hotend(e) >> 1 : 0; #if WATCH_HOTENDS // Make sure temperature is increasing if (watch_hotend[e].elapsed(ms)) { // Enabled and time to check? - if (watch_hotend[e].check(degHotend(e))) // Increased enough? + auto temp = degHotend(e); + if (watch_hotend[e].check(temp)) // Increased enough? start_watching_hotend(e); // If temp reached, turn off elapsed check else { TERN_(HAS_DWIN_E3V2_BASIC, dwinPopupTemperature(0)); - _temp_error((heater_id_t)e, FPSTR(str_t_heating_failed), GET_TEXT_F(MSG_HEATING_FAILED_LCD)); + _TEMP_ERROR(e, FPSTR(str_t_heating_failed), MSG_HEATING_FAILED_LCD, temp); } } #endif @@ -1770,19 +1780,25 @@ void Temperature::mintemp_error(const heater_id_t heater_id) { void Temperature::manage_heated_bed(const millis_t &ms) { #if ENABLED(THERMAL_PROTECTION_BED) - if (degBed() > BED_MAXTEMP) maxtemp_error(H_BED); + { + const auto deg = degBed(); + if (deg > BED_MAXTEMP) MAXTEMP_ERROR(H_BED, deg); + } #endif #if WATCH_BED + { // Make sure temperature is increasing if (watch_bed.elapsed(ms)) { // Time to check the bed? - if (watch_bed.check(degBed())) // Increased enough? + const auto deg = degBed(); + if (watch_bed.check(deg)) // Increased enough? start_watching_bed(); // If temp reached, turn off elapsed check else { TERN_(HAS_DWIN_E3V2_BASIC, dwinPopupTemperature(0)); - _temp_error(H_BED, FPSTR(str_t_heating_failed), GET_TEXT_F(MSG_HEATING_FAILED_LCD)); + _TEMP_ERROR(H_BED, FPSTR(str_t_heating_failed), MSG_HEATING_FAILED_LCD, deg); } } + } #endif // WATCH_BED #if ALL(PROBING_HEATERS_OFF, BED_LIMIT_SWITCHING) @@ -1860,17 +1876,23 @@ void Temperature::mintemp_error(const heater_id_t heater_id) { #endif #if ENABLED(THERMAL_PROTECTION_CHAMBER) - if (degChamber() > (CHAMBER_MAXTEMP)) maxtemp_error(H_CHAMBER); + { + const auto deg = degChamber(); + if (deg > CHAMBER_MAXTEMP) MAXTEMP_ERROR(H_CHAMBER, deg); + } #endif #if WATCH_CHAMBER + { // Make sure temperature is increasing if (watch_chamber.elapsed(ms)) { // Time to check the chamber? - if (watch_chamber.check(degChamber())) // Increased enough? Error below. + const auto deg = degChamber(); + if (watch_chamber.check(deg)) // Increased enough? Error below. start_watching_chamber(); // If temp reached, turn off elapsed check. else - _temp_error(H_CHAMBER, FPSTR(str_t_heating_failed), GET_TEXT_F(MSG_HEATING_FAILED_LCD)); + _TEMP_ERROR(H_CHAMBER, FPSTR(str_t_heating_failed), MSG_HEATING_FAILED_LCD, deg); } + } #endif #if ANY(CHAMBER_FAN, CHAMBER_VENT) || DISABLED(PIDTEMPCHAMBER) @@ -1986,16 +2008,20 @@ void Temperature::mintemp_error(const heater_id_t heater_id) { #endif #if ENABLED(THERMAL_PROTECTION_COOLER) - if (degCooler() > COOLER_MAXTEMP) maxtemp_error(H_COOLER); + { + const auto deg = degCooler(); + if (deg > COOLER_MAXTEMP) MAXTEMP_ERROR(H_COOLER, deg); + } #endif #if WATCH_COOLER // Make sure temperature is decreasing if (watch_cooler.elapsed(ms)) { // Time to check the cooler? - if (degCooler() > watch_cooler.target) // Failed to decrease enough? - _temp_error(H_COOLER, GET_TEXT_F(MSG_COOLING_FAILED), GET_TEXT_F(MSG_COOLING_FAILED)); + const auto deg = degCooler(); + if (deg > watch_cooler.target) // Failed to decrease enough? + _TEMP_ERROR(H_COOLER, GET_TEXT_F(MSG_COOLING_FAILED), MSG_COOLING_FAILED, deg); else - start_watching_cooler(); // Start again if the target is still far off + start_watching_cooler(); // Start again if the target is still far off } #endif @@ -2076,20 +2102,32 @@ void Temperature::task() { #if DISABLED(IGNORE_THERMOCOUPLE_ERRORS) #if TEMP_SENSOR_IS_MAX_TC(0) - if (degHotend(0) > _MIN(HEATER_0_MAXTEMP, TEMP_SENSOR_0_MAX_TC_TMAX - 1.0)) maxtemp_error(H_E0); - if (degHotend(0) < _MAX(HEATER_0_MINTEMP, TEMP_SENSOR_0_MAX_TC_TMIN + .01)) mintemp_error(H_E0); + { + const auto deg = degHotend(0); + if (deg > _MIN(HEATER_0_MAXTEMP, TEMP_SENSOR_0_MAX_TC_TMAX - 1.0)) MAXTEMP_ERROR(H_E0, deg); + if (deg < _MAX(HEATER_0_MINTEMP, TEMP_SENSOR_0_MAX_TC_TMIN + .01)) MINTEMP_ERROR(H_E0, deg); + } #endif #if TEMP_SENSOR_IS_MAX_TC(1) - if (degHotend(1) > _MIN(HEATER_1_MAXTEMP, TEMP_SENSOR_1_MAX_TC_TMAX - 1.0)) maxtemp_error(H_E1); - if (degHotend(1) < _MAX(HEATER_1_MINTEMP, TEMP_SENSOR_1_MAX_TC_TMIN + .01)) mintemp_error(H_E1); + { + const auto deg = degHotend(1); + if (deg > _MIN(HEATER_1_MAXTEMP, TEMP_SENSOR_1_MAX_TC_TMAX - 1.0)) MAXTEMP_ERROR(H_E1, deg); + if (deg < _MAX(HEATER_1_MINTEMP, TEMP_SENSOR_1_MAX_TC_TMIN + .01)) MINTEMP_ERROR(H_E1, deg); + } #endif #if TEMP_SENSOR_IS_MAX_TC(2) - if (degHotend(2) > _MIN(HEATER_2_MAXTEMP, TEMP_SENSOR_2_MAX_TC_TMAX - 1.0)) maxtemp_error(H_E2); - if (degHotend(2) < _MAX(HEATER_2_MINTEMP, TEMP_SENSOR_2_MAX_TC_TMIN + .01)) mintemp_error(H_E2); + { + const auto deg = degHotend(2); + if (deg > _MIN(HEATER_2_MAXTEMP, TEMP_SENSOR_2_MAX_TC_TMAX - 1.0)) MAXTEMP_ERROR(H_E2, deg); + if (deg < _MAX(HEATER_2_MINTEMP, TEMP_SENSOR_2_MAX_TC_TMIN + .01)) MINTEMP_ERROR(H_E2, deg); + } #endif #if TEMP_SENSOR_IS_MAX_TC(REDUNDANT) - if (degRedundant() > TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX - 1.0) maxtemp_error(H_REDUNDANT); - if (degRedundant() < TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN + .01) mintemp_error(H_REDUNDANT); + { + const auto deg = degRedundant(); + if (deg > TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX - 1.0) MAXTEMP_ERROR(H_REDUNDANT, deg); + if (deg < TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN + .01) MINTEMP_ERROR(H_REDUNDANT, deg); + } #endif #else #warning "Safety Alert! Disable IGNORE_THERMOCOUPLE_ERRORS for the final build!" @@ -2101,9 +2139,12 @@ void Temperature::task() { TERN_(HAS_HOTEND, manage_hotends(ms)); #if HAS_TEMP_REDUNDANT + { + const auto deg = degRedundant(); // Make sure measured temperatures are close together - if (ABS(degRedundantTarget() - degRedundant()) > TEMP_SENSOR_REDUNDANT_MAX_DIFF) - _temp_error((heater_id_t)HEATER_ID(TEMP_SENSOR_REDUNDANT_TARGET), F(STR_REDUNDANCY), GET_TEXT_F(MSG_ERR_REDUNDANT_TEMP)); + if (ABS(degRedundantTarget() - deg) > TEMP_SENSOR_REDUNDANT_MAX_DIFF) + _TEMP_ERROR(HEATER_ID(TEMP_SENSOR_REDUNDANT_TARGET), F(STR_REDUNDANCY), MSG_ERR_REDUNDANT_TEMP, deg); + } #endif // Manage extruder auto fans and/or read fan tachometers @@ -2616,7 +2657,7 @@ void Temperature::updateTemperaturesFromRawValues() { const raw_adc_t r = temp_hotend[e].getraw(); const bool neg = temp_dir[e] < 0, pos = temp_dir[e] > 0; if ((neg && r < temp_range[e].raw_max) || (pos && r > temp_range[e].raw_max)) - maxtemp_error((heater_id_t)e); + MAXTEMP_ERROR(e, temp_hotend[e].celsius); /** // DEBUG PREHEATING TIME @@ -2628,7 +2669,7 @@ void Temperature::updateTemperaturesFromRawValues() { const bool heater_on = temp_hotend[e].target > 0; if (heater_on && !is_hotend_preheating(e) && ((neg && r > temp_range[e].raw_min) || (pos && r < temp_range[e].raw_min))) { if (TERN1(MULTI_MAX_CONSECUTIVE_LOW_TEMP_ERR, ++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED)) - mintemp_error((heater_id_t)e); + MINTEMP_ERROR(e, temp_hotend[e].celsius); } else { TERN_(MULTI_MAX_CONSECUTIVE_LOW_TEMP_ERR, consecutive_low_temperature_error[e] = 0); @@ -2639,27 +2680,27 @@ void Temperature::updateTemperaturesFromRawValues() { #define TP_CMP(S,A,B) (TEMPDIR(S) < 0 ? ((A)<(B)) : ((A)>(B))) #if ENABLED(THERMAL_PROTECTION_BED) - if (TP_CMP(BED, temp_bed.getraw(), maxtemp_raw_BED)) maxtemp_error(H_BED); - if (temp_bed.target > 0 && !is_bed_preheating() && TP_CMP(BED, mintemp_raw_BED, temp_bed.getraw())) mintemp_error(H_BED); + if (TP_CMP(BED, temp_bed.getraw(), maxtemp_raw_BED)) MAXTEMP_ERROR(H_BED, temp_bed.celsius); + if (temp_bed.target > 0 && !is_bed_preheating() && TP_CMP(BED, mintemp_raw_BED, temp_bed.getraw())) MINTEMP_ERROR(H_BED, temp_bed.celsius); #endif #if ALL(HAS_HEATED_CHAMBER, THERMAL_PROTECTION_CHAMBER) - if (TP_CMP(CHAMBER, temp_chamber.getraw(), maxtemp_raw_CHAMBER)) maxtemp_error(H_CHAMBER); - if (temp_chamber.target > 0 && TP_CMP(CHAMBER, mintemp_raw_CHAMBER, temp_chamber.getraw())) mintemp_error(H_CHAMBER); + if (TP_CMP(CHAMBER, temp_chamber.getraw(), maxtemp_raw_CHAMBER)) MAXTEMP_ERROR(H_CHAMBER, temp_chamber.celsius); + if (temp_chamber.target > 0 && TP_CMP(CHAMBER, mintemp_raw_CHAMBER, temp_chamber.getraw())) MINTEMP_ERROR(H_CHAMBER, temp_chamber.celsius); #endif #if ALL(HAS_COOLER, THERMAL_PROTECTION_COOLER) - if (cutter.unitPower > 0 && TP_CMP(COOLER, temp_cooler.getraw(), maxtemp_raw_COOLER)) maxtemp_error(H_COOLER); - if (TP_CMP(COOLER, mintemp_raw_COOLER, temp_cooler.getraw())) mintemp_error(H_COOLER); + if (cutter.unitPower > 0 && TP_CMP(COOLER, temp_cooler.getraw(), maxtemp_raw_COOLER)) MAXTEMP_ERROR(H_COOLER, temp_cooler.celsius); + if (TP_CMP(COOLER, mintemp_raw_COOLER, temp_cooler.getraw())) MINTEMP_ERROR(H_COOLER, temp_cooler.celsius); #endif #if ALL(HAS_TEMP_BOARD, THERMAL_PROTECTION_BOARD) - if (TP_CMP(BOARD, temp_board.getraw(), maxtemp_raw_BOARD)) maxtemp_error(H_BOARD); - if (TP_CMP(BOARD, mintemp_raw_BOARD, temp_board.getraw())) mintemp_error(H_BOARD); + if (TP_CMP(BOARD, temp_board.getraw(), maxtemp_raw_BOARD)) MAXTEMP_ERROR(H_BOARD, temp_board.celsius); + if (TP_CMP(BOARD, mintemp_raw_BOARD, temp_board.getraw())) MINTEMP_ERROR(H_BOARD, temp_board.celsius); #endif #if ALL(HAS_TEMP_SOC, THERMAL_PROTECTION_SOC) - if (TP_CMP(SOC, temp_soc.getraw(), maxtemp_raw_SOC)) maxtemp_error(H_SOC); + if (TP_CMP(SOC, temp_soc.getraw(), maxtemp_raw_SOC)) MAXTEMP_ERROR(H_SOC, temp_soc.celsius); #endif #undef TP_CMP @@ -3178,12 +3219,12 @@ void Temperature::init() { case TRRunaway: TERN_(HAS_DWIN_E3V2_BASIC, dwinPopupTemperature(0)); - _temp_error(heater_id, FPSTR(str_t_thermal_runaway), GET_TEXT_F(MSG_THERMAL_RUNAWAY)); + _TEMP_ERROR(heater_id, FPSTR(str_t_thermal_runaway), MSG_THERMAL_RUNAWAY, current); #if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR) case TRMalfunction: TERN_(HAS_DWIN_E3V2_BASIC, dwinPopupTemperature(0)); - _temp_error(heater_id, FPSTR(str_t_temp_malfunction), GET_TEXT_F(MSG_TEMP_MALFUNCTION)); + _TEMP_ERROR(heater_id, FPSTR(str_t_temp_malfunction), MSG_TEMP_MALFUNCTION, current); #endif } } diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index a8873bf2af..d5a27a8671 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -41,6 +41,8 @@ #include "../feature/fancheck.h" #endif +//#define ERR_INCLUDE_TEMP + #define HOTEND_INDEX TERN(HAS_MULTI_HOTEND, e, 0) #define E_NAME TERN_(HAS_MULTI_HOTEND, e) @@ -1360,9 +1362,13 @@ class Temperature { static float get_pid_output_chamber(); #endif - static void _temp_error(const heater_id_t e, FSTR_P const serial_msg, FSTR_P const lcd_msg); - static void mintemp_error(const heater_id_t e); - static void maxtemp_error(const heater_id_t e); + static void _temp_error(const heater_id_t e, FSTR_P const serial_msg, FSTR_P const lcd_msg OPTARG(ERR_INCLUDE_TEMP, const celsius_float_t deg)); + static void mintemp_error(const heater_id_t e OPTARG(ERR_INCLUDE_TEMP, const celsius_float_t deg)); + static void maxtemp_error(const heater_id_t e OPTARG(ERR_INCLUDE_TEMP, const celsius_float_t deg)); + + #define _TEMP_ERROR(e, m, l, d) _temp_error(heater_id_t(e), m, GET_TEXT_F(l) OPTARG(ERR_INCLUDE_TEMP, d)) + #define MINTEMP_ERROR(e, d) mintemp_error(heater_id_t(e) OPTARG(ERR_INCLUDE_TEMP, d)) + #define MAXTEMP_ERROR(e, d) maxtemp_error(heater_id_t(e) OPTARG(ERR_INCLUDE_TEMP, d)) #define HAS_THERMAL_PROTECTION ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_COOLER)