From fd55dcba1a4e45d359a87bb2d5e4086acb9525c0 Mon Sep 17 00:00:00 2001 From: ConstantijnCrijnen <43953114+ConstantijnCrijnen@users.noreply.github.com> Date: Tue, 26 Jan 2021 09:30:31 +0100 Subject: [PATCH] Configure / disable PRINTCOUNTER save interval (#20856) Co-authored-by: Scott Lahteine --- Marlin/Configuration.h | 3 ++ .../src/HAL/LPC1768/inc/Conditionals_post.h | 7 ++++ Marlin/src/MarlinCore.cpp | 3 +- Marlin/src/lcd/marlinui.cpp | 2 +- Marlin/src/libs/stopwatch.h | 1 + Marlin/src/module/printcounter.cpp | 39 +++++++++++-------- Marlin/src/module/printcounter.h | 21 ++++++---- 7 files changed, 50 insertions(+), 26 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index e48e2e433168..d888e62aaf46 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -1754,6 +1754,9 @@ * View the current statistics with M78. */ //#define PRINTCOUNTER +#if ENABLED(PRINTCOUNTER) + #define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print +#endif /** * Password diff --git a/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h b/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h index ce6d3fdde27f..94e4ce134170 100644 --- a/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h +++ b/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h @@ -26,3 +26,10 @@ #elif EITHER(I2C_EEPROM, SPI_EEPROM) #define USE_SHARED_EEPROM 1 #endif + +// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785) +// TODO: Which other boards are incompatible? +#if defined(MCU_LPC1768) && PRINTCOUNTER_SAVE_INTERVAL > 0 + #warning "To prevent step loss, motion will pause for PRINTCOUNTER auto-save." + #define PRINTCOUNTER_SYNC 1 +#endif diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 737651526053..4b6c281de2ed 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -365,7 +365,8 @@ void startOrResumeJob() { queue.clear(); quickstop_stepper(); - print_job_timer.stop(); + + print_job_timer.abort(); IF_DISABLED(SD_ABORT_NO_COOLDOWN, thermalManager.disable_all_heaters()); diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index c3c5d3f09447..46db57193669 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -1495,8 +1495,8 @@ void MarlinUI::update() { #ifdef ACTION_ON_CANCEL host_action_cancel(); #endif + IF_DISABLED(SDSUPPORT, print_job_timer.stop()); TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_INFO, PSTR("UI Aborted"), DISMISS_STR)); - print_job_timer.stop(); LCD_MESSAGEPGM(MSG_PRINT_ABORTED); TERN_(HAS_LCD_MENU, return_to_status()); } diff --git a/Marlin/src/libs/stopwatch.h b/Marlin/src/libs/stopwatch.h index 6e8e95a9a5f1..b64a36a90e78 100644 --- a/Marlin/src/libs/stopwatch.h +++ b/Marlin/src/libs/stopwatch.h @@ -56,6 +56,7 @@ class Stopwatch { * @return true on success */ static bool stop(); + static inline bool abort() { return stop(); } // Alias by default /** * @brief Pause the stopwatch diff --git a/Marlin/src/module/printcounter.cpp b/Marlin/src/module/printcounter.cpp index 5da1d09c75b4..45072c8f0189 100644 --- a/Marlin/src/module/printcounter.cpp +++ b/Marlin/src/module/printcounter.cpp @@ -41,6 +41,10 @@ Stopwatch print_job_timer; // Global Print Job Timer instance #include "../libs/buzzer.h" #endif +#if PRINTCOUNTER_SYNC + #include "../module/planner.h" +#endif + // Service intervals #if HAS_SERVICE_INTERVALS #if SERVICE_INTERVAL_1 > 0 @@ -160,6 +164,8 @@ void PrintCounter::saveStats() { // Refuses to save data if object is not loaded if (!isLoaded()) return; + TERN_(PRINTCOUNTER_SYNC, planner.synchronize()); + // Saves the struct to EEPROM persistentStore.access_start(); persistentStore.write_data(address + sizeof(uint8_t), (uint8_t*)&data, sizeof(printStatistics)); @@ -244,11 +250,13 @@ void PrintCounter::tick() { #endif } - static uint32_t eeprom_next; // = 0 - if (ELAPSED(now, eeprom_next)) { - eeprom_next = now + saveInterval * 1000; - saveStats(); - } + #if PRINTCOUNTER_SAVE_INTERVAL > 0 + static millis_t eeprom_next; // = 0 + if (ELAPSED(now, eeprom_next)) { + eeprom_next = now + saveInterval; + saveStats(); + } + #endif } // @Override @@ -268,21 +276,20 @@ bool PrintCounter::start() { return false; } -// @Override -bool PrintCounter::stop() { +bool PrintCounter::_stop(const bool completed) { TERN_(DEBUG_PRINTCOUNTER, debug(PSTR("stop"))); - if (super::stop()) { - data.finishedPrints++; + const bool did_stop = super::stop(); + if (did_stop) { data.printTime += deltaDuration(); - - if (duration() > data.longestPrint) - data.longestPrint = duration(); - - saveStats(); - return true; + if (completed) { + data.finishedPrints++; + if (duration() > data.longestPrint) + data.longestPrint = duration(); + } } - else return false; + saveStats(); + return did_stop; } // @Override diff --git a/Marlin/src/module/printcounter.h b/Marlin/src/module/printcounter.h index f7fc96c579a7..4deae45a656d 100644 --- a/Marlin/src/module/printcounter.h +++ b/Marlin/src/module/printcounter.h @@ -74,13 +74,15 @@ class PrintCounter: public Stopwatch { */ static constexpr millis_t updateInterval = SEC_TO_MS(10); - /** - * @brief Interval in seconds between EEPROM saves - * @details This const value defines what will be the time between each - * EEPROM save cycle, the development team recommends to set this value - * no lower than 3600 secs (1 hour). - */ - static constexpr uint16_t saveInterval = 3600; + #if PRINTCOUNTER_SAVE_INTERVAL > 0 + /** + * @brief Interval in seconds between EEPROM saves + * @details This const value defines what will be the time between each + * EEPROM save cycle, the development team recommends to set this value + * no lower than 3600 secs (1 hour). + */ + static constexpr millis_t saveInterval = MIN_TO_MS(PRINTCOUNTER_SAVE_INTERVAL); + #endif /** * @brief Timestamp of the last call to deltaDuration() @@ -173,7 +175,10 @@ class PrintCounter: public Stopwatch { * The following functions are being overridden */ static bool start(); - static bool stop(); + static bool _stop(const bool completed); + static inline bool stop() { return _stop(true); } + static inline bool abort() { return _stop(false); } + static void reset(); #if HAS_SERVICE_INTERVALS