Merge pull request #3311 from wavexx/temp_runaway_fixes

Ensure THERMAL RUNAWAY / temperature errors stay on-screen
This commit is contained in:
DRracer 2021-12-14 06:53:27 +01:00 committed by GitHub
commit 1a7a313cbf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 85 additions and 67 deletions

View file

@ -236,10 +236,12 @@ void update_currents();
void get_coordinates();
void prepare_move();
void kill(const char *full_screen_message = NULL, unsigned char id = 0);
void Stop();
bool IsStopped();
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
//put an ASCII command at the end of the current buffer, read from flash
#define enquecommand_P(cmd) enquecommand(cmd, true)

View file

@ -294,7 +294,7 @@ uint8_t newFanSpeed = 0;
bool powersupply = true;
#endif
bool cancel_heatup = false ;
bool cancel_heatup = false;
int8_t busy_state = NOT_BUSY;
static long prev_busy_signal_ms = -1;
@ -6751,7 +6751,7 @@ Sigma_Exit:
target_direction = isHeatingBed(); // true if heating, false if cooling
KEEPALIVE_STATE(NOT_BUSY);
while ( (target_direction)&&(!cancel_heatup) ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false)) )
while ( (!cancel_heatup) && (target_direction ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false))) )
{
if(( _millis() - codenum) > 1000 ) //Print Temp Reading every 1 second while heating up.
{
@ -10154,6 +10154,32 @@ void kill(const char *full_screen_message, unsigned char id)
} // Wait for reset
}
void UnconditionalStop()
{
CRITICAL_SECTION_START;
// Disable all heaters and unroll the temperature wait loop stack
disable_heater();
cancel_heatup = true;
// Clear any saved printing state
cancel_saved_printing();
// Abort the planner
planner_abort_hard();
// Reset the queue
cmdqueue_reset();
cmdqueue_serial_disabled = false;
// Reset the sd status
card.sdprinting = false;
card.closefile();
st_reset_timer();
CRITICAL_SECTION_END;
}
// Stop: Emergency stop used by overtemp functions which allows recovery
//
// In addition to stopping the print, this prevents subsequent G[0-3] commands to be
@ -10166,15 +10192,27 @@ void kill(const char *full_screen_message, unsigned char id)
// the addition of disabling the headers) could allow true recovery in the future.
void Stop()
{
// Keep disabling heaters
disable_heater();
// 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));
}
// 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; };

View file

