PFW-1522 Fix an issue where MMU unloads while nozzle is cold if print is stopped

In the case of a Fan Error, the print is paused. If the nozzle is allowed to cool for a while before the print is stopped via the LCD, then the MMU will try to unload with a cold nozzle.

This can happen with ANY recoverable thermal errors.

In this commit I attempt to fix all scenarios. Including PFW-1544 where the nozzle is cooling down when the print has finished normally.

PFW-1544
PFW-1552

Change in memory:
Flash: +74 bytes
SRAM: 0 bytes
This commit is contained in:
gudnimg 2024-01-27 11:53:46 +00:00
parent c0b76dd5cf
commit f022567239
4 changed files with 47 additions and 9 deletions

View File

@ -197,6 +197,7 @@ void kill(const char *full_screen_message = NULL);
void finishAndDisableSteppers(); void finishAndDisableSteppers();
void UnconditionalStop(); // Stop heaters, motion and clear current print status void UnconditionalStop(); // Stop heaters, motion and clear current print status
void ConditionalStop(); // Similar to UnconditionalStop, but doesn't disable heaters
void ThermalStop(bool allow_pause = false); // Emergency stop used by overtemp functions which allows void ThermalStop(bool allow_pause = false); // Emergency stop used by overtemp functions which allows
// recovery (with pause=true) // recovery (with pause=true)
bool IsStopped(); // Returns true if the print has been stopped bool IsStopped(); // Returns true if the print has been stopped

View File

@ -9755,6 +9755,28 @@ void UnconditionalStop()
st_reset_timer(); st_reset_timer();
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
// clear paused state immediately
did_pause_print = false;
print_job_timer.stop();
}
void ConditionalStop()
{
CRITICAL_SECTION_START;
// Clear any saved printing state
cancel_saved_printing();
// Abort the planner
planner_abort_hard();
// Reset the queue
cmdqueue_reset();
cmdqueue_serial_disabled = false;
st_reset_timer();
CRITICAL_SECTION_END;
} }
// Emergency stop used by overtemp functions which allows recovery // Emergency stop used by overtemp functions which allows recovery
@ -9789,7 +9811,7 @@ void ThermalStop(bool allow_recovery)
} }
} else { } else {
// We got a hard thermal error and/or there is no print going on. Just stop. // We got a hard thermal error and/or there is no print going on. Just stop.
print_stop(); print_stop(false, true);
} }
// Report the error on the serial // Report the error on the serial

View File

@ -5656,6 +5656,7 @@ void retract_for_ooze_prevention() {
// continue stopping the print from the main loop after lcd_print_stop() is called // continue stopping the print from the main loop after lcd_print_stop() is called
void lcd_print_stop_finish() void lcd_print_stop_finish()
{ {
print_job_timer.stop();
save_statistics(); save_statistics();
// lift Z // lift Z
@ -5688,26 +5689,40 @@ void lcd_print_stop_finish()
if (MMU2::mmu2.Enabled() && MMU2::mmu2.FindaDetectsFilament()) if (MMU2::mmu2.Enabled() && MMU2::mmu2.FindaDetectsFilament())
{ {
// The print was aborted while when the nozzle was cold:
// 1. in a paused state => a partial backup in RAM is always available
// 2. after a recoverable thermal/fan error had paused the print => only extruder temperature is saved to RAM
if (printingIsPaused()) if (printingIsPaused())
{ {
// Restore temperature saved in ram after pausing print // Restore temperature saved in ram after pausing print
restore_extruder_temperature_from_ram(); restore_extruder_temperature_from_ram();
} }
MMU2::mmu2.unload(); // M702
// If the pause state was cleared previously or the target temperature is 0°C in the case
// of an unconditional stop. In that scenario we do not want to unload.
if (target_temperature[0] >= extrude_min_temp) {
MMU2::mmu2.unload(); // M702
}
} }
lcd_cooldown(); //turns off heaters and fan; goes to status screen. lcd_cooldown(); //turns off heaters and fan; goes to status screen.
finishAndDisableSteppers(); //M84 finishAndDisableSteppers(); //M84
axis_relative_modes = E_AXIS_MASK; //XYZ absolute, E relative axis_relative_modes = E_AXIS_MASK; //XYZ absolute, E relative
did_pause_print = false; // Clear pause state in case the print was aborted while paused
} }
void print_stop(bool interactive) void print_stop(bool interactive, bool unconditional_stop)
{ {
// UnconditionalStop() will internally cause planner_abort_hard(), meaning we _cannot_ plan any // UnconditionalStop() will internally cause planner_abort_hard(), meaning we _cannot_ plan any
// more move in this call! Any further move must happen inside lcd_print_stop_finish(), which is // more move in this call! Any further move must happen inside lcd_print_stop_finish(), which is
// called by the main loop one iteration later. // called by the main loop one iteration later.
UnconditionalStop(); if (unconditional_stop) {
UnconditionalStop();
} else {
// Allow lcd_print_stop_finish() to use the heaters when it is safe
ConditionalStop();
}
if (card.sdprinting) { if (card.sdprinting) {
// Reset the sd status // Reset the sd status
@ -5721,10 +5736,6 @@ void print_stop(bool interactive)
mbl.active = false; mbl.active = false;
#endif #endif
// clear any pending paused state immediately
did_pause_print = false;
print_job_timer.stop();
if (interactive) { if (interactive) {
// acknowledged by the user from the LCD: resume processing USB commands again // acknowledged by the user from the LCD: resume processing USB commands again
Stopped = false; Stopped = false;

View File

@ -60,7 +60,11 @@ void lcd_pause_usb_print();
void lcd_send_action_start(); void lcd_send_action_start();
void lcd_resume_print(); void lcd_resume_print();
void lcd_print_stop(); // interactive print stop void lcd_print_stop(); // interactive print stop
void print_stop(bool interactive=false);
/// @brief Stop the print immediately
/// @param interactive True if the user acknowledged the action from the LCD: resume processing USB commands again
/// @param unconditional_stop True when the print is stopped by a serious error condition e.g. Thermal Runaway. False otherwise.
void print_stop(bool interactive=false, bool unconditional_stop=false);
#ifdef THERMAL_MODEL #ifdef THERMAL_MODEL
void lcd_thermal_model_cal(); void lcd_thermal_model_cal();
#endif //THERMAL_MODEL #endif //THERMAL_MODEL