From 09952db139f9828f82a3ced0767f5d9798e2599e Mon Sep 17 00:00:00 2001 From: gudnimg Date: Tue, 2 Jan 2024 17:25:38 +0000 Subject: [PATCH 1/2] Restart USB timer during long moves When long moves are planned and executed the USB timer can expire. In PrusaSlicer 2.7.1 the Toolchange command (T0, T1, etc.) is sent while the USB timer is expired. This will trigger a manual MMU unload in the firmware. Not only does this trigger a loud beep from the buzzer, but this will also significantly increase print time. The issue only affects host prints. SD card printing does not have this issue. Fixes #4551 The fix in this commit is the following: If there are blocks queued while printing via host AND the USB timer is halfway expired WHILE executing a move. Then simply restart the timer to keep it alive. Change in memory: Flash: +62 bytes SRAM: 0 bytes --- Firmware/Configuration_adv.h | 3 +++ Firmware/Marlin_main.cpp | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 34c683ce2..b57c549e8 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -69,6 +69,9 @@ // Keepalive period which is restarted with M79 #define M79_TIMEOUT 30 * 1000 // ms +// A timer which is restarted everytime a G-command is added to the command queue. +#define USB_TIMER_TIMEOUT 10 * 1000 // ms + //=========================================================================== //=============================Mechanical Settings=========================== //=========================================================================== diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 74ac22d06..b2d4cd2ab 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1728,7 +1728,7 @@ void loop() if (print_job_timer.isPaused() && saved_printing_type == PowerPanic::PRINT_TYPE_USB) { //keep believing that usb is being printed. Prevents accessing dangerous menus while pausing. usb_timer.start(); } - else if (usb_timer.expired(10000)) { //just need to check if it expired. Nothing else is needed to be done. + else if (usb_timer.expired(USB_TIMER_TIMEOUT)) { //just need to check if it expired. Nothing else is needed to be done. SetPrinterState(PrinterState::HostPrintingFinished); //set printer state to show LCD menu after finished SD print } @@ -9600,6 +9600,13 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s get_command(); } + if (blocks_queued() && GetPrinterState() == PrinterState::IsHostPrinting && usb_timer.elapsed() > ((USB_TIMER_TIMEOUT) / 2)) + { + // Handle the case where planned moves may take a longer time to execute than the USB timer period. + // An example is the toolchange unload sequence generated by PrusaSlicer with default settings. + usb_timer.start(); + } + if(max_inactive_time && previous_millis_cmd.expired(max_inactive_time)) kill(PSTR("Inactivity Shutdown")); if(stepper_inactive_time && previous_millis_cmd.expired(stepper_inactive_time)) { From ae31c0ec31f0360787c5c4efbb0034b66e630ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Sat, 6 Jan 2024 00:19:15 +0000 Subject: [PATCH 2/2] optimisation: used expired() instead of elapsed() If the timer is expired, then the timer is stopped. This is OK since we are starting the timer again anyway Change in memory: Flash: -14 bytes SRAM: 0 bytes --- Firmware/Marlin_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index b2d4cd2ab..186b111a2 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -9600,7 +9600,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s get_command(); } - if (blocks_queued() && GetPrinterState() == PrinterState::IsHostPrinting && usb_timer.elapsed() > ((USB_TIMER_TIMEOUT) / 2)) + if (blocks_queued() && GetPrinterState() == PrinterState::IsHostPrinting && usb_timer.expired((USB_TIMER_TIMEOUT) / 2)) { // Handle the case where planned moves may take a longer time to execute than the USB timer period. // An example is the toolchange unload sequence generated by PrusaSlicer with default settings.