Browse Source

Cleanup original thermal error handlers.

Remove useless repeated calls to disable heaters and turn on the fans,
since this is done at a higher level.

Avoid repeating messages on the serial. Do it just once.

Make a critical alert sound unconditionally.
Yuri D'Elia 2 years ago
parent
commit
6751586db6
3 changed files with 91 additions and 120 deletions
  1. 4 3
      Firmware/Marlin.h
  2. 28 20
      Firmware/Marlin_main.cpp
  3. 59 97
      Firmware/temperature.cpp

+ 4 - 3
Firmware/Marlin.h

@@ -241,9 +241,10 @@ void prepare_move();
 void kill(const char *full_screen_message = NULL, unsigned char id = 0);
 void finishAndDisableSteppers();
 
-void UnconditionalStop(); // Stop heaters, motion and clear current print status
-void Stop();              // Emergency stop used by overtemp functions which allows recovery
-bool IsStopped();         // Returns true if the print has been stopped
+void UnconditionalStop();             // Stop heaters, motion and clear current print status
+void ThermalStop(bool pause = false); // Emergency stop used by overtemp functions which allows
+                                      // recovery (with pause=true)
+bool IsStopped();                     // Returns true if the print has been stopped
 
 //put an ASCII command at the end of the current buffer, read from flash
 #define enquecommand_P(cmd) enquecommand(cmd, true)

+ 28 - 20
Firmware/Marlin_main.cpp

@@ -9967,7 +9967,9 @@ void UnconditionalStop()
     CRITICAL_SECTION_END;
 }
 
-// Stop: Emergency stop used by overtemp functions which allows recovery
+// Emergency stop used by overtemp functions which allows recovery
+//
+//   This function is called *continuously* during a thermal failure.
 //
 //   In addition to stopping the print, this prevents subsequent G[0-3] commands to be
 //   processed via USB (using "Stopped") until the print is resumed via M999 or
@@ -9977,29 +9979,35 @@ void UnconditionalStop()
 //   will introduce either over/under extrusion on the current segment, and will not
 //   survive a power panic. Switching Stop() to use the pause machinery instead (with
 //   the addition of disabling the headers) could allow true recovery in the future.
-void Stop()
+void ThermalStop(bool pause)
 {
-  // Keep disabling heaters
-  disable_heater();
+    if(Stopped == false) {
+        Stopped = true;
+        if(pause && (IS_SD_PRINTING || usb_timer.running())) {
+            if (!isPrintPaused) {
+                // we cannot make a distinction for an host here, the pause must be instantaneous
+                lcd_pause_print();
+            }
+        } else {
+            // We got a hard thermal error and/or there is no print going on. Just stop.
+            lcd_print_stop();
+        }
+        Stopped_gcode_LastN = gcode_LastN; // Save last g_code for "restart"
 
-  // Call the regular stop function if that's the first time during a new print
-  if(Stopped == false) {
-    Stopped = true;
-    lcd_print_stop();
-    Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
+        // Eventually report the stopped status (though this is usually overridden by a
+        // higher-priority alert status message)
+        SERIAL_ERROR_START;
+        SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
+        LCD_MESSAGERPGM(_T(MSG_STOPPED));
 
-    // Eventually report the stopped status (though this is usually overridden by a
-    // higher-priority alert status message)
-    SERIAL_ERROR_START;
-    SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
-    LCD_MESSAGERPGM(_T(MSG_STOPPED));
-  }
+        Sound_MakeCustom(1000,0,true);
+    }
 
-  // Return to the status screen to stop any pending menu action which could have been
-  // started by the user while stuck in the Stopped state. This also ensures the NEW
-  // error is immediately shown.
-  if (menu_menu != lcd_status_screen)
-      lcd_return_to_status();
+    // Return to the status screen to stop any pending menu action which could have been
+    // started by the user while stuck in the Stopped state. This also ensures the NEW
+    // error is immediately shown.
+    if (menu_menu != lcd_status_screen)
+        lcd_return_to_status();
 }
 
 bool IsStopped() { return Stopped; };

+ 59 - 97
Firmware/temperature.cpp

@@ -842,7 +842,7 @@ void soft_pwm_init()
 }
 
 #if (defined (TEMP_RUNAWAY_BED_HYSTERESIS) && TEMP_RUNAWAY_BED_TIMEOUT > 0) || (defined (TEMP_RUNAWAY_EXTRUDER_HYSTERESIS) && TEMP_RUNAWAY_EXTRUDER_TIMEOUT > 0)
