Skip to content

Commit 1a7a313

Browse files
authoredDec 14, 2021
Merge pull request prusa3d#3311 from wavexx/temp_runaway_fixes
Ensure THERMAL RUNAWAY / temperature errors stay on-screen
2 parents a7dfe4b + 3849f97 commit 1a7a313

File tree

6 files changed

+85
-67
lines changed

6 files changed

+85
-67
lines changed
 

‎Firmware/Marlin.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,12 @@ void update_currents();
236236
void get_coordinates();
237237
void prepare_move();
238238
void kill(const char *full_screen_message = NULL, unsigned char id = 0);
239-
void Stop();
240-
bool IsStopped();
241239
void finishAndDisableSteppers();
242240

241+
void UnconditionalStop(); // Stop heaters, motion and clear current print status
242+
void Stop(); // Emergency stop used by overtemp functions which allows recovery
243+
bool IsStopped(); // Returns true if the print has been stopped
244+
243245
//put an ASCII command at the end of the current buffer, read from flash
244246
#define enquecommand_P(cmd) enquecommand(cmd, true)
245247

‎Firmware/Marlin_main.cpp

+40-2
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ uint8_t newFanSpeed = 0;
294294
bool powersupply = true;
295295
#endif
296296

297-
bool cancel_heatup = false ;
297+
bool cancel_heatup = false;
298298

299299
int8_t busy_state = NOT_BUSY;
300300
static long prev_busy_signal_ms = -1;
@@ -6751,7 +6751,7 @@ SERIAL_PROTOCOLPGM("\n\n");
67516751
target_direction = isHeatingBed(); // true if heating, false if cooling
67526752

67536753
KEEPALIVE_STATE(NOT_BUSY);
6754-
while ( (target_direction)&&(!cancel_heatup) ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false)) )
6754+
while ( (!cancel_heatup) && (target_direction ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false))) )
67556755
{
67566756
if(( _millis() - codenum) > 1000 ) //Print Temp Reading every 1 second while heating up.
67576757
{
@@ -10154,6 +10154,32 @@ void kill(const char *full_screen_message, unsigned char id)
1015410154
} // Wait for reset
1015510155
}
1015610156

10157+
void UnconditionalStop()
10158+
{
10159+
CRITICAL_SECTION_START;
10160+
10161+
// Disable all heaters and unroll the temperature wait loop stack
10162+
disable_heater();
10163+
cancel_heatup = true;
10164+
10165+
// Clear any saved printing state
10166+
cancel_saved_printing();
10167+
10168+
// Abort the planner
10169+
planner_abort_hard();
10170+
10171+
// Reset the queue
10172+
cmdqueue_reset();
10173+
cmdqueue_serial_disabled = false;
10174+
10175+
// Reset the sd status
10176+
card.sdprinting = false;
10177+
card.closefile();
10178+
10179+
st_reset_timer();
10180+
CRITICAL_SECTION_END;
10181+
}
10182+
1015710183
// Stop: Emergency stop used by overtemp functions which allows recovery
1015810184
//
1015910185
// 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)
1016610192
// the addition of disabling the headers) could allow true recovery in the future.
1016710193
void Stop()
1016810194
{
10195+
// Keep disabling heaters
1016910196
disable_heater();
10197+
10198+
// Call the regular stop function if that's the first time during a new print
1017010199
if(Stopped == false) {
1017110200
Stopped = true;
1017210201
lcd_print_stop();
1017310202
Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
10203+
10204+
// Eventually report the stopped status (though this is usually overridden by a
10205+
// higher-priority alert status message)
1017410206
SERIAL_ERROR_START;
1017510207
SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
1017610208
LCD_MESSAGERPGM(_T(MSG_STOPPED));
1017710209
}
10210+
10211+
// Return to the status screen to stop any pending menu action which could have been
10212+
// started by the user while stuck in the Stopped state. This also ensures the NEW
10213+
// error is immediately shown.
10214+
if (menu_menu != lcd_status_screen)
10215+
lcd_return_to_status();
1017810216
}
1017910217

1018010218
bool IsStopped() { return Stopped; };

‎Firmware/temperature.cpp

