From 8ceda27cdab58dc904fd052362611d509f3fcdcf Mon Sep 17 00:00:00 2001 From: Panayiotis-git Date: Thu, 30 Nov 2023 13:01:14 +0200 Subject: [PATCH] Provide option to repeat the M600 unload/load filament sequence --- Firmware/Marlin.h | 2 +- Firmware/Marlin_main.cpp | 137 +++++++++++++++++++++------------------ Firmware/ultralcd.cpp | 31 +++++---- 3 files changed, 89 insertions(+), 81 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 14d89907e..0c3dce4ea 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -446,7 +446,7 @@ void gcode_M701(float fastLoadLength, uint8_t mmuSlotIndex); void M600_load_filament(); void M600_load_filament_movements(); void M600_wait_for_user(); -void M600_check_state(); +bool M600_check_state_and_repeat(); void load_filament_final_feed(); void marlin_wait_for_click(); float raise_z(float delta); diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index c91d309dd..4416b7278 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3435,17 +3435,19 @@ static void gcode_M600(const bool automatic, const float x_position, const float plan_buffer_line_curposXYZE(FILAMENTCHANGE_XYFEED); st_synchronize(); - // Unload filament - if (MMU2::mmu2.Enabled()) { - eject_slot = MMU2::mmu2.get_current_tool(); - mmu_M600_unload_filament(); - } else { - // Beep, manage nozzle heater and wait for user to start unload filament - M600_wait_for_user(); - unload_filament(e_shift_late); - } - st_synchronize(); // finish moves - { + bool repeat = false; + do { + // Unload filament + if (MMU2::mmu2.Enabled()) { + eject_slot = MMU2::mmu2.get_current_tool(); + mmu_M600_unload_filament(); + } else { + // Beep, manage nozzle heater and wait for user to start unload filament + M600_wait_for_user(); + unload_filament(e_shift_late); + } + st_synchronize(); // finish moves + FSensorBlockRunout fsBlockRunout; if (!MMU2::mmu2.Enabled()) @@ -3453,10 +3455,11 @@ static void gcode_M600(const bool automatic, const float x_position, const float KEEPALIVE_STATE(PAUSED_FOR_USER); uint8_t choice = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Was filament unload successful?"), false, LCD_LEFT_BUTTON_CHOICE); ////MSG_UNLOAD_SUCCESSFUL c=20 r=3 + lcd_update_enable(false); if (choice == LCD_MIDDLE_BUTTON_CHOICE) { lcd_clear(); lcd_puts_at_P(0, 2, _T(MSG_PLEASE_WAIT)); - current_position[X_AXIS] -= 100; + current_position[X_AXIS] = 100; plan_buffer_line_curposXYZE(FILAMENTCHANGE_XYFEED); st_synchronize(); lcd_show_fullscreen_message_and_wait_P(_i("Please open idler and remove filament manually.")); ////MSG_CHECK_IDLER c=20 r=4 @@ -3469,51 +3472,54 @@ static void gcode_M600(const bool automatic, const float x_position, const float mmu_M600_load_filament(automatic); } if (!automatic) - M600_check_state(); - - lcd_update_enable(true); - - // Not let's go back to print - fanSpeed = saved_fan_speed; - - // Feed a little of filament to stabilize pressure - if (!automatic) { - if (print_job_timer.isPaused()) - { - // Return to retracted state during a pause - // @todo is retraction really needed? E-position is reverted a few lines below - current_position[E_AXIS] -= default_retraction; - plan_buffer_line_curposXYZE(FILAMENTCHANGE_RFEED); - - // Cooldown the extruder again - setTargetHotend(0); - } - else - { - // Feed a little of filament to stabilize pressure - current_position[E_AXIS] += FILAMENTCHANGE_RECFEED; - plan_buffer_line_curposXYZE(FILAMENTCHANGE_EXFEED); - } - } - - // Move XY back - plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_XYFEED); - st_synchronize(); - - // Move Z back - plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], saved_pos[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_ZFEED); - st_synchronize(); - - // Set E position to original - plan_set_e_position(saved_pos[E_AXIS]); - - memcpy(current_position, saved_pos, sizeof(saved_pos)); - set_destination_to_current(); - - // Recover feed rate - feedmultiply = saved_feedmultiply2; - enquecommandf_P(MSG_M220, saved_feedmultiply2); + repeat = M600_check_state_and_repeat(); + } + while (repeat); + + lcd_update_enable(true); + + // Not let's go back to print + fanSpeed = saved_fan_speed; + + // Feed a little of filament to stabilize pressure + if (!automatic) { + if (print_job_timer.isPaused()) + { + // Return to retracted state during a pause + // @todo is retraction really needed? E-position is reverted a few lines below + current_position[E_AXIS] -= default_retraction; + plan_buffer_line_curposXYZE(FILAMENTCHANGE_RFEED); + + // Cooldown the extruder again + setTargetHotend(0); + } + else + { + // Feed a little of filament to stabilize pressure + current_position[E_AXIS] += FILAMENTCHANGE_RECFEED; + plan_buffer_line_curposXYZE(FILAMENTCHANGE_EXFEED); + } + } + + // Move XY back + plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_XYFEED); + st_synchronize(); + + // Move Z back + plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], saved_pos[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_ZFEED); + st_synchronize(); + + // Set E position to original + plan_set_e_position(saved_pos[E_AXIS]); + + memcpy(current_position, saved_pos, sizeof(saved_pos)); + set_destination_to_current(); + + // Recover feed rate + feedmultiply = saved_feedmultiply2; + enquecommandf_P(MSG_M220, saved_feedmultiply2); + if (print_job_timer.isPaused()) lcd_setstatuspgm(_T(MSG_PRINT_PAUSED)); else lcd_setstatuspgm(MSG_WELCOME); custom_message_type = CustomMsg::Status; @@ -10970,10 +10976,10 @@ void load_filament_final_feed() } //! @brief Wait for user to check the state -void M600_check_state() +bool M600_check_state_and_repeat() { - uint8_t lcd_change_filament_state = 0; - while (lcd_change_filament_state != 1) + uint8_t lcd_change_filament_state = 10; + while (lcd_change_filament_state != 0 && lcd_change_filament_state != 3) { KEEPALIVE_STATE(PAUSED_FOR_USER); lcd_change_filament_state = lcd_alright(); @@ -10981,7 +10987,7 @@ void M600_check_state() switch(lcd_change_filament_state) { // Filament failed to load so load it again - case 2: + case 1: if (MMU2::mmu2.Enabled()) { uint8_t eject_slot = MMU2::mmu2.get_current_tool(); @@ -10999,19 +11005,24 @@ void M600_check_state() break; // Filament loaded properly but color is not clear - case 3: + case 2: st_synchronize(); load_filament_final_feed(); lcd_loading_color(); st_synchronize(); break; + // Unload filament + case 3: + return true; + // Everything good default: lcd_change_success(); break; } } + return false; } //! @brief Wait for user action @@ -11096,11 +11107,9 @@ void M600_load_filament() { } KEEPALIVE_STATE(IN_HANDLER); - M600_load_filament_movements(); + M600_load_filament_movements(); Sound_MakeCustom(50,1000,false); - - lcd_update_enable(false); } diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index f31b56b31..0e4d27976 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2179,14 +2179,14 @@ void lcd_loading_filament() { uint8_t lcd_alright() { - uint8_t cursor_pos = 1; + uint8_t cursor_pos = 0; lcd_clear(); - lcd_puts_at_P(0, 0, _i("Changed correctly?"));////MSG_CORRECTLY c=20 - lcd_puts_at_P(1, 1, _T(MSG_YES)); - lcd_puts_at_P(1, 2, _i("Filament not loaded"));////MSG_NOT_LOADED c=19 - lcd_puts_at_P(1, 3, _i("Color not correct"));////MSG_NOT_COLOR c=19 - lcd_putc_at(0, 1, '>'); + lcd_puts_at_P(1, 0, _i("Changed correctly"));////MSG_CORRECTLY c=20 + lcd_puts_at_P(1, 1, _i("Filament not loaded"));////MSG_NOT_LOADED c=19 + lcd_puts_at_P(1, 2, _i("Color not correct"));////MSG_NOT_COLOR c=19 + lcd_puts_at_P(1, 3, _i("Unload filament"));////MSG_UNLOAD_FILAMENT c=17 + lcd_putc_at(0, cursor_pos, '>'); lcd_consume_click(); while (1) @@ -2199,21 +2199,20 @@ uint8_t lcd_alright() { if (lcd_encoder < 0 ) { // Rotating knob counter clockwise - cursor_pos--; + if (cursor_pos > 0) + cursor_pos--; + else + Sound_MakeSound(e_SOUND_TYPE_BlindAlert); } else if (lcd_encoder > 0) { // Rotating knob clockwise - cursor_pos++; - } - if (cursor_pos > 3) { - cursor_pos = 3; - Sound_MakeSound(e_SOUND_TYPE_BlindAlert); - } else if (cursor_pos < 1) { - cursor_pos = 1; - Sound_MakeSound(e_SOUND_TYPE_BlindAlert); + if (cursor_pos < 3) + cursor_pos++; + else + Sound_MakeSound(e_SOUND_TYPE_BlindAlert); } // Update '>' render only - lcd_puts_at_P(0, 1, PSTR(" \n \n ")); + lcd_puts_at_P(0, 0, PSTR(" \n \n \n ")); lcd_putc_at(0, cursor_pos, '>'); // Consume rotation event and make feedback sound