@ -1381,33 +1381,15 @@ void temp_runaway_check(int _heater_id, float _target_temperature, float _curren
void temp_runaway_stop(bool isPreheat, bool isBed)
{
cancel_heatup = true;
quickStop();
if (card.sdprinting)
disable_heater();
Sound_MakeCustom(200,0,true);
if (isPreheat)
{
card.sdprinting = false;
card.closefile();
}
// Clean the input command queue
// This is necessary, because in command queue there can be commands which would later set heater or bed temperature.
cmdqueue_reset();
disable_heater();
disable_x();
disable_y();
disable_e0();
disable_e1();
disable_e2();
manage_heater();
lcd_update(0);
Sound_MakeCustom(200,0,true);
if (isPreheat)
{
Stop();
isBed ? LCD_ALERTMESSAGEPGM("BED PREHEAT ERROR") : LCD_ALERTMESSAGEPGM("PREHEAT ERROR");
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)");
isBed ? SERIAL_ERRORLNPGM(" THERMAL RUNAWAY (PREHEAT HEATBED)") : SERIAL_ERRORLNPGM(" THERMAL RUNAWAY (PREHEAT HOTEND)");
#ifdef EXTRUDER_ALTFAN_DETECT
altfanStatus.altfanOverride = 1; //full speed
#endif //EXTRUDER_ALTFAN_DETECT
@ -1418,16 +1400,16 @@ void temp_runaway_stop(bool isPreheat, bool isBed)
#else //FAN_SOFT_PWM
analogWrite(FAN_PIN, 255);
#endif //FAN_SOFT_PWM
fanSpeed = 255;
delayMicroseconds(2000);
}
else
{
isBed ? LCD_ALERTMESSAGEPGM("BED THERMAL RUNAWAY") : LCD_ALERTMESSAGEPGM("THERMAL RUNAWAY");
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();
}
#endif
@ -1483,13 +1465,12 @@ uint8_t last_alert_sent_to_lcd = LCDALERT_NONE;
//! update the current temperature error message
//! @param type short error abbreviation (PROGMEM)
//! @param func optional lcd update function (lcd_setalertstatus when first setting the error)
void temp_update_messagepgm(const char* PROGMEM type, void (*func)(const char*) = lcd_updatestatus)
void temp_update_messagepgm(const char* PROGMEM type)
{
char msg[LCD_WIDTH];
strcpy_P(msg, PSTR("Err: "));
strcat_P(msg, type);
(*func)(msg);
lcd_setalertstatus(msg, LCD_STATUS_CRITICAL);
}
//! signal a temperature error on both the lcd and serial
@ -1497,7 +1478,7 @@ void temp_update_messagepgm(const char* PROGMEM type, void (*func)(const char*)
//! @param e optional extruder index for hotend errors
void temp_error_messagepgm(const char* PROGMEM type, uint8_t e = EXTRUDERS)
{
temp_update_messagepgm(type, lcd_setalertstatus);
temp_update_messagepgm(type);
SERIAL_ERROR_START;

View file

@ -220,7 +220,7 @@ FORCE_INLINE bool isCoolingBed() {
#define CHECK_ALL_HEATERS (checkAllHotends()||(target_temperature_bed!=0))
int getHeaterPower(int heater);
void disable_heater();
void disable_heater(); // Disable all heaters
void updatePID();

View file

@ -1399,7 +1399,6 @@ static void lcd_cooldown()
setAllTargetHotends(0);
setTargetBed(0);
fanSpeed = 0;
eFilamentAction = FilamentAction::None;
lcd_return_to_status();
}
@ -7090,24 +7089,11 @@ static void lcd_sd_updir()
void lcd_print_stop()
{
if (!card.sdprinting) {
SERIAL_ECHOLNRPGM(MSG_OCTOPRINT_CANCEL); // for Octoprint
SERIAL_ECHOLNRPGM(MSG_OCTOPRINT_CANCEL); // for Octoprint
}
cmdqueue_serial_disabled = false; //for when canceling a print with a fancheck
CRITICAL_SECTION_START;
// Clear any saved printing state
cancel_saved_printing();
// Abort the planner/queue/sd
planner_abort_hard();
cmdqueue_reset();
card.sdprinting = false;
card.closefile();
st_reset_timer();
CRITICAL_SECTION_END;
UnconditionalStop();
// TODO: all the following should be moved in the main marlin loop!
#ifdef MESH_BED_LEVELING
mbl.active = false; //also prevents undoing the mbl compensation a second time in the second planner_abort_hard()
#endif
@ -7118,11 +7104,11 @@ void lcd_print_stop()
pause_time = 0;
save_statistics(total_filament_used, t);
// reset current command
lcd_commands_step = 0;
lcd_commands_type = LcdCommands::Idle;
lcd_cooldown(); //turns off heaters and fan; goes to status screen.
cancel_heatup = true; //unroll temperature wait loop stack.
current_position[Z_AXIS] += 10; //lift Z.
plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60);
@ -8604,7 +8590,7 @@ static bool check_file(const char* filename) {
cmdqueue_serial_disabled = false;
card.printingHasFinished();
strncpy_P(lcd_status_message, _T(WELCOME_MSG), LCD_WIDTH);
lcd_setstatuspgm(_T(WELCOME_MSG));
lcd_finishstatus();
return result;
}
@ -8813,18 +8799,22 @@ void lcd_updatestatus(const char *message){
lcd_draw_update = 1;
}
void lcd_setalertstatuspgm(const char* message)
void lcd_setalertstatuspgm(const char* message, uint8_t severity)
{
lcd_setstatuspgm(message);
lcd_status_message_level = 1;
lcd_return_to_status();
if (severity > lcd_status_message_level) {
lcd_updatestatuspgm(message);
lcd_status_message_level = severity;
lcd_return_to_status();
}
}
void lcd_setalertstatus(const char* message)
void lcd_setalertstatus(const char* message, uint8_t severity)
{
lcd_setstatus(message);
lcd_status_message_level = 1;
lcd_return_to_status();
if (severity > lcd_status_message_level) {
lcd_updatestatus(message);
lcd_status_message_level = severity;
lcd_return_to_status();
}
}
void lcd_reset_alert_level()

View file

@ -12,13 +12,20 @@ extern void menu_lcd_lcdupdate_func(void);
void ultralcd_init();
void lcd_setstatus(const char* message);
void lcd_setstatuspgm(const char* message);
//! LCD status severities
#define LCD_STATUS_CRITICAL 2 //< Heater failure
#define LCD_STATUS_ALERT 1 //< Other hardware issue
#define LCD_STATUS_NONE 0 //< No alert message set
//! return to the main status screen and display the alert message
//! Beware - it has sideeffects:
//! - always returns the display to the main status screen
//! - always makes lcd_reset (which is slow and causes flicker)
//! - does not update the message if there is already one (i.e. lcd_status_message_level > 0)
void lcd_setalertstatus(const char* message);
void lcd_setalertstatuspgm(const char* message);
//! - does not update the message if there is one with the same (or higher) severity present
void lcd_setalertstatus(const char* message, uint8_t severity = LCD_STATUS_ALERT);
void lcd_setalertstatuspgm(const char* message, uint8_t severity = LCD_STATUS_ALERT);
//! only update the alert message on the main status screen
//! has no sideeffects, may be called multiple times
void lcd_updatestatus(const char *message);