From 9850ba0cbd61aae3b19140ed47629097e724621e Mon Sep 17 00:00:00 2001 From: Rowan Meara Date: Sun, 29 Oct 2017 02:34:47 -0700 Subject: [PATCH] [1.1.x] Fix M303 thermal protection #8103 (#8126) * Fixed M303 thermal protection The temperature sanity checking logic was not being applied during M303 (pid autotuning) because instead of setting a target temperature, it directly manipulated the pwm values. When PIDTEMP/PIDTEMPBED is enabled, PWM values rather than the target temperature determine whether the heater is on. I changed this to look directly at the PWM amount when pid is enabled. * Turn off heaters on M303 error Currently, PID autotuning stops if it overshoots the temperature by 20C or if if the temperature does not change for 20 minutes and it times out. I added calls to disable the heaters in these scenarios. * Removed unnecessary if statement. Added changes suggested by GMagician. * Update temperature.cpp * Update temperature.cpp * Update temperature.cpp --- Marlin/temperature.cpp | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index 9eb098f8d..11a3ed8bc 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -269,7 +269,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], // PID Tuning loop while (wait_for_heatup) { - millis_t ms = millis(); + const millis_t ms = millis(); if (temp_meas_ready) { // temp sample ready updateTemperaturesFromRawValues(); @@ -384,21 +384,21 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], #define MAX_OVERSHOOT_PID_AUTOTUNE 20 if (input > temp + MAX_OVERSHOOT_PID_AUTOTUNE) { SERIAL_PROTOCOLLNPGM(MSG_PID_TEMP_TOO_HIGH); - return; + break; } // Every 2 seconds... - if (ELAPSED(ms, temp_ms + 2000UL)) { + if (ELAPSED(ms, temp_ms)) { #if HAS_TEMP_HOTEND || HAS_TEMP_BED print_heaterstates(); SERIAL_EOL(); #endif - temp_ms = ms; + temp_ms = ms + 2000UL; } // every 2 seconds - // Over 2 minutes? - if (((ms - t1) + (ms - t2)) > (10L * 60L * 1000L * 2L)) { + // Timeout after 20 minutes since the last undershoot/overshoot cycle + if (((ms - t1) + (ms - t2)) > (20L * 60L * 1000L)) { SERIAL_PROTOCOLLNPGM(MSG_PID_TIMEOUT); - return; + break; } if (cycles > ncycles) { SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED); @@ -447,7 +447,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], } lcd_update(); } - if (!wait_for_heatup) disable_all_heaters(); + disable_all_heaters(); } #endif // HAS_PID_HEATING @@ -2067,8 +2067,15 @@ void Temperature::isr() { for (uint8_t e = 0; e < COUNT(temp_dir); e++) { const int16_t tdir = temp_dir[e], rawtemp = current_temperature_raw[e] * tdir; - if (rawtemp > maxttemp_raw[e] * tdir && target_temperature[e] > 0) max_temp_error(e); - if (rawtemp < minttemp_raw[e] * tdir && !is_preheating(e) && target_temperature[e] > 0) { + const bool heater_on = 0 < + #if ENABLED(PIDTEMP) + soft_pwm_amount[e] + #else + target_temperature[e] + #endif + ; + if (rawtemp > maxttemp_raw[e] * tdir && heater_on) max_temp_error(e); + if (rawtemp < minttemp_raw[e] * tdir && !is_preheating(e) && heater_on) { #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) #endif @@ -2086,8 +2093,15 @@ void Temperature::isr() { #else #define GEBED >= #endif - if (current_temperature_bed_raw GEBED bed_maxttemp_raw && target_temperature_bed > 0) max_temp_error(-1); - if (bed_minttemp_raw GEBED current_temperature_bed_raw && target_temperature_bed > 0) min_temp_error(-1); + const bool bed_on = 0 < + #if ENABLED(PIDTEMPBED) + soft_pwm_amount_bed + #else + target_temperature_bed + #endif + ; + if (current_temperature_bed_raw GEBED bed_maxttemp_raw && bed_on) max_temp_error(-1); + if (bed_minttemp_raw GEBED current_temperature_bed_raw && bed_on) min_temp_error(-1); #endif } // temp_count >= OVERSAMPLENR