From 423f98ff6ebd9efdd75d3c7c94256e7d9cc151be Mon Sep 17 00:00:00 2001 From: gudnimg Date: Sun, 22 Oct 2023 16:12:41 +0000 Subject: [PATCH 1/6] Implement Marlin's print job timer I changed the code a bit so it would compile in Prusa Firmware. The paused duration is no longer included in the print time statistics. Change in memory: Flash: -122 bytes SRAM: 0 bytes --- CMakeLists.txt | 1 + Firmware/Marlin.h | 3 -- Firmware/Marlin_main.cpp | 33 ++++++------ Firmware/Prusa_farm.cpp | 7 +-- Firmware/cardreader.cpp | 5 +- Firmware/cmdqueue.cpp | 6 +-- Firmware/fancheck.cpp | 3 +- Firmware/stopwatch.cpp | 83 +++++++++++++++++++++++++++++ Firmware/stopwatch.h | 109 +++++++++++++++++++++++++++++++++++++++ Firmware/ultralcd.cpp | 38 +++++++------- Firmware/ultralcd.h | 2 - 11 files changed, 238 insertions(+), 52 deletions(-) create mode 100644 Firmware/stopwatch.cpp create mode 100644 Firmware/stopwatch.h diff --git a/CMakeLists.txt b/CMakeLists.txt index aa08d6ba8..e611b51fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,6 +225,7 @@ set(FW_SOURCES spi.c SpoolJoin.cpp stepper.cpp + stopwatch.cpp strtod.c swi2c.c Tcodes.cpp diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 02c22eaa3..294fa7f33 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -262,9 +262,6 @@ extern float retract_length_swap; extern float retract_recover_length_swap; #endif -extern uint32_t starttime; // milliseconds -extern uint32_t pause_time; // milliseconds -extern uint32_t start_pause_print; // milliseconds extern ShortTimer usb_timer; extern bool processing_tcode; extern bool homing_flag; diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 5bbe9b2d3..c289b2b33 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -89,6 +89,7 @@ #include "Tcodes.h" #include "Dcodes.h" #include "SpoolJoin.h" +#include "stopwatch.h" #ifndef LA_NOCOMPAT #include "la10compat.h" @@ -289,9 +290,6 @@ static uint32_t max_inactive_time = 0; static uint32_t stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME*1000l; static uint32_t safetytimer_inactive_time = DEFAULT_SAFETYTIMER_TIME_MINS*60*1000ul; -uint32_t starttime; -uint32_t pause_time; -uint32_t start_pause_print; ShortTimer usb_timer; bool Stopped=false; @@ -509,12 +507,12 @@ void servo_init() } bool __attribute__((noinline)) printJobOngoing() { - return (IS_SD_PRINTING || usb_timer.running()); + return (IS_SD_PRINTING || usb_timer.running() || print_job_timer.isRunning()); } bool __attribute__((noinline)) printer_active() { return printJobOngoing() - || isPrintPaused + || print_job_timer.isPaused() || saved_printing || (lcd_commands_type != LcdCommands::Idle) || MMU2::mmu2.MMU_PRINT_SAVED() @@ -535,7 +533,7 @@ bool check_fsensor() { bool __attribute__((noinline)) babystep_allowed() { return ( !homing_flag && !mesh_bed_leveling_flag - && !isPrintPaused + && !print_job_timer.isPaused() && ((lcd_commands_type == LcdCommands::Layer1Cal && CHECK_ALL_HEATERS) || printJobOngoing() || lcd_commands_type == LcdCommands::Idle @@ -1731,7 +1729,7 @@ void loop() KEEPALIVE_STATE(NOT_BUSY); } - if (isPrintPaused && saved_printing_type == PowerPanic::PRINT_TYPE_USB) { //keep believing that usb is being printed. Prevents accessing dangerous menus while pausing. + 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. @@ -1828,7 +1826,7 @@ void loop() } //check heater every n milliseconds manage_heater(); - manage_inactivity(isPrintPaused); + manage_inactivity(print_job_timer.isPaused()); checkHitEndstops(); lcd_update(0); #ifdef TMC2130 @@ -5256,7 +5254,7 @@ void process_commands() ### M24 - Start SD print M24: Start/resume SD print */ case 24: - if (isPrintPaused) + if (print_job_timer.isPaused()) lcd_resume_print(); else { @@ -5271,7 +5269,7 @@ void process_commands() } card.startFileprint(); - starttime=_millis(); + print_job_timer.start(); if (MMU2::mmu2.Enabled()) { if (MMU2::mmu2.FindaDetectsFilament() && !fsensor.getFilamentPresent()) @@ -5389,7 +5387,7 @@ void process_commands() la10c_reset(); #endif } - starttime=_millis(); // procedure calls count as normal print time. + print_job_timer.start(); // procedure calls count as normal print time. } } } break; @@ -5413,7 +5411,7 @@ void process_commands() case 31: //M31 take time since the start of the SD print or an M109 command { char time[30]; - uint32_t t = (_millis() - starttime) / 1000; + uint32_t t = print_job_timer.duration(); int16_t sec, min; min = t / 60; sec = t % 60; @@ -6050,8 +6048,7 @@ Sigma_Exit: LCD_MESSAGERPGM(_T(MSG_HEATING_COMPLETE)); heating_status = HeatingStatus::EXTRUDER_HEATING_COMPLETE; prusa_statistics(2); - - //starttime=_millis(); + previous_millis_cmd.start(); } break; @@ -7743,7 +7740,7 @@ Sigma_Exit: SERIAL_ECHOPGM("Z:"); SERIAL_ECHOLN(pause_position[Z_AXIS]); */ - if (!isPrintPaused) { + if (!print_job_timer.isPaused()) { st_synchronize(); ClearToSend(); //send OK even before the command finishes executing because we want to make sure it is not skipped because of cmdqueue_pop_front(); cmdqueue_pop_front(); //trick because we want skip this command (M601) after restore @@ -7757,7 +7754,7 @@ Sigma_Exit: */ case 602: { - if (isPrintPaused) lcd_resume_print(); + if (print_job_timer.isPaused()) lcd_resume_print(); } break; @@ -9631,7 +9628,7 @@ void ThermalStop(bool allow_recovery) // Either pause or stop the print if(allow_recovery && printJobOngoing()) { - if (!isPrintPaused) { + if (!print_job_timer.isPaused()) { lcd_setalertstatuspgm(_T(MSG_PAUSED_THERMAL_ERROR), LCD_STATUS_CRITICAL); // we cannot make a distinction for the host here, the pause must be instantaneous @@ -9772,6 +9769,7 @@ void save_statistics(uint32_t _total_filament_used, uint32_t _total_print_time) eeprom_update_dword((uint32_t *)EEPROM_TOTALTIME, _previous_time + _total_print_time); // EEPROM_TOTALTIME unit: min eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, _previous_filament + (_total_filament_used / 1000)); + print_job_timer.reset(); total_filament_used = 0; if (MMU2::mmu2.Enabled()) { @@ -10460,7 +10458,6 @@ float temp_compensation_pinda_thermistor_offset(float temperature_pinda) void long_pause() //long pause print { st_synchronize(); - start_pause_print = _millis(); // Stop heaters heating_status = HeatingStatus::NO_HEATING; diff --git a/Firmware/Prusa_farm.cpp b/Firmware/Prusa_farm.cpp index 032f2d109..6f5e96aae 100644 --- a/Firmware/Prusa_farm.cpp +++ b/Firmware/Prusa_farm.cpp @@ -8,6 +8,7 @@ #include "ultralcd.h" #include "Filament_sensor.h" #include "language.h" +#include "stopwatch.h" #ifdef PRUSA_FARM uint8_t farm_mode = 0; @@ -92,8 +93,8 @@ static void prusa_stat_printinfo() { SERIAL_ECHOPGM("][FNM:"); SERIAL_ECHO(card.longFilename[0] ? card.longFilename : card.filename); SERIAL_ECHOPGM("][TIM:"); - if (starttime != 0) { - SERIAL_ECHO((_millis() - starttime) / 1000); + if (print_job_timer.isRunning()) { + SERIAL_ECHO(print_job_timer.duration()); } else { SERIAL_ECHO(0); @@ -237,7 +238,7 @@ void prusa_statistics(uint8_t _message) { if (busy_state == PAUSED_FOR_USER) { prusa_statistics_case0(15); } - else if (isPrintPaused) { + else if (print_job_timer.isPaused()) { prusa_statistics_case0(14); } else if (IS_SD_PRINTING || (eFilamentAction != FilamentAction::None)) { diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 1d6c50ec6..1ad03423d 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -8,6 +8,7 @@ #include "language.h" #include "Prusa_farm.h" #include "power_panic.h" +#include "stopwatch.h" #ifdef SDSUPPORT @@ -556,7 +557,7 @@ uint32_t CardReader::getFileSize() void CardReader::getStatus(bool arg_P) { - if (isPrintPaused) + if (print_job_timer.isPaused()) { if (saved_printing && (saved_printing_type == PowerPanic::PRINT_TYPE_SD)) SERIAL_PROTOCOLLNPGM("SD print paused"); @@ -577,7 +578,7 @@ void CardReader::getStatus(bool arg_P) SERIAL_PROTOCOL(sdpos); SERIAL_PROTOCOL('/'); SERIAL_PROTOCOLLN(filesize); - uint16_t time = ( _millis() - starttime ) / 60000U; + uint16_t time = print_job_timer.duration() / 60; SERIAL_PROTOCOL((int)(time / 60)); SERIAL_PROTOCOL(':'); SERIAL_PROTOCOLLN((int)(time % 60)); diff --git a/Firmware/cmdqueue.cpp b/Firmware/cmdqueue.cpp index 39030cb10..bb2bc8c33 100755 --- a/Firmware/cmdqueue.cpp +++ b/Firmware/cmdqueue.cpp @@ -7,6 +7,7 @@ #include "meatpack.h" #include "messages.h" #include "language.h" +#include "stopwatch.h" // Reserve BUFSIZE lines of length MAX_CMD_SIZE plus CMDBUFFER_RESERVE_FRONT. char cmdbuffer[BUFSIZE * (MAX_CMD_SIZE + 1) + CMDBUFFER_RESERVE_FRONT]; @@ -366,7 +367,7 @@ void get_command() } // start of serial line processing loop - while (((MYSERIAL.available() > 0 && !saved_printing) || (MYSERIAL.available() > 0 && isPrintPaused)) && !cmdqueue_serial_disabled) { //is print is saved (crash detection or filament detection), dont process data from serial line + while (((MYSERIAL.available() > 0 && !saved_printing) || (MYSERIAL.available() > 0 && print_job_timer.isPaused())) && !cmdqueue_serial_disabled) { //is print is saved (crash detection or filament detection), dont process data from serial line #ifdef ENABLE_MEATPACK // MeatPack Changes @@ -658,8 +659,7 @@ void get_command() SERIAL_PROTOCOLLNRPGM(_n("Done printing file"));////MSG_FILE_PRINTED char time[30]; - uint32_t t = (_millis() - starttime - pause_time) / 60000; - pause_time = 0; + uint32_t t = print_job_timer.duration() / 60; int hours, minutes; minutes = t % 60; hours = t / 60; diff --git a/Firmware/fancheck.cpp b/Firmware/fancheck.cpp index 1afcd35df..2c90b8aad 100755 --- a/Firmware/fancheck.cpp +++ b/Firmware/fancheck.cpp @@ -5,6 +5,7 @@ #include "messages.h" #include "temperature.h" #include "stepper.h" +#include "stopwatch.h" #define FAN_CHECK_PERIOD 5000 //5s #define FAN_CHECK_DURATION 100 //100ms @@ -93,7 +94,7 @@ void fanSpeedError(unsigned char _fan) { if (printJobOngoing()) { // A print is ongoing, pause the print normally - if(!isPrintPaused) { + if(!print_job_timer.isPaused()) { if (usb_timer.running()) lcd_pause_usb_print(); else diff --git a/Firmware/stopwatch.cpp b/Firmware/stopwatch.cpp new file mode 100644 index 000000000..2e34b66e4 --- /dev/null +++ b/Firmware/stopwatch.cpp @@ -0,0 +1,83 @@ +/** + * + * NOTE: this file has been changed in order to compile & run on Prusa-Firmware https://github.com/prusa3d/Prusa-Firmware + * + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "stopwatch.h" +#include "system_timer.h" + +Stopwatch print_job_timer; + +#define MS_TO_SEC(N) uint32_t((N)/1000UL) + +Stopwatch::State Stopwatch::state; +uint32_t Stopwatch::accumulator; +uint32_t Stopwatch::startTimestamp; +uint32_t Stopwatch::stopTimestamp; + +bool Stopwatch::stop() { + if (isRunning() || isPaused()) { + state = STOPPED; + stopTimestamp = _millis(); + return true; + } + else return false; +} + +bool Stopwatch::pause() { + if (isRunning()) { + state = PAUSED; + stopTimestamp = _millis(); + return true; + } + else return false; +} + +bool Stopwatch::start() { + if (!isRunning()) { + if (isPaused()) accumulator = duration(); + else reset(); + + state = RUNNING; + startTimestamp = _millis(); + return true; + } + else return false; +} + +void Stopwatch::resume(const uint32_t with_time) { + reset(); + if ((accumulator = with_time)) state = RUNNING; +} + +void Stopwatch::reset() { + state = STOPPED; + startTimestamp = 0; + stopTimestamp = 0; + accumulator = 0; +} + +uint32_t Stopwatch::duration() { + return accumulator + MS_TO_SEC((isRunning() ? _millis() : stopTimestamp) - startTimestamp); +} + diff --git a/Firmware/stopwatch.h b/Firmware/stopwatch.h new file mode 100644 index 000000000..d2ea277b1 --- /dev/null +++ b/Firmware/stopwatch.h @@ -0,0 +1,109 @@ +/** + * + * NOTE: this file has been changed in order to compile & run on Prusa-Firmware https://github.com/prusa3d/Prusa-Firmware + * + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "Timer.h" +#include "macros.h" + +/** + * @brief Stopwatch class + * @details This class acts as a timer proving stopwatch functionality including + * the ability to pause the running time counter. + */ +class Stopwatch { + private: + enum State : char { STOPPED, RUNNING, PAUSED }; + + static Stopwatch::State state; + static uint32_t accumulator; + static uint32_t startTimestamp; + static uint32_t stopTimestamp; + + public: + /** + * @brief Initialize the stopwatch + */ + FORCE_INLINE static void init() { reset(); } + + /** + * @brief Stop the stopwatch + * @details Stop the running timer, it will silently ignore the request if + * no timer is currently running. + * @return true on success + */ + static bool stop(); + static bool abort() { return stop(); } // Alias by default + + /** + * @brief Pause the stopwatch + * @details Pause the running timer, it will silently ignore the request if + * no timer is currently running. + * @return true on success + */ + static bool pause(); + + /** + * @brief Start the stopwatch + * @details Start the timer, it will silently ignore the request if the + * timer is already running. + * @return true on success + */ + static bool start(); + + /** + * @brief Resume the stopwatch + * @details Resume a timer from a given duration + */ + static void resume(const uint32_t with_time); + + /** + * @brief Reset the stopwatch + * @details Reset all settings to their default values. + */ + static void reset(); + + /** + * @brief Check if the timer is running + * @details Return true if the timer is currently running, false otherwise. + * @return true if stopwatch is running + */ + FORCE_INLINE static bool isRunning() { return state == RUNNING; } + + /** + * @brief Check if the timer is paused + * @details Return true if the timer is currently paused, false otherwise. + * @return true if stopwatch is paused + */ + FORCE_INLINE static bool isPaused() { return state == PAUSED; } + + /** + * @brief Get the running time + * @details Return the total number of seconds the timer has been running. + * @return the delta since starting the stopwatch + */ + static uint32_t duration(); +}; + +extern Stopwatch print_job_timer; diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index f0039eacb..cbd14b4cc 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -13,7 +13,7 @@ #include "ConfigurationStore.h" #include "printers.h" #include - +#include "stopwatch.h" #include "lcd.h" #include "menu.h" @@ -68,8 +68,6 @@ static bool extraPurgeNeeded = false; ///< lcd_commands - detect if extra purge CustomMsg custom_message_type = CustomMsg::Status; uint8_t custom_message_state = 0; -bool isPrintPaused = false; - static ShortTimer display_time; //just timer for showing pid finished message on lcd; static uint16_t pid_temp = DEFAULT_PID_TEMP; @@ -487,7 +485,7 @@ void lcdui_print_time(void) print_t = print_tr; suff = 'R'; } else - print_t = (_millis() - starttime) / 60000; + print_t = print_job_timer.duration() / 60; if (feedmultiply != 100 && (print_t == print_tr || print_t == print_tc)) { suff_doubt = '?'; @@ -1017,7 +1015,8 @@ void lcd_pause_print() stop_and_save_print_to_ram(0.0, -default_retraction); SERIAL_ECHOLNRPGM(MSG_OCTOPRINT_PAUSED); - isPrintPaused = true; + + print_job_timer.pause(); // return to status is required to continue processing in the main loop! lcd_commands_type = LcdCommands::LongPause; @@ -1994,7 +1993,7 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed) if (!bFilamentPreheatState) { setTargetHotend(0); - if (!isPrintPaused) setTargetBed(0); + if (!print_job_timer.isPaused()) setTargetBed(0); menu_back(); } menu_back(); @@ -2309,7 +2308,8 @@ void lcd_menu_statistics() if (IS_SD_PRINTING) { const float _met = ((float)total_filament_used) / (100000.f); - const uint32_t _t = (_millis() - starttime) / 1000ul; + + const uint32_t _t = print_job_timer.duration(); const uint32_t _h = (_t / 60) / 60; const uint8_t _m = (_t / 60) % 60; const uint8_t _s = _t % 60; @@ -4431,7 +4431,7 @@ static void lcd_settings_menu() MENU_ITEM_SUBMENU_P(_i("Temperature"), lcd_control_temperature_menu);////MSG_TEMPERATURE c=18 - if (!printer_active() || isPrintPaused) + if (!printer_active() || print_job_timer.isPaused()) { MENU_ITEM_SUBMENU_P(_i("Move axis"), lcd_move_menu_axis);////MSG_MOVE_AXIS c=18 MENU_ITEM_GCODE_P(_i("Disable steppers"), MSG_M84);////MSG_DISABLE_STEPPERS c=18 @@ -4475,7 +4475,7 @@ static void lcd_settings_menu() MENU_ITEM_TOGGLE_P(_T(MSG_RPI_PORT), (selectedSerialPort == 0) ? _T(MSG_OFF) : _T(MSG_ON), lcd_second_serial_set); #endif //HAS_SECOND_SERIAL - if (!isPrintPaused) MENU_ITEM_SUBMENU_P(_T(MSG_BABYSTEP_Z), lcd_babystep_z); + if (!print_job_timer.isPaused()) MENU_ITEM_SUBMENU_P(_T(MSG_BABYSTEP_Z), lcd_babystep_z); #if (LANG_MODE != 0) MENU_ITEM_SUBMENU_P(_T(MSG_SELECT_LANGUAGE), lcd_language_menu); @@ -5005,8 +5005,7 @@ void lcd_resume_print() Stopped = false; restore_print_from_ram_and_continue(default_retraction); - isPrintPaused = false; - pause_time += (_millis() - start_pause_print); //accumulate time when print is paused for correct statistics calculation + print_job_timer.start(); refresh_cmd_timeout(); SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_RESUMED); //resume octoprint custom_message_type = CustomMsg::Status; @@ -5192,14 +5191,14 @@ static void lcd_main_menu() MENU_ITEM_SUBMENU_P(_i("Preheat"), lcd_preheat_menu);////MSG_PREHEAT c=18 } - if (mesh_bed_leveling_flag == false && homing_flag == false && !isPrintPaused && !processing_tcode) { + if (mesh_bed_leveling_flag == false && homing_flag == false && !print_job_timer.isPaused() && !processing_tcode) { if (usb_timer.running()) { MENU_ITEM_FUNCTION_P(_T(MSG_PAUSE_PRINT), lcd_pause_usb_print); } else if (IS_SD_PRINTING) { MENU_ITEM_FUNCTION_P(_T(MSG_PAUSE_PRINT), lcd_pause_print); } } - if(isPrintPaused) + if(print_job_timer.isPaused()) { // only allow resuming if hardware errors (temperature or fan) are cleared if(!get_temp_error() @@ -5214,7 +5213,7 @@ static void lcd_main_menu() } } } - if((printJobOngoing() || isPrintPaused) && (custom_message_type != CustomMsg::MeshBedLeveling) && !processing_tcode) { + if((printJobOngoing() || print_job_timer.isPaused()) && (custom_message_type != CustomMsg::MeshBedLeveling) && !processing_tcode) { MENU_ITEM_SUBMENU_P(_T(MSG_STOP_PRINT), lcd_sdcard_stop); } #ifdef THERMAL_MODEL @@ -5287,7 +5286,7 @@ static void lcd_main_menu() MENU_ITEM_SUBMENU_P(_T(MSG_UNLOAD_FILAMENT), lcd_unLoadFilament); } MENU_ITEM_SUBMENU_P(_T(MSG_SETTINGS), lcd_settings_menu); - if(!isPrintPaused) MENU_ITEM_SUBMENU_P(_T(MSG_CALIBRATION), lcd_calibration_menu); + if(!print_job_timer.isPaused()) MENU_ITEM_SUBMENU_P(_T(MSG_CALIBRATION), lcd_calibration_menu); } if (!usb_timer.running()) { @@ -5445,7 +5444,7 @@ static void lcd_tune_menu() if (!farm_mode) MENU_ITEM_FUNCTION_P(_T(MSG_FILAMENTCHANGE), lcd_colorprint_change); #endif - if (isPrintPaused) {// Don't allow rehome if actively printing. Maaaaybe it could work to insert on the fly, seems too risky. + if (print_job_timer.isPaused()) {// Don't allow rehome if actively printing. Maaaaybe it could work to insert on the fly, seems too risky. MENU_ITEM_FUNCTION_P(_T(MSG_AUTO_HOME), lcd_rehome_xy); } #ifdef FILAMENT_SENSOR @@ -5581,7 +5580,7 @@ static void lcd_sd_updir() void lcd_print_stop_finish() { // Convert the time from ms to minutes, divide by 60 * 1000 - uint32_t t = (_millis() - starttime - pause_time) / 60000; + uint32_t t = print_job_timer.duration() / 60; save_statistics(total_filament_used, t); // lift Z @@ -5609,7 +5608,7 @@ void lcd_print_stop_finish() if (MMU2::mmu2.Enabled() && MMU2::mmu2.FindaDetectsFilament()) { - if (isPrintPaused) + if (print_job_timer.isPaused()) { // Restore temperature saved in ram after pausing print restore_extruder_temperature_from_ram(); @@ -5639,8 +5638,7 @@ void print_stop(bool interactive) #endif // clear any pending paused state immediately - pause_time = 0; - isPrintPaused = false; + print_job_timer.stop(); if (interactive) { // acknowledged by the user from the LCD: resume processing USB commands again diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index c340fef95..e8d3bb8ab 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -169,8 +169,6 @@ void printf_IRSensorAnalogBoardChange(); extern int8_t SilentModeMenu; -extern bool isPrintPaused; - extern uint8_t scrollstuff; From a6de11059ff43d70dad65a0cac0ca715d407d9f6 Mon Sep 17 00:00:00 2001 From: gudnimg Date: Sun, 12 Nov 2023 14:57:16 +0000 Subject: [PATCH 2/6] PFW-1206 Add M75-M78 Change in memory: Flash: +240 bytes SRAM: 0 bytes --- Firmware/Marlin_main.cpp | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index c289b2b33..889b5eaa5 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -5873,6 +5873,47 @@ Sigma_Exit: break; } + /*! + ### M75 - Start the print job timer M75: Start the print job timer + */ + case 75: + { + print_job_timer.start(); + break; + } + + /*! + ### M76 - Pause the print job timer M76: Pause the print job timer + */ + case 76: + { + print_job_timer.pause(); + break; + } + + /*! + ### M77 - Stop the print job timer M77: Stop the print job timer + */ + case 77: + { + print_job_timer.stop(); + break; + } + + /*! + ### M78 - Show statistical information about the print jobs M78: Show statistical information about the print jobs + */ + case 78: + { + // @todo useful for maintenance notifications + SERIAL_ECHOPGM("STATS "); + SERIAL_ECHO(eeprom_read_dword((uint32_t *)EEPROM_TOTALTIME)); + SERIAL_ECHOPGM(" min "); + SERIAL_ECHO(eeprom_read_dword((uint32_t *)EEPROM_FILAMENTUSED)); + SERIAL_ECHOLNPGM(" cm."); + break; + } + /*! ### M79 - Start host timer M79: Start host timer Start the printer-host enable keep-alive timer. While the timer has not expired, the printer will enable host specific features. From a2e6cda37e694ae44ed44ab8b8ea224a45277488 Mon Sep 17 00:00:00 2001 From: gudnimg Date: Sun, 19 Nov 2023 11:51:41 +0000 Subject: [PATCH 3/6] Fix build failure --- Firmware/Marlin_main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 889b5eaa5..aa6e8dd50 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3423,7 +3423,7 @@ static void gcode_M600(const bool automatic, const float x_position, const float fanSpeed = 0; // Retract E - if (!isPrintPaused) + if (!print_job_timer.isPaused()) { current_position[E_AXIS] += e_shift; plan_buffer_line_curposXYZE(FILAMENTCHANGE_RFEED); @@ -3486,7 +3486,7 @@ static void gcode_M600(const bool automatic, const float x_position, const float // Feed a little of filament to stabilize pressure if (!automatic) { - if (isPrintPaused) + 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 @@ -3522,7 +3522,7 @@ static void gcode_M600(const bool automatic, const float x_position, const float feedmultiply = feedmultiplyBckp; enquecommandf_P(MSG_M220, feedmultiplyBckp); } - if (isPrintPaused) lcd_setstatuspgm(_T(MSG_PRINT_PAUSED)); + if (print_job_timer.isPaused()) lcd_setstatuspgm(_T(MSG_PRINT_PAUSED)); else lcd_setstatuspgm(MSG_WELCOME); custom_message_type = CustomMsg::Status; } From 331ceaf04480f9bb8070780fa34340f1cffbcb65 Mon Sep 17 00:00:00 2001 From: gudnimg Date: Sun, 19 Nov 2023 11:57:30 +0000 Subject: [PATCH 4/6] M77: Save statistics when timer is stopped For remote hosts, when the timer is stopped, then also save the statistics. Slightly refactored save_statistics function by removing the parameters. The function parameters are always the same. Change in memory: Flash: -40 bytes SRAM: 0 bytes --- Firmware/Marlin.h | 4 +--- Firmware/Marlin_main.cpp | 10 ++++++---- Firmware/cmdqueue.cpp | 2 +- Firmware/ultralcd.cpp | 4 +--- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 294fa7f33..5db418b7b 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -268,9 +268,7 @@ extern bool homing_flag; extern uint32_t total_filament_used; // mm/100 or 10um /// @brief Save print statistics to EEPROM -/// @param _total_filament_used has unit mm/100 or 10um -/// @param _total_print_time has unit minutes, for example 123 minutes -void save_statistics(uint32_t _total_filament_used, uint32_t _total_print_time); +void save_statistics(); extern int fan_edge_counter[2]; extern int fan_speed[2]; diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index aa6e8dd50..1445938a9 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -175,7 +175,7 @@ static LongTimer crashDetTimer; bool mesh_bed_leveling_flag = false; -uint32_t total_filament_used; +uint32_t total_filament_used; // unit mm/100 or 10um HeatingStatus heating_status; int fan_edge_counter[2]; int fan_speed[2]; @@ -5897,6 +5897,7 @@ Sigma_Exit: case 77: { print_job_timer.stop(); + save_statistics(); break; } @@ -9803,12 +9804,13 @@ void setPwmFrequency(uint8_t pin, int val) } #endif //FAST_PWM_FAN -void save_statistics(uint32_t _total_filament_used, uint32_t _total_print_time) { +void save_statistics() { uint32_t _previous_filament = eeprom_init_default_dword((uint32_t *)EEPROM_FILAMENTUSED, 0); //_previous_filament unit: meter uint32_t _previous_time = eeprom_init_default_dword((uint32_t *)EEPROM_TOTALTIME, 0); //_previous_time unit: min - eeprom_update_dword((uint32_t *)EEPROM_TOTALTIME, _previous_time + _total_print_time); // EEPROM_TOTALTIME unit: min - eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, _previous_filament + (_total_filament_used / 1000)); + uint32_t time_minutes = print_job_timer.duration() / 60; + eeprom_update_dword((uint32_t *)EEPROM_TOTALTIME, _previous_time + time_minutes); // EEPROM_TOTALTIME unit: min + eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, _previous_filament + (total_filament_used / 1000)); print_job_timer.reset(); total_filament_used = 0; diff --git a/Firmware/cmdqueue.cpp b/Firmware/cmdqueue.cpp index bb2bc8c33..84f11329e 100755 --- a/Firmware/cmdqueue.cpp +++ b/Firmware/cmdqueue.cpp @@ -663,7 +663,7 @@ void get_command() int hours, minutes; minutes = t % 60; hours = t / 60; - save_statistics(total_filament_used, t); + save_statistics(); sprintf_P(time, PSTR("%i hours %i minutes"),hours, minutes); SERIAL_ECHO_START; SERIAL_ECHOLN(time); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index cbd14b4cc..d2ad902f7 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -5579,9 +5579,7 @@ static void lcd_sd_updir() // continue stopping the print from the main loop after lcd_print_stop() is called void lcd_print_stop_finish() { - // Convert the time from ms to minutes, divide by 60 * 1000 - uint32_t t = print_job_timer.duration() / 60; - save_statistics(total_filament_used, t); + save_statistics(); // lift Z raise_z(10); From 60cb089e9679917e966c5cb4844ca2122fea5d6c Mon Sep 17 00:00:00 2001 From: gudnimg Date: Sun, 19 Nov 2023 12:05:43 +0000 Subject: [PATCH 5/6] Show statistics menu for USB/Serial prints Change in memory: Flash: -8 bytes SRAM: 0 bytes --- Firmware/ultralcd.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index d2ad902f7..8b8043ac9 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2305,7 +2305,7 @@ void lcd_AutoLoadFilament() { void lcd_menu_statistics() { lcd_timeoutToStatus.stop(); //infinite timeout - if (IS_SD_PRINTING) + if (printJobOngoing()) { const float _met = ((float)total_filament_used) / (100000.f); @@ -5289,9 +5289,7 @@ static void lcd_main_menu() if(!print_job_timer.isPaused()) MENU_ITEM_SUBMENU_P(_T(MSG_CALIBRATION), lcd_calibration_menu); } - if (!usb_timer.running()) { MENU_ITEM_SUBMENU_P(_i("Statistics"), lcd_menu_statistics);////MSG_STATISTICS c=18 - } #if defined(TMC2130) || defined(FILAMENT_SENSOR) MENU_ITEM_SUBMENU_P(_i("Fail stats"), lcd_menu_fails_stats);////MSG_FAIL_STATS c=18 From 134e892d8eb8feedba10980ea7032a59b0074cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Tue, 21 Nov 2023 18:40:28 +0000 Subject: [PATCH 6/6] Fix build failure Another isPrintPaused was added by rebase --- 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 1445938a9..2ab26bf70 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -631,7 +631,7 @@ void crashdet_detected(uint8_t mask) void crashdet_recover() { - if (!isPrintPaused) crashdet_restore_print_and_continue(); + if (!print_job_timer.isPaused()) crashdet_restore_print_and_continue(); if (lcd_crash_detect_enabled()) tmc2130_sg_stop_on_crash = true; }