+13-32
Original file line numberDiff line numberDiff line change
@@ -1381,33 +1381,15 @@ void temp_runaway_check(int _heater_id, float _target_temperature, float _curren
13811381

13821382
void temp_runaway_stop(bool isPreheat, bool isBed)
13831383
{
1384-
cancel_heatup = true;
1385-
quickStop();
1386-
if (card.sdprinting)
1387-
{
1388-
card.sdprinting = false;
1389-
card.closefile();
1390-
}
1391-
// Clean the input command queue
1392-
// This is necessary, because in command queue there can be commands which would later set heater or bed temperature.
1393-
cmdqueue_reset();
1394-
1395-
disable_heater();
1396-
disable_x();
1397-
disable_y();
1398-
disable_e0();
1399-
disable_e1();
1400-
disable_e2();
1401-
manage_heater();
1402-
lcd_update(0);
1403-
Sound_MakeCustom(200,0,true);
1404-
1405-
if (isPreheat)
1384+
disable_heater();
1385+
Sound_MakeCustom(200,0,true);
1386+
1387+
if (isPreheat)
14061388
{
1407-
Stop();
1408-
isBed ? LCD_ALERTMESSAGEPGM("BED PREHEAT ERROR") : LCD_ALERTMESSAGEPGM("PREHEAT ERROR");
1389+
lcd_setalertstatuspgm(isBed? PSTR("BED PREHEAT ERROR") : PSTR("PREHEAT ERROR"), LCD_STATUS_CRITICAL);
14091390
SERIAL_ERROR_START;
1410-
isBed ? SERIAL_ERRORLNPGM(" THERMAL RUNAWAY ( PREHEAT HEATBED)") : SERIAL_ERRORLNPGM(" THERMAL RUNAWAY ( PREHEAT HOTEND)");
1391+
isBed ? SERIAL_ERRORLNPGM(" THERMAL RUNAWAY (PREHEAT HEATBED)") : SERIAL_ERRORLNPGM(" THERMAL RUNAWAY (PREHEAT HOTEND)");
1392+
14111393
#ifdef EXTRUDER_ALTFAN_DETECT
14121394
altfanStatus.altfanOverride = 1; //full speed
14131395
#endif //EXTRUDER_ALTFAN_DETECT
@@ -1418,16 +1400,16 @@ void temp_runaway_stop(bool isPreheat, bool isBed)
14181400
#else //FAN_SOFT_PWM
14191401
analogWrite(FAN_PIN, 255);
14201402
#endif //FAN_SOFT_PWM
1421-
14221403
fanSpeed = 255;
1423-
delayMicroseconds(2000);
14241404
}
14251405
else
14261406
{
1427-
isBed ? LCD_ALERTMESSAGEPGM("BED THERMAL RUNAWAY") : LCD_ALERTMESSAGEPGM("THERMAL RUNAWAY");
1407+
lcd_setalertstatuspgm(isBed? PSTR("BED THERMAL RUNAWAY") : PSTR("THERMAL RUNAWAY"), LCD_STATUS_CRITICAL);
14281408
SERIAL_ERROR_START;
14291409
isBed ? SERIAL_ERRORLNPGM(" HEATBED THERMAL RUNAWAY") : SERIAL_ERRORLNPGM(" HOTEND THERMAL RUNAWAY");
14301410
}
1411+
1412+
Stop();
14311413
}
14321414
#endif
14331415

@@ -1483,21 +1465,20 @@ uint8_t last_alert_sent_to_lcd = LCDALERT_NONE;
14831465

14841466
//! update the current temperature error message
14851467
//! @param type short error abbreviation (PROGMEM)
1486-
//! @param func optional lcd update function (lcd_setalertstatus when first setting the error)
1487-
void temp_update_messagepgm(const char* PROGMEM type, void (*func)(const char*) = lcd_updatestatus)
1468+
void temp_update_messagepgm(const char* PROGMEM type)
14881469
{
14891470
char msg[LCD_WIDTH];
14901471
strcpy_P(msg, PSTR("Err: "));
14911472
strcat_P(msg, type);
1492-
(*func)(msg);
1473+
lcd_setalertstatus(msg, LCD_STATUS_CRITICAL);
14931474
}
14941475

14951476
//! signal a temperature error on both the lcd and serial
14961477
//! @param type short error abbreviation (PROGMEM)
14971478
//! @param e optional extruder index for hotend errors
14981479
void temp_error_messagepgm(const char* PROGMEM type, uint8_t e = EXTRUDERS)
14991480
{
1500-
temp_update_messagepgm(type, lcd_setalertstatus);
1481+
temp_update_messagepgm(type);
15011482

15021483
SERIAL_ERROR_START;
15031484

‎Firmware/temperature.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ FORCE_INLINE bool isCoolingBed() {
220220
#define CHECK_ALL_HEATERS (checkAllHotends()||(target_temperature_bed!=0))
221221

222222
int getHeaterPower(int heater);
223-
void disable_heater();
223+
void disable_heater(); // Disable all heaters
224224
void updatePID();
225225

226226

‎Firmware/ultralcd.cpp

+17-27
Original file line numberDiff line numberDiff line change
@@ -1399,7 +1399,6 @@ static void lcd_cooldown()
13991399
setAllTargetHotends(0);
14001400
setTargetBed(0);
14011401
fanSpeed = 0;
1402-
eFilamentAction = FilamentAction::None;
14031402
lcd_return_to_status();
14041403
}
14051404

@@ -7090,24 +7089,11 @@ static void lcd_sd_updir()
70907089
void lcd_print_stop()
70917090
{
70927091
if (!card.sdprinting) {
7093-
SERIAL_ECHOLNRPGM(MSG_OCTOPRINT_CANCEL); // for Octoprint
7092+
SERIAL_ECHOLNRPGM(MSG_OCTOPRINT_CANCEL); // for Octoprint
70947093
}
7095-
cmdqueue_serial_disabled = false; //for when canceling a print with a fancheck
7096-
7097-
CRITICAL_SECTION_START;
7098-
7099-
// Clear any saved printing state
7100-
cancel_saved_printing();
7101-
7102-
// Abort the planner/queue/sd
7103-
planner_abort_hard();
7104-
cmdqueue_reset();
7105-
card.sdprinting = false;
7106-
card.closefile();
7107-
st_reset_timer();
7108-
7109-
CRITICAL_SECTION_END;
7094+
UnconditionalStop();
71107095

7096+
// TODO: all the following should be moved in the main marlin loop!
71117097
#ifdef MESH_BED_LEVELING
71127098
mbl.active = false; //also prevents undoing the mbl compensation a second time in the second planner_abort_hard()
71137099
#endif
@@ -7118,11 +7104,11 @@ void lcd_print_stop()
71187104
pause_time = 0;
71197105
save_statistics(total_filament_used, t);
71207106

7107+
// reset current command
71217108
lcd_commands_step = 0;
71227109
lcd_commands_type = LcdCommands::Idle;
71237110

71247111
lcd_cooldown(); //turns off heaters and fan; goes to status screen.
7125-
cancel_heatup = true; //unroll temperature wait loop stack.
71267112

71277113
current_position[Z_AXIS] += 10; //lift Z.
71287114
plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60);
@@ -8604,7 +8590,7 @@ static bool check_file(const char* filename) {
86048590
cmdqueue_serial_disabled = false;
86058591
card.printingHasFinished();
86068592

8607-
strncpy_P(lcd_status_message, _T(WELCOME_MSG), LCD_WIDTH);
8593+
lcd_setstatuspgm(_T(WELCOME_MSG));
86088594
lcd_finishstatus();
86098595
return result;
86108596
}
@@ -8813,18 +8799,22 @@ void lcd_updatestatus(const char *message){
88138799
lcd_draw_update = 1;
88148800
}
88158801

8816-
void lcd_setalertstatuspgm(const char* message)
8802+
void lcd_setalertstatuspgm(const char* message, uint8_t severity)
88178803
{
8818-
lcd_setstatuspgm(message);
8819-
lcd_status_message_level = 1;
8820-
lcd_return_to_status();
8804+
if (severity > lcd_status_message_level) {
8805+
lcd_updatestatuspgm(message);
8806+
lcd_status_message_level = severity;
8807+
lcd_return_to_status();
8808+
}
88218809
}
88228810

8823-
void lcd_setalertstatus(const char* message)
8811+
void lcd_setalertstatus(const char* message, uint8_t severity)
88248812
{
8825-
lcd_setstatus(message);
8826-
lcd_status_message_level = 1;
8827-
lcd_return_to_status();
8813+
if (severity > lcd_status_message_level) {
8814+
lcd_updatestatus(message);
8815+
lcd_status_message_level = severity;
8816+
lcd_return_to_status();
8817+
}
88288818
}
88298819

88308820
void lcd_reset_alert_level()

‎Firmware/ultralcd.h

+10-3
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,20 @@ extern void menu_lcd_lcdupdate_func(void);
1212
void ultralcd_init();
1313
void lcd_setstatus(const char* message);
1414
void lcd_setstatuspgm(const char* message);
15+
16+
//! LCD status severities
17+
#define LCD_STATUS_CRITICAL 2 //< Heater failure
18+
#define LCD_STATUS_ALERT 1 //< Other hardware issue
19+
#define LCD_STATUS_NONE 0 //< No alert message set
20+
1521
//! return to the main status screen and display the alert message
1622
//! Beware - it has sideeffects:
1723
//! - always returns the display to the main status screen
1824
//! - always makes lcd_reset (which is slow and causes flicker)
19-
//! - does not update the message if there is already one (i.e. lcd_status_message_level > 0)
20-
void lcd_setalertstatus(const char* message);
21-
void lcd_setalertstatuspgm(const char* message);
25+
//! - does not update the message if there is one with the same (or higher) severity present
26+
void lcd_setalertstatus(const char* message, uint8_t severity = LCD_STATUS_ALERT);
27+
void lcd_setalertstatuspgm(const char* message, uint8_t severity = LCD_STATUS_ALERT);
28+
2229
//! only update the alert message on the main status screen
2330
//! has no sideeffects, may be called multiple times
2431
void lcd_updatestatus(const char *message);

0 commit comments

Comments
 (0)