Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temperature feedback through serial on error #25341

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Marlin/src/core/language.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
137 changes: 89 additions & 48 deletions Marlin/src/module/temperature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)) {
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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));
Expand All @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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!"
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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

Expand Down Expand Up @@ -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
}
}
Expand Down
12 changes: 9 additions & 3 deletions Marlin/src/module/temperature.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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)

Expand Down
Loading