First pass, improving the error recovery.
This commit is contained in:
parent
1e391f303c
commit
9a20c85a5d
|
|
@ -91,7 +91,7 @@ MMU2::MMU2()
|
|||
, resume_hotend_temp(0)
|
||||
, logicStepLastStatus(StepStatus::Finished)
|
||||
, state(xState::Stopped)
|
||||
, mmu_print_saved(false)
|
||||
, mmu_print_saved(SavedState::None)
|
||||
, loadFilamentStarted(false)
|
||||
, loadingToNozzle(false)
|
||||
{
|
||||
|
|
@ -458,15 +458,14 @@ void MMU2::Home(uint8_t mode){
|
|||
}
|
||||
|
||||
void MMU2::SaveAndPark(bool move_axes, bool turn_off_nozzle) {
|
||||
if (!mmu_print_saved) { // First occurrence. Save current position, park print head, disable nozzle heater.
|
||||
if (mmu_print_saved == SavedState::None) { // First occurrence. Save current position, park print head, disable nozzle heater.
|
||||
LogEchoEvent("Saving and parking");
|
||||
st_synchronize();
|
||||
|
||||
mmu_print_saved = true;
|
||||
|
||||
|
||||
resume_hotend_temp = degTargetHotend(active_extruder);
|
||||
|
||||
if (move_axes){
|
||||
mmu_print_saved |= SavedState::ParkExtruder;
|
||||
// save current pos
|
||||
for(uint8_t i = 0; i < 3; ++i){
|
||||
resume_position.xyz[i] = current_position[i];
|
||||
|
|
@ -487,6 +486,7 @@ void MMU2::SaveAndPark(bool move_axes, bool turn_off_nozzle) {
|
|||
}
|
||||
|
||||
if (turn_off_nozzle){
|
||||
mmu_print_saved |= SavedState::Cooldown;
|
||||
LogEchoEvent("Heater off");
|
||||
setAllTargetHotends(0);
|
||||
}
|
||||
|
|
@ -496,35 +496,37 @@ void MMU2::SaveAndPark(bool move_axes, bool turn_off_nozzle) {
|
|||
// gcode.reset_stepper_timeout();
|
||||
}
|
||||
|
||||
void MMU2::ResumeAndUnPark(bool move_axes, bool turn_off_nozzle) {
|
||||
if (mmu_print_saved) {
|
||||
LogEchoEvent("Resuming print");
|
||||
void MMU2::ResumeHotendTemp() {
|
||||
if ((mmu_print_saved & SavedState::Cooldown) && resume_hotend_temp) {
|
||||
LogEchoEvent("Resuming Temp");
|
||||
MMU2_ECHO_MSG("Restoring hotend temperature ");
|
||||
SERIAL_ECHOLN(resume_hotend_temp);
|
||||
setTargetHotend(resume_hotend_temp, active_extruder);
|
||||
lcd_display_message_fullscreen_P(_i("MMU OK. Resuming temperature...")); // better report the event and let the GUI do its work somewhere else
|
||||
ReportErrorHookSensorLineRender();
|
||||
waitForHotendTargetTemp(1000, []{
|
||||
ReportErrorHookDynamicRender();
|
||||
});
|
||||
LogEchoEvent("Hotend temperature reached");
|
||||
lcd_update_enable(true); // temporary hack to stop this locking the printer...
|
||||
}
|
||||
}
|
||||
|
||||
if (turn_off_nozzle && resume_hotend_temp) {
|
||||
MMU2_ECHO_MSG("Restoring hotend temperature ");
|
||||
SERIAL_ECHOLN(resume_hotend_temp);
|
||||
setTargetHotend(resume_hotend_temp, active_extruder);
|
||||
waitForHotendTargetTemp(3000, []{
|
||||
lcd_display_message_fullscreen_P(_i("MMU OK. Resuming temperature...")); // better report the event and let the GUI do its work somewhere else
|
||||
});
|
||||
LogEchoEvent("Hotend temperature reached");
|
||||
lcd_update_enable(true); // temporary hack to stop this locking the printer...
|
||||
}
|
||||
void MMU2::ResumeUnpark()
|
||||
{
|
||||
if (mmu_print_saved & SavedState::ParkExtruder) {
|
||||
LogEchoEvent("Resuming XYZ");
|
||||
|
||||
if (move_axes) {
|
||||
LogEchoEvent("Resuming XYZ");
|
||||
|
||||
current_position[X_AXIS] = resume_position.xyz[X_AXIS];
|
||||
current_position[Y_AXIS] = resume_position.xyz[Y_AXIS];
|
||||
plan_buffer_line_curposXYZE(NOZZLE_PARK_XY_FEEDRATE);
|
||||
st_synchronize();
|
||||
|
||||
current_position[Z_AXIS] = resume_position.xyz[Z_AXIS];
|
||||
plan_buffer_line_curposXYZE(NOZZLE_PARK_Z_FEEDRATE);
|
||||
st_synchronize();
|
||||
} else {
|
||||
LogEchoEvent("NOT resuming XYZ");
|
||||
}
|
||||
current_position[X_AXIS] = resume_position.xyz[X_AXIS];
|
||||
current_position[Y_AXIS] = resume_position.xyz[Y_AXIS];
|
||||
plan_buffer_line_curposXYZE(NOZZLE_PARK_XY_FEEDRATE);
|
||||
st_synchronize();
|
||||
|
||||
current_position[Z_AXIS] = resume_position.xyz[Z_AXIS];
|
||||
plan_buffer_line_curposXYZE(NOZZLE_PARK_Z_FEEDRATE);
|
||||
st_synchronize();
|
||||
} else {
|
||||
LogEchoEvent("NOT resuming XYZ");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -534,6 +536,7 @@ void MMU2::CheckUserInput(){
|
|||
case Left:
|
||||
case Middle:
|
||||
case Right:
|
||||
ResumeHotendTemp(); // Recover the hotend temp before we attempt to do anything else...
|
||||
Button(btn);
|
||||
break;
|
||||
case RestartMMU:
|
||||
|
|
@ -559,7 +562,7 @@ void MMU2::CheckUserInput(){
|
|||
/// But - in case of an error, the command is not yet finished, but we must react accordingly - move the printhead elsewhere, stop heating, eat a cat or so.
|
||||
/// That's what's being done here...
|
||||
void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
||||
mmu_print_saved = false;
|
||||
mmu_print_saved = SavedState::None;
|
||||
|
||||
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
||||
|
||||
|
|
@ -577,7 +580,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
|||
case Finished:
|
||||
// command/operation completed, let Marlin continue its work
|
||||
// the E may have some more moves to finish - wait for them
|
||||
ResumeAndUnPark(move_axes, turn_off_nozzle); // This is needed here otherwise recovery doesn't work.
|
||||
ResumeUnpark(); // We can now travel back to the tower or wherever we were when we saved.
|
||||
st_synchronize();
|
||||
return;
|
||||
case VersionMismatch: // this basically means the MMU will be disabled until reconnected
|
||||
|
|
@ -591,7 +594,8 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
|||
break;
|
||||
case CommunicationRecovered: // @@TODO communication recovered and may be an error recovered as well
|
||||
// may be the logic layer can detect the change of state a respond with one "Recovered" to be handled here
|
||||
ResumeAndUnPark(move_axes, turn_off_nozzle);
|
||||
ResumeHotendTemp();
|
||||
ResumeUnpark();
|
||||
break;
|
||||
case Processing: // wait for the MMU to respond
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -58,6 +58,13 @@ public:
|
|||
ResetPin = 1, ///< trigger the reset pin of the MMU
|
||||
CutThePower = 2 ///< power off and power on (that includes +5V and +24V power lines)
|
||||
};
|
||||
|
||||
/// Saved print state on error.
|
||||
enum SavedState: uint8_t {
|
||||
None = 0, // No state saved.
|
||||
ParkExtruder = 1, // The extruder was parked.
|
||||
Cooldown = 2, // The extruder was allowed to cool.
|
||||
};
|
||||
|
||||
/// Perform a reset of the MMU
|
||||
/// @param level physical form of the reset
|
||||
|
|
@ -143,7 +150,7 @@ public:
|
|||
bool is_mmu_error_monitor_active;
|
||||
|
||||
/// Method to read-only mmu_print_saved
|
||||
bool MMU_PRINT_SAVED() const { return mmu_print_saved; }
|
||||
bool MMU_PRINT_SAVED() const { return mmu_print_saved != SavedState::None; }
|
||||
|
||||
private:
|
||||
/// Perform software self-reset of the MMU (sends an X0 command)
|
||||
|
|
@ -193,8 +200,11 @@ private:
|
|||
/// Save print and park the print head
|
||||
void SaveAndPark(bool move_axes, bool turn_off_nozzle);
|
||||
|
||||
/// Resume print (unpark, turn on heating etc.)
|
||||
void ResumeAndUnPark(bool move_axes, bool turn_off_nozzle);
|
||||
/// Resume hotend temperature, if it was cooled. Safe to call if we aren't saved.
|
||||
void ResumeHotendTemp();
|
||||
|
||||
/// Resume position, if the extruder was parked. Safe to all if state was not saved.
|
||||
void ResumeUnpark();
|
||||
|
||||
/// Check for any button/user input coming from the printer's UI
|
||||
void CheckUserInput();
|
||||
|
|
@ -220,7 +230,7 @@ private:
|
|||
|
||||
enum xState state;
|
||||
|
||||
bool mmu_print_saved;
|
||||
uint8_t mmu_print_saved;
|
||||
bool loadFilamentStarted;
|
||||
|
||||
friend struct LoadingToNozzleRAII;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ enum class ResponseMsgParamCodes : uint8_t {
|
|||
Error = 'E',
|
||||
Finished = 'F',
|
||||
Accepted = 'A',
|
||||
Rejected = 'R'
|
||||
Rejected = 'R',
|
||||
Button = 'B' // the MMU registered a button press and is sending it to the printer for processing
|
||||
};
|
||||
|
||||
/// A request message - requests are being sent by the printer into the MMU.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ void EndReport(CommandInProgress cip, uint16_t ec) {
|
|||
* @brief Renders any characters that will be updated live on the MMU error screen.
|
||||
*Currently, this is FINDA and Filament Sensor status and Extruder temperature.
|
||||
*/
|
||||
static void ReportErrorHookDynamicRender(void)
|
||||
extern void ReportErrorHookDynamicRender(void)
|
||||
{
|
||||
lcd_set_cursor(3, 2);
|
||||
lcd_printf_P(PSTR("%d"), mmu2.FindaDetectsFilament());
|
||||
|
|
@ -78,17 +78,23 @@ static void ReportErrorHookStaticRender(uint8_t ei) {
|
|||
lcd_update_enable(false);
|
||||
lcd_clear();
|
||||
|
||||
ReportErrorHookSensorLineRender();
|
||||
|
||||
// Print title and header
|
||||
lcd_printf_P(PSTR("%.20S\nprusa3d.com/ERR04%hu"), _T(PrusaErrorTitle(ei)), PrusaErrorCode(ei) );
|
||||
|
||||
// Render static characters in third line
|
||||
lcd_set_cursor(0, 2);
|
||||
lcd_printf_P(PSTR("FI: FS: > %c %c"), LCD_STR_THERMOMETER[0], LCD_STR_DEGREE[0]);
|
||||
|
||||
// Render the choices
|
||||
lcd_show_choices_prompt_P(two_choices ? LCD_LEFT_BUTTON_CHOICE : LCD_MIDDLE_BUTTON_CHOICE, _T(PrusaErrorButtonTitle(button_op_middle)), _T(two_choices ? PrusaErrorButtonMore() : PrusaErrorButtonTitle(button_op_right)), two_choices ? 10 : 7, two_choices ? nullptr : _T(PrusaErrorButtonMore()));
|
||||
}
|
||||
|
||||
extern void ReportErrorHookSensorLineRender()
|
||||
{
|
||||
// Render static characters in third line
|
||||
lcd_set_cursor(0, 2);
|
||||
lcd_printf_P(PSTR("FI: FS: > %c %c"), LCD_STR_THERMOMETER[0], LCD_STR_DEGREE[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Monitors the LCD button selection without blocking MMU communication
|
||||
* @param[in] ei Error code index
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ void ReportErrorHook(uint16_t ec);
|
|||
/// Called when the MMU sends operation progress update
|
||||
void ReportProgressHook(CommandInProgress cip, uint16_t ec);
|
||||
|
||||
/// Remders the sensor status line. Also used by the "resume temperature" screen.
|
||||
void ReportErrorHookDynamicRender();
|
||||
|
||||
/// Renders the static part of the sensor state line. Also used by "resuming temperature screen"
|
||||
void ReportErrorHookSensorLineRender();
|
||||
|
||||
/// @returns true if the MMU is communicating and available
|
||||
/// can change at runtime
|
||||
bool MMUAvailable();
|
||||
|
|
|
|||
Loading…
Reference in New Issue