-void temp_runaway_check(uint8_t _heater_id, float _target_temperature, float _current_temperature, float _output, bool _isbed)
+static void temp_runaway_check(uint8_t _heater_id, float _target_temperature, float _current_temperature, float _output, bool _isbed)
 {
 	float __delta;
 	float __hysteresis = 0;
@@ -851,7 +851,6 @@ void temp_runaway_check(uint8_t _heater_id, float _target_temperature, float _cu
 	static float __preheat_start[2] = { 0,0}; //currently just bed and one extruder
 	static uint8_t __preheat_counter[2] = { 0,0};
 	static uint8_t __preheat_errors[2] = { 0,0};
-		
 
 	if (_millis() - temp_runaway_timer[_heater_id] > 2000)
 	{
@@ -974,32 +973,32 @@ void temp_runaway_check(uint8_t _heater_id, float _target_temperature, float _cu
 	}
 }
 
-void temp_runaway_stop(bool isPreheat, bool isBed)
+static void temp_runaway_stop(bool isPreheat, bool isBed)
 {
-    disable_heater();
-    Sound_MakeCustom(200,0,true);
-
-    if (isPreheat)
-	{
-		lcd_setalertstatuspgm(isBed? PSTR("BED PREHEAT ERROR") : PSTR("PREHEAT ERROR"), LCD_STATUS_CRITICAL);
-		SERIAL_ERROR_START;
-		isBed ? SERIAL_ERRORLNPGM(" THERMAL RUNAWAY (PREHEAT HEATBED)") : SERIAL_ERRORLNPGM(" THERMAL RUNAWAY (PREHEAT HOTEND)");
-
-        hotendFanSetFullSpeed();
-	}
-	else
-	{
-		lcd_setalertstatuspgm(isBed? PSTR("BED THERMAL RUNAWAY") : PSTR("THERMAL RUNAWAY"), LCD_STATUS_CRITICAL);
-		SERIAL_ERROR_START;
-		isBed ? SERIAL_ERRORLNPGM(" HEATBED THERMAL RUNAWAY") : SERIAL_ERRORLNPGM(" HOTEND THERMAL RUNAWAY");
-	}
-
-    Stop();
-
-    if (farm_mode) {
-        prusa_statistics(0);
-        prusa_statistics(isPreheat? 91 : 90);
+    if(IsStopped() == false) {
+        if (isPreheat) {
+            lcd_setalertstatuspgm(isBed? PSTR("BED PREHEAT ERROR") : PSTR("PREHEAT ERROR"), LCD_STATUS_CRITICAL);
+            SERIAL_ERROR_START;
+            if (isBed) {
+                SERIAL_ERRORLNPGM(" THERMAL RUNAWAY (PREHEAT HEATBED)");
+            } else {
+                SERIAL_ERRORLNPGM(" THERMAL RUNAWAY (PREHEAT HOTEND)");
+            }
+        } else {
+            lcd_setalertstatuspgm(isBed? PSTR("BED THERMAL RUNAWAY") : PSTR("THERMAL RUNAWAY"), LCD_STATUS_CRITICAL);
+            SERIAL_ERROR_START;
+            if (isBed) {
+                SERIAL_ERRORLNPGM(" HEATBED THERMAL RUNAWAY");
+            } else {
+                SERIAL_ERRORLNPGM(" HOTEND THERMAL RUNAWAY");
+            }
+        }
+        if (farm_mode) {
+            prusa_statistics(0);
+            prusa_statistics(isPreheat? 91 : 90);
+        }
     }
+    ThermalStop();
 }
 #endif
 
@@ -1011,12 +1010,12 @@ enum { LCDALERT_NONE = 0, LCDALERT_HEATERMINTEMP, LCDALERT_BEDMINTEMP, LCDALERT_
 
 //! remember the last alert message sent to the LCD
 //! to prevent flicker and improve speed
-uint8_t last_alert_sent_to_lcd = LCDALERT_NONE;
+static uint8_t last_alert_sent_to_lcd = LCDALERT_NONE;
 
 
 //! update the current temperature error message
 //! @param type short error abbreviation (PROGMEM)
-void temp_update_messagepgm(const char* PROGMEM type)
+static void temp_update_messagepgm(const char* PROGMEM type)
 {
     char msg[LCD_WIDTH];
     strcpy_P(msg, PSTR("Err: "));
@@ -1027,7 +1026,7 @@ void temp_update_messagepgm(const char* PROGMEM type)
 //! signal a temperature error on both the lcd and serial
 //! @param type short error abbreviation (PROGMEM)
 //! @param e optional extruder index for hotend errors
-void temp_error_messagepgm(const char* PROGMEM type, uint8_t e = EXTRUDERS)
+static void temp_error_messagepgm(const char* PROGMEM type, uint8_t e = EXTRUDERS)
 {
     temp_update_messagepgm(type);
 
@@ -1044,60 +1043,38 @@ void temp_error_messagepgm(const char* PROGMEM type, uint8_t e = EXTRUDERS)
 }
 
 
-void max_temp_error(uint8_t e) {
-  disable_heater();
-  if(IsStopped() == false) {
-    temp_error_messagepgm(PSTR("MAXTEMP"), e);
-  }
-  #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
-  Stop();
-  #endif
-
-  hotendFanSetFullSpeed();
-  if (farm_mode) { prusa_statistics(93); }
-}
-
-void min_temp_error(uint8_t e) {
-#ifdef DEBUG_DISABLE_MINTEMP
-	return;
+static void max_temp_error(uint8_t e) {
+    if(IsStopped() == false) {
+        temp_error_messagepgm(PSTR("MAXTEMP"), e);
+        if (farm_mode) prusa_statistics(93);
+    }
+#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
+    ThermalStop();
 #endif
-  disable_heater();
-//if (current_temperature_ambient < MINTEMP_MINAMBIENT) return;
-	static const char err[] PROGMEM = "MINTEMP";
-  if(IsStopped() == false) {
-    temp_error_messagepgm(err, e);
-    last_alert_sent_to_lcd = LCDALERT_HEATERMINTEMP;
-  } else if( last_alert_sent_to_lcd != LCDALERT_HEATERMINTEMP ){ // only update, if the lcd message is to be changed (i.e. not the same as last time)
-	// we are already stopped due to some error, only update the status message without flickering
-    temp_update_messagepgm(err);
-	last_alert_sent_to_lcd = LCDALERT_HEATERMINTEMP;
-  }
-  #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
-//	if( last_alert_sent_to_lcd != LCDALERT_HEATERMINTEMP ){
-//		last_alert_sent_to_lcd = LCDALERT_HEATERMINTEMP;
-//		lcd_print_stop();
-//	}
-  Stop();
-  #endif
-  if (farm_mode) { prusa_statistics(92); }
+}
 
+static void min_temp_error(uint8_t e) {
+    static const char err[] PROGMEM = "MINTEMP";
+    if(IsStopped() == false) {
+        temp_error_messagepgm(err, e);
+        last_alert_sent_to_lcd = LCDALERT_HEATERMINTEMP;
+        if (farm_mode) prusa_statistics(92);
+    } else if( last_alert_sent_to_lcd != LCDALERT_HEATERMINTEMP ){ // only update, if the lcd message is to be changed (i.e. not the same as last time)
+        // we are already stopped due to some error, only update the status message without flickering
+        temp_update_messagepgm(err);
+        last_alert_sent_to_lcd = LCDALERT_HEATERMINTEMP;
+    }
+    ThermalStop();
 }
 
-void bed_max_temp_error(void) {
-  disable_heater();
-  if(IsStopped() == false) {
-    temp_error_messagepgm(PSTR("MAXTEMP BED"));
-  }
-  #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
-  Stop();
-  #endif
+static void bed_max_temp_error(void) {
+    if(IsStopped() == false) {
+        temp_error_messagepgm(PSTR("MAXTEMP BED"));
+    }
+    ThermalStop();
 }
 
-void bed_min_temp_error(void) {
-#ifdef DEBUG_DISABLE_MINTEMP
-	return;
-#endif
-    disable_heater();
+static void bed_min_temp_error(void) {
     static const char err[] PROGMEM = "MINTEMP BED";
     if(IsStopped() == false) {
         temp_error_messagepgm(err);
@@ -1107,34 +1084,23 @@ void bed_min_temp_error(void) {
         temp_update_messagepgm(err);
 		last_alert_sent_to_lcd = LCDALERT_BEDMINTEMP;
     }
-#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
-    Stop();
-#endif
+    ThermalStop();
 }
 
 
 #ifdef AMBIENT_THERMISTOR
-void ambient_max_temp_error(void) {
-    disable_heater();
+static void ambient_max_temp_error(void) {
     if(IsStopped() == false) {
         temp_error_messagepgm(PSTR("MAXTEMP AMB"));
     }
-#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
-    Stop();
-#endif
+    ThermalStop();
 }
 
-void ambient_min_temp_error(void) {
-#ifdef DEBUG_DISABLE_MINTEMP
-	return;
-#endif
-    disable_heater();
+static void ambient_min_temp_error(void) {
     if(IsStopped() == false) {
         temp_error_messagepgm(PSTR("MINTEMP AMB"));
     }
-#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
-    Stop();
-#endif
+    ThermalStop();
 }
 #endif
 
@@ -1713,10 +1679,6 @@ void check_min_temp_ambient()
 
 void handle_temp_error()
 {
-    // TODO: Stop and the various *_error() functions need an overhaul!
-    // The heaters are kept disabled already at a higher level, making almost
-    // all the code inside the invidual handlers useless!
-
     // relay to the original handler
     switch((TempErrorType)temp_error_state.type) {
     case TempErrorType::min: