diff --git a/.gitignore b/.gitignore index 0b852d7673..09db344257 100755 --- a/.gitignore +++ b/.gitignore @@ -147,6 +147,7 @@ vc-fileutils.settings imgui.ini eeprom.dat spi_flash.bin +fs.img #cmake CMakeLists.txt diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index cb327e9b73..29873073d3 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1403,9 +1403,6 @@ // On the Info Screen, display XY with one decimal place when possible //#define LCD_DECIMAL_SMALL_XY - // Add an 'M73' G-code to set the current percentage - //#define LCD_SET_PROGRESS_MANUALLY - // Show the E position (filament used) during printing //#define LCD_SHOW_E_TOTAL @@ -1426,37 +1423,43 @@ //#define LED_USER_PRESET_STARTUP // Have the printer display the user preset color on startup #endif #if ENABLED(NEO2_COLOR_PRESETS) - #define NEO2_USER_PRESET_RED 255 // User defined RED value - #define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value - #define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value - #define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value - #define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity - //#define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip + #define NEO2_USER_PRESET_RED 255 // User defined RED value + #define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value + #define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value + #define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value + #define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity + //#define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip #endif #endif +#endif // HAS_DISPLAY || DWIN_LCD_PROUI + +// Add the G-code 'M73' to set / report the current job progress +//#define SET_PROGRESS_MANUALLY +#if ENABLED(SET_PROGRESS_MANUALLY) + //#define SET_PROGRESS_PERCENT // Add 'P' parameter to set percentage done, otherwise use Marlin's estimate + //#define SET_REMAINING_TIME // Add 'R' parameter to set remaining time, otherwise use Marlin's estimate + //#define SET_INTERACTION_TIME // Add 'C' parameter to set time until next filament change or other user interaction + #if ENABLED(SET_INTERACTION_TIME) + #define SHOW_INTERACTION_TIME // Display time until next user interaction ('C' = filament change) + #endif + //#define M73_REPORT // Report progress to host with 'M73' #endif -// LCD Print Progress options -#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) - #if CAN_SHOW_REMAINING_TIME - //#define SHOW_REMAINING_TIME // Display estimated time to completion - #if ENABLED(SHOW_REMAINING_TIME) - //#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation - //#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time - #endif - #endif +// LCD Print Progress options, multiple can be rotated depending on screen layout +#if HAS_DISPLAY && EITHER(SDSUPPORT, SET_PROGRESS_MANUALLY) + #define SHOW_PROGRESS_PERCENT // Show print progress percentage (doesn't affect progress bar) + #define SHOW_ELAPSED_TIME // Display elapsed printing time (prefix 'E') + //#define SHOW_REMAINING_TIME // Display estimated time to completion (prefix 'R') - #if EITHER(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI) - //#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits - #endif + //#define PRINT_PROGRESS_SHOW_DECIMALS // Show/report progress with decimal digits, not all UIs support this #if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) //#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing #if ENABLED(LCD_PROGRESS_BAR) #define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar #define PROGRESS_BAR_MSG_TIME 3000 // (ms) Amount of time to show the status message - #define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever) //#define PROGRESS_MSG_ONCE // Show the message for MSG_TIME then clear it //#define LCD_PROGRESS_BAR_TEST // Add a menu item to test the progress bar #endif @@ -1799,14 +1802,8 @@ #endif // HAS_MARLINUI_U8GLIB #if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI - // Show SD percentage next to the progress bar - //#define SHOW_SD_PERCENT - - // Enable to save many cycles by drawing a hollow frame on Menu Screens - #define MENU_HOLLOW_FRAME - - // Swap the CW/CCW indicators in the graphics overlay - //#define OVERLAY_GFX_REVERSE + #define MENU_HOLLOW_FRAME // Enable to save many cycles by drawing a hollow frame on Menu Screens + //#define OVERLAY_GFX_REVERSE // Swap the CW/CCW indicators in the graphics overlay #endif // @@ -2064,7 +2061,7 @@ */ //#define LIN_ADVANCE #if ENABLED(LIN_ADVANCE) - //#define EXTRA_LIN_ADVANCE_K // Add a second linear advance constant, configurable with M900. + //#define EXTRA_LIN_ADVANCE_K // Add a second linear advance constant, configurable with M900 L. #define LIN_ADVANCE_K 0.22 // Unit: mm compression per 1mm/s extruder speed //#define LA_DEBUG // Print debug information to serial during operation. Disable for production use. //#define EXPERIMENTAL_SCURVE // Allow S-Curve Acceleration to be used with LA. @@ -4058,7 +4055,7 @@ /** * Mechanical Gantry Calibration - * Modern replacement for the Prusa TMC_Z_CALIBRATION. + * Modern replacement for the Průša TMC_Z_CALIBRATION. * Adds capability to work with any adjustable current drivers. * Implemented as G34 because M915 is deprecated. * @section calibrate diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 0ea55b7ef4..ea57e3ccd7 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -347,7 +347,7 @@ void startOrResumeJob() { TERN_(GCODE_REPEAT_MARKERS, repeat.reset()); TERN_(CANCEL_OBJECTS, cancelable.reset()); TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator = 0); - #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) + #if ENABLED(SET_REMAINING_TIME) ui.reset_remaining_time(); #endif } diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 405e2d460c..863d432095 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -561,8 +561,8 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 48: M48(); break; // M48: Z probe repeatability test #endif - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) - case 73: M73(); break; // M73: Set progress percentage (for display on LCD) + #if ENABLED(SET_PROGRESS_MANUALLY) + case 73: M73(); break; // M73: Set progress percentage #endif case 75: M75(); break; // M75: Start print timer diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 2b15706395..d69298e28b 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -114,7 +114,7 @@ * M43 - Display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins (Requires PINS_DEBUGGING) * M48 - Measure Z Probe repeatability: M48 P X Y V E L S. (Requires Z_MIN_PROBE_REPEATABILITY_TEST) * - * M73 - Set the progress percentage. (Requires LCD_SET_PROGRESS_MANUALLY) + * M73 - Set the progress percentage. (Requires SET_PROGRESS_MANUALLY) * M75 - Start the print job timer. * M76 - Pause the print job timer. * M77 - Stop the print job timer. @@ -677,7 +677,7 @@ private: static void M48(); #endif - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) + #if ENABLED(SET_PROGRESS_MANUALLY) static void M73(); #endif diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp index a244e9802f..d3338d396d 100644 --- a/Marlin/src/gcode/host/M115.cpp +++ b/Marlin/src/gcode/host/M115.cpp @@ -142,7 +142,7 @@ void GcodeSuite::M115() { cap_line(F("LEVELING_DATA"), ENABLED(HAS_LEVELING)); // BUILD_PERCENT (M73) - cap_line(F("BUILD_PERCENT"), ENABLED(LCD_SET_PROGRESS_MANUALLY)); + cap_line(F("BUILD_PERCENT"), ENABLED(SET_PROGRESS_PERCENT)); // SOFTWARE_POWER (M80, M81) cap_line(F("SOFTWARE_POWER"), ENABLED(PSU_CONTROL)); diff --git a/Marlin/src/gcode/lcd/M73.cpp b/Marlin/src/gcode/lcd/M73.cpp index a86eee4d99..77d93019ac 100644 --- a/Marlin/src/gcode/lcd/M73.cpp +++ b/Marlin/src/gcode/lcd/M73.cpp @@ -22,21 +22,35 @@ #include "../../inc/MarlinConfig.h" -#if ENABLED(LCD_SET_PROGRESS_MANUALLY) +#if ENABLED(SET_PROGRESS_MANUALLY) #include "../gcode.h" #include "../../lcd/marlinui.h" #include "../../sd/cardreader.h" +#include "../../libs/numtostr.h" #if ENABLED(DWIN_LCD_PROUI) #include "../../lcd/e3v2/proui/dwin.h" #endif +#if ENABLED(M73_REPORT) + #define M73_REPORT_PRUSA +#endif + /** * M73: Set percentage complete (for display on LCD) * * Example: - * M73 P25 ; Set progress to 25% + * M73 P25.63 ; Set progress to 25.63% + * M73 R456 ; Set remaining time to 456 minutes + * M73 C12 ; Set next interaction countdown to 12 minutes + * M73 ; Report current values + * + * Use a shorter-than-Průša report format: + * M73 Percent done: ---%; Time left: -----m; Change: -----m; + * + * When PRINT_PROGRESS_SHOW_DECIMALS is enabled - reports percent with 100 / 23.4 / 3.45 format + * */ void GcodeSuite::M73() { @@ -46,17 +60,39 @@ void GcodeSuite::M73() { #else - if (parser.seenval('P')) - ui.set_progress((PROGRESS_SCALE) > 1 - ? parser.value_float() * (PROGRESS_SCALE) - : parser.value_byte() - ); + #if ENABLED(SET_PROGRESS_PERCENT) + if (parser.seenval('P')) + ui.set_progress((PROGRESS_SCALE) > 1 + ? parser.value_float() * (PROGRESS_SCALE) + : parser.value_byte() + ); + #endif - #if ENABLED(USE_M73_REMAINING_TIME) + #if ENABLED(SET_REMAINING_TIME) if (parser.seenval('R')) ui.set_remaining_time(60 * parser.value_ulong()); #endif + #if ENABLED(SET_INTERACTION_TIME) + if (parser.seenval('C')) ui.set_interaction_time(60 * parser.value_ulong()); + #endif + + #endif + + #if ENABLED(M73_REPORT) + { + SERIAL_ECHO_MSG( + TERN(M73_REPORT_PRUSA, "M73 Percent done: ", "Progress: ") + , TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(ui.get_progress_permyriad()), ui.get_progress_percent()) + #if ENABLED(SET_REMAINING_TIME) + , TERN(M73_REPORT_PRUSA, "; Print time remaining in mins: ", "%; Time left: "), ui.remaining_time / 60 + #endif + #if ENABLED(SET_INTERACTION_TIME) + , TERN(M73_REPORT_PRUSA, "; Change in mins: ", "m; Change: "), ui.interaction_time / 60 + #endif + , TERN(M73_REPORT_PRUSA, ";", "m") + ); + } #endif } -#endif // LCD_SET_PROGRESS_MANUALLY +#endif // SET_PROGRESS_MANUALLY diff --git a/Marlin/src/gcode/sd/M1001.cpp b/Marlin/src/gcode/sd/M1001.cpp index 197177882c..f404358862 100644 --- a/Marlin/src/gcode/sd/M1001.cpp +++ b/Marlin/src/gcode/sd/M1001.cpp @@ -34,7 +34,7 @@ #include "../queue.h" #endif -#if EITHER(LCD_SET_PROGRESS_MANUALLY, SD_REPRINT_LAST_SELECTED_FILE) +#if EITHER(SET_PROGRESS_MANUALLY, SD_REPRINT_LAST_SELECTED_FILE) #include "../../lcd/marlinui.h" #endif @@ -84,7 +84,7 @@ void GcodeSuite::M1001() { process_subcommands_now(F("M77")); // Set the progress bar "done" state - TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress_done()); + TERN_(SET_PROGRESS_PERCENT, ui.set_progress_done()); // Announce SD file completion { diff --git a/Marlin/src/gcode/sd/M23.cpp b/Marlin/src/gcode/sd/M23.cpp index 51bc824130..8722e9b6de 100644 --- a/Marlin/src/gcode/sd/M23.cpp +++ b/Marlin/src/gcode/sd/M23.cpp @@ -38,7 +38,7 @@ void GcodeSuite::M23() { for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0'; card.openFileRead(parser.string_arg); - TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress(0)); + TERN_(SET_PROGRESS_PERCENT, ui.set_progress(0)); } #endif // SDSUPPORT diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 5e23cedc4d..e1c764f9f0 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -529,10 +529,6 @@ #define HAS_MANUAL_MOVE_MENU 1 #endif -#if ANY(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL, IS_DWIN_MARLINUI, DWIN_CREALITY_LCD_JYERSUI) - #define CAN_SHOW_REMAINING_TIME 1 -#endif - #if HAS_MARLINUI_U8GLIB #ifndef LCD_PIXEL_WIDTH #define LCD_PIXEL_WIDTH 128 diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index c3f746dc72..ba8c3587fe 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -599,10 +599,16 @@ #undef MENU_ADDAUTOSTART #endif -#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) +#if EITHER(SDSUPPORT, SET_PROGRESS_MANUALLY) #define HAS_PRINT_PROGRESS 1 #endif +#if DISABLED(SET_PROGRESS_MANUALLY) + #undef SET_REMAINING_TIME + #undef SET_INTERACTION_TIME + #undef M73_REPORT +#endif + #if ANY(HAS_MARLINUI_MENU, ULTIPANEL_FEEDMULTIPLY, SOFT_RESET_ON_KILL) #define HAS_ENCODER_ACTION 1 #endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 95d0e74922..a76ea7418b 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -587,7 +587,7 @@ #elif defined(MKS_LCD12864) #error "MKS_LCD12864 is now MKS_LCD12864A or MKS_LCD12864B." #elif defined(DOGM_SD_PERCENT) - #error "DOGM_SD_PERCENT is now SHOW_SD_PERCENT." + #error "DOGM_SD_PERCENT is now SHOW_PROGRESS_PERCENT." #elif defined(NEOPIXEL_BKGD_LED_INDEX) #error "NEOPIXEL_BKGD_LED_INDEX is now NEOPIXEL_BKGD_INDEX_FIRST." #elif defined(TEMP_SENSOR_1_AS_REDUNDANT) @@ -646,6 +646,12 @@ #error "TOUCH_IDLE_SLEEP (seconds) is now TOUCH_IDLE_SLEEP_MINS (minutes)." #elif defined(LCD_BACKLIGHT_TIMEOUT) #error "LCD_BACKLIGHT_TIMEOUT (seconds) is now LCD_BACKLIGHT_TIMEOUT_MINS (minutes)." +#elif defined(LCD_SET_PROGRESS_MANUALLY) + #error "LCD_SET_PROGRESS_MANUALLY is now SET_PROGRESS_MANUALLY." +#elif defined(USE_M73_REMAINING_TIME) + #error "USE_M73_REMAINING_TIME is now SET_REMAINING_TIME." +#elif defined(SHOW_SD_PERCENT) + #error "SHOW_SD_PERCENT is now SHOW_PROGRESS_PERCENT." #endif // L64xx stepper drivers have been removed @@ -894,8 +900,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS * Progress Bar */ #if ENABLED(LCD_PROGRESS_BAR) - #if NONE(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) - #error "LCD_PROGRESS_BAR requires SDSUPPORT or LCD_SET_PROGRESS_MANUALLY." + #if NONE(SDSUPPORT, SET_PROGRESS_MANUALLY) + #error "LCD_PROGRESS_BAR requires SDSUPPORT or SET_PROGRESS_MANUALLY." #elif NONE(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) #error "LCD_PROGRESS_BAR only applies to HD44780 character LCD and TFTGLCD_PANEL_(SPI|I2C)." #elif HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI @@ -905,12 +911,14 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #elif PROGRESS_MSG_EXPIRE < 0 #error "PROGRESS_MSG_EXPIRE must be greater than or equal to 0." #endif -#elif ENABLED(LCD_SET_PROGRESS_MANUALLY) && NONE(HAS_MARLINUI_U8GLIB, HAS_GRAPHICAL_TFT, HAS_MARLINUI_HD44780, EXTENSIBLE_UI, HAS_DWIN_E3V2, IS_DWIN_MARLINUI) - #error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR, Character LCD, Graphical LCD, TFT, DWIN_CREALITY_LCD, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI, DWIN_MARLINUI_*, OR EXTENSIBLE_UI." #endif -#if ENABLED(USE_M73_REMAINING_TIME) && DISABLED(LCD_SET_PROGRESS_MANUALLY) - #error "USE_M73_REMAINING_TIME requires LCD_SET_PROGRESS_MANUALLY" +#if ENABLED(SET_PROGRESS_MANUALLY) && NONE(SET_PROGRESS_PERCENT, SET_REMAINING_TIME, SET_INTERACTION_TIME) + #error "SET_PROGRESS_MANUALLY requires at least one of SET_PROGRESS_PERCENT, SET_REMAINING_TIME, SET_INTERACTION_TIME to be enabled." +#endif + +#if HAS_LCDPRINT && LCD_HEIGHT < 4 && ANY(SHOW_PROGRESS_PERCENT, SHOW_ELAPSED_TIME, SHOW_REMAINING_TIME, SHOW_INTERACTION_TIME) + #error "Displays with fewer than 4 rows of text can't show progress values." #endif #if !HAS_MARLINUI_MENU && ENABLED(SD_REPRINT_LAST_SELECTED_FILE) @@ -4038,10 +4046,6 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive."); #error "COOLANT_FLOOD requires COOLANT_FLOOD_PIN to be defined." #endif -#if NONE(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI, IS_DWIN_MARLINUI) && ENABLED(PRINT_PROGRESS_SHOW_DECIMALS) - #error "PRINT_PROGRESS_SHOW_DECIMALS currently requires a Graphical LCD." -#endif - #if HAS_ADC_BUTTONS && defined(ADC_BUTTON_DEBOUNCE_DELAY) && ADC_BUTTON_DEBOUNCE_DELAY < 16 #error "ADC_BUTTON_DEBOUNCE_DELAY must be greater than 16." #endif diff --git a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp index b8dc8db817..ba222897fc 100644 --- a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp @@ -612,20 +612,6 @@ FORCE_INLINE void _draw_bed_status(const bool blink) { _draw_heater_status(H_BED, TERN0(HAS_LEVELING, blink && planner.leveling_active) ? '_' : LCD_STR_BEDTEMP[0], blink); } -#if HAS_PRINT_PROGRESS - - FORCE_INLINE void _draw_print_progress() { - const uint8_t progress = ui.get_progress_percent(); - lcd_put_u8str(F(TERN(SDSUPPORT, "SD", "P:"))); - if (progress) - lcd_put_u8str(ui8tostr3rj(progress)); - else - lcd_put_u8str(F("---")); - lcd_put_lchar('%'); - } - -#endif - #if ENABLED(LCD_PROGRESS_BAR) void MarlinUI::draw_progress_bar(const uint8_t percent) { @@ -733,6 +719,56 @@ void MarlinUI::draw_status_message(const bool blink) { #endif } +#if HAS_PRINT_PROGRESS + #define TPOFFSET (LCD_WIDTH - 1) + static uint8_t timepos = TPOFFSET - 6; + static char buffer[14]; + static lcd_uint_t pc, pr; + + #if ENABLED(SHOW_PROGRESS_PERCENT) + void MarlinUI::drawPercent() { + const uint8_t progress = ui.get_progress_percent(); + if (progress) { + lcd_moveto(pc, pr); + lcd_put_u8str(F(TERN(IS_SD_PRINTING, "SD", "P:"))); + lcd_put_u8str(TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(ui.get_progress_permyriad()), ui8tostr3rj(progress))); + lcd_put_lchar('%'); + } + } + #endif + #if ENABLED(SHOW_REMAINING_TIME) + void MarlinUI::drawRemain() { + const duration_t remaint = ui.get_remaining_time(); + if (printJobOngoing()) { + timepos = TPOFFSET - remaint.toDigital(buffer); + lcd_put_lchar(TERN(LCD_INFO_SCREEN_STYLE, 11, timepos), 2, 'R'); + lcd_put_u8str(buffer); + } + } + #endif + #if ENABLED(SHOW_INTERACTION_TIME) + void MarlinUI::drawInter() { + const duration_t interactt = ui.interaction_time; + if (printingIsActive() && interactt.value) { + timepos = TPOFFSET - interactt.toDigital(buffer); + lcd_put_lchar(TERN(LCD_INFO_SCREEN_STYLE, 11, timepos), 2, 'C'); + lcd_put_u8str(buffer); + } + } + #endif + #if ENABLED(SHOW_ELAPSED_TIME) + void MarlinUI::drawElapsed() { + const duration_t elapsedt = print_job_timer.duration(); + if (printJobOngoing()) { + timepos = TPOFFSET - elapsedt.toDigital(buffer); + lcd_put_lchar(TERN(LCD_INFO_SCREEN_STYLE, 11, timepos), 2, 'E'); + //lcd_put_lchar(timepos, 2, LCD_STR_CLOCK[0]); + lcd_put_u8str(buffer); + } + } + #endif +#endif // HAS_PRINT_PROGRESS + /** * LCD_INFO_SCREEN_STYLE 0 : Classic Status Screen * @@ -765,35 +801,6 @@ void MarlinUI::draw_status_message(const bool blink) { * |01234567890123456789| */ -inline uint8_t draw_elapsed_or_remaining_time(uint8_t timepos, const bool blink) { - char buffer[14]; - - #if ENABLED(SHOW_REMAINING_TIME) - const bool show_remain = TERN1(ROTATE_PROGRESS_DISPLAY, blink) && printingIsActive(); - if (show_remain) { - #if ENABLED(USE_M73_REMAINING_TIME) - duration_t remaining = ui.get_remaining_time(); - #else - uint8_t progress = ui.get_progress_percent(); - uint32_t elapsed = print_job_timer.duration(); - duration_t remaining = (progress > 0) ? ((elapsed * 25600 / progress) >> 8) - elapsed : 0; - #endif - timepos -= remaining.toDigital(buffer); - lcd_put_lchar(timepos, 2, 'R'); - } - #else - constexpr bool show_remain = false; - #endif - - if (!show_remain) { - duration_t elapsed = print_job_timer.duration(); - timepos -= elapsed.toDigital(buffer); - lcd_put_lchar(timepos, 2, LCD_STR_CLOCK[0]); - } - lcd_put_u8str(buffer); - return timepos; -} - void MarlinUI::draw_status_screen() { const bool blink = get_blink(); @@ -856,8 +863,8 @@ void MarlinUI::draw_status_screen() { #if LCD_WIDTH < 20 #if HAS_PRINT_PROGRESS - lcd_moveto(0, 2); - _draw_print_progress(); + pc = 0, pr = 2; + rotate_progress(); #endif #else // LCD_WIDTH >= 20 @@ -940,12 +947,11 @@ void MarlinUI::draw_status_screen() { lcd_put_u8str(i16tostr3rj(feedrate_percentage)); lcd_put_lchar('%'); - const uint8_t timepos = draw_elapsed_or_remaining_time(LCD_WIDTH - 1, blink); - #if LCD_WIDTH >= 20 - lcd_moveto(timepos - 7, 2); + #if HAS_PRINT_PROGRESS - _draw_print_progress(); + pc = timepos - 7, pr = 2; + rotate_progress(); #else char c; uint16_t per; @@ -1016,7 +1022,7 @@ void MarlinUI::draw_status_screen() { // ========== Line 3 ========== // - // SD Percent, Hotend 2, or Bed + // Progress percent, Hotend 2, or Bed // lcd_moveto(0, 2); #if HOTENDS > 2 @@ -1025,24 +1031,17 @@ void MarlinUI::draw_status_screen() { _draw_bed_status(blink); #elif HAS_PRINT_PROGRESS #define DREW_PRINT_PROGRESS 1 - _draw_print_progress(); + pc = 0, pr = 2; + rotate_progress(); #endif // - // Elapsed Time or SD Percent + // All progress strings // - lcd_moveto(LCD_WIDTH - 9, 2); - #if HAS_PRINT_PROGRESS && !DREW_PRINT_PROGRESS - - _draw_print_progress(); - - #else - - (void)draw_elapsed_or_remaining_time(LCD_WIDTH - 4, blink); - + pc = LCD_WIDTH - 9, pr = 2; + rotate_progress(); #endif - #endif // LCD_INFO_SCREEN_STYLE 1 // ========= Last Line ======== diff --git a/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp b/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp index f3d98ec555..029a04bf97 100644 --- a/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp +++ b/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp @@ -606,7 +606,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const const uint8_t progress = ui._get_progress(); #if ENABLED(SDSUPPORT) lcd_put_u8str(F("SD")); - #elif ENABLED(LCD_SET_PROGRESS_MANUALLY) + #elif ENABLED(SET_PROGRESS_PERCENT) lcd_put_u8str(F("P:")); #endif if (progress) diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index 67039d52de..81119c0a10 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -40,9 +40,7 @@ #include "../../gcode/parser.h" // for units (and volumetric) -#if ENABLED(LCD_SHOW_E_TOTAL) - #include "../../MarlinCore.h" // for printingIsActive() -#endif +#include "../../MarlinCore.h" // for printingIsActive() #if ENABLED(FILAMENT_LCD_DISPLAY) #include "../../feature/filwidth.h" @@ -445,6 +443,55 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const lcd_put_u8str(value); } +// Prepare strings for progress display +#if HAS_PRINT_PROGRESS + #define _PRGR_INFO_X(len) (LCD_PIXEL_WIDTH - (len) * (MENU_FONT_WIDTH)) + #define PCENTERED 1 // center percent value over progress bar, else align to the right + static uint8_t lastProgress = 0xFF; + static u8g_uint_t progress_bar_solid_width = 0; + #if ENABLED(SHOW_PROGRESS_PERCENT) + static char progress_string[5]; + static u8g_uint_t progress_x_pos; + void MarlinUI::drawPercent() { + if (progress_string[0]) { + lcd_put_u8str(progress_x_pos, EXTRAS_BASELINE, progress_string); + lcd_put_lchar('%'); + } + } + #endif + #if ENABLED(SHOW_REMAINING_TIME) + static char remaining_string[10]; + static u8g_uint_t remaining_x_pos = 0; + void MarlinUI::drawRemain() { + if (printJobOngoing()){ + lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, F("R:")); + lcd_put_u8str(remaining_x_pos, EXTRAS_BASELINE, remaining_string); + } + } + #endif + #if ENABLED(SHOW_INTERACTION_TIME) + static char interaction_string[10]; + static u8g_uint_t interaction_x_pos = 0; + void MarlinUI::drawInter() { + if (printingIsActive() && interaction_string[0]) { + lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, F("C:")); + lcd_put_u8str(interaction_x_pos, EXTRAS_BASELINE, interaction_string); + } + } + #endif + #if ENABLED(SHOW_ELAPSED_TIME) + static char elapsed_string[10]; + static u8g_uint_t elapsed_x_pos = 0; + static uint8_t lastElapsed; + void MarlinUI::drawElapsed() { + if (printJobOngoing()) { + lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, F("E:")); + lcd_put_u8str(elapsed_x_pos, EXTRAS_BASELINE, elapsed_string); + } + } + #endif +#endif // HAS_PRINT_PROGRESS + /** * Draw the Status Screen for a 128x64 DOGM (U8glib) display. * @@ -459,30 +506,6 @@ void MarlinUI::draw_status_screen() { static char wstring[5], mstring[4]; #endif - #if HAS_PRINT_PROGRESS - #if DISABLED(SHOW_SD_PERCENT) - #define _SD_INFO_X(len) (PROGRESS_BAR_X + (PROGRESS_BAR_WIDTH) / 2 - (len) * (MENU_FONT_WIDTH) / 2) - #else - #define _SD_INFO_X(len) (LCD_PIXEL_WIDTH - (len) * (MENU_FONT_WIDTH)) - #endif - - #if ENABLED(SHOW_SD_PERCENT) - static char progress_string[5]; - #endif - static uint8_t lastElapsed = 0xFF, lastProgress = 0xFF; - static u8g_uint_t elapsed_x_pos = 0, progress_bar_solid_width = 0; - static char elapsed_string[16]; - #if ENABLED(SHOW_REMAINING_TIME) - static u8g_uint_t estimation_x_pos = 0; - static char estimation_string[10]; - #if BOTH(SHOW_SD_PERCENT, ROTATE_PROGRESS_DISPLAY) - static u8g_uint_t progress_x_pos = 0; - static uint8_t progress_state = 0; - static bool prev_blink = 0; - #endif - #endif - #endif - const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive()); // At the first page, generate new display values @@ -523,61 +546,59 @@ void MarlinUI::draw_status_screen() { // Progress / elapsed / estimation updates and string formatting to avoid float math on each LCD draw #if HAS_PRINT_PROGRESS const progress_t progress = TERN(HAS_PRINT_PROGRESS_PERMYRIAD, get_progress_permyriad, get_progress_percent)(); - duration_t elapsed = print_job_timer.duration(); - const uint8_t p = progress & 0xFF, ev = elapsed.value & 0xFF; + duration_t elapsedt = print_job_timer.duration(); + const uint8_t p = progress & 0xFF, ev = elapsedt.value & 0xFF; if (p != lastProgress) { lastProgress = p; progress_bar_solid_width = u8g_uint_t((PROGRESS_BAR_WIDTH - 2) * (progress / (PROGRESS_SCALE)) * 0.01f); - #if ENABLED(SHOW_SD_PERCENT) - if (progress == 0) { + #if ENABLED(SHOW_PROGRESS_PERCENT) + if (progress == 0) progress_string[0] = '\0'; - #if ENABLED(SHOW_REMAINING_TIME) - estimation_string[0] = '\0'; - estimation_x_pos = _SD_INFO_X(0); - #endif - } else strcpy(progress_string, TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(progress), ui8tostr3rj(progress / (PROGRESS_SCALE)))); - - #if BOTH(SHOW_REMAINING_TIME, ROTATE_PROGRESS_DISPLAY) // Tri-state progress display mode - progress_x_pos = _SD_INFO_X(strlen(progress_string) + 1); - #endif + progress_x_pos = TERN(PCENTERED, 77, _PRGR_INFO_X(strlen(progress_string) + 1)); #endif } - constexpr bool can_show_days = DISABLED(SHOW_SD_PERCENT) || ENABLED(ROTATE_PROGRESS_DISPLAY); - if (ev != lastElapsed) { - lastElapsed = ev; - const uint8_t len = elapsed.toDigital(elapsed_string, can_show_days && elapsed.value >= 60*60*24L); - elapsed_x_pos = _SD_INFO_X(len); + #if ENABLED(SHOW_INTERACTION_TIME) + if (!(interaction_time)) { + interaction_string[0] = '\0'; + interaction_x_pos = _PRGR_INFO_X(0); + } + else { + const duration_t interactt = ui.interaction_time; + interactt.toDigital(interaction_string, interactt.value >= 60*60*24L); + interaction_x_pos = _PRGR_INFO_X(strlen(interaction_string)); + } + #endif - #if ENABLED(SHOW_REMAINING_TIME) - if (!(ev & 0x3)) { - uint32_t timeval = (0 - #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) - + get_remaining_time() - #endif - ); - if (!timeval && progress > 0) timeval = elapsed.value * (100 * (PROGRESS_SCALE) - progress) / progress; - if (!timeval) { - estimation_string[0] = '\0'; - estimation_x_pos = _SD_INFO_X(0); - } - else { - duration_t estimation = timeval; - const uint8_t len = estimation.toDigital(estimation_string, can_show_days && estimation.value >= 60*60*24L); - estimation_x_pos = _SD_INFO_X(len + !BOTH(SHOW_SD_PERCENT, ROTATE_PROGRESS_DISPLAY)); - } + #if ENABLED(SHOW_ELAPSED_TIME) + if (ev != lastElapsed) { + lastElapsed = ev; + const uint8_t len = elapsedt.toDigital(elapsed_string, elapsedt.value >= 60*60*24L); + elapsed_x_pos = _PRGR_INFO_X(len); + } + #endif + + #if ENABLED(SHOW_REMAINING_TIME) + if (!(ev & 0x3)) { + uint32_t timeval = get_remaining_time(); + if (!timeval) { + remaining_string[0] = '\0'; + remaining_x_pos = _PRGR_INFO_X(0); } - #endif - } + else { + const duration_t remaint = timeval; + const uint8_t len = remaint.toDigital(remaining_string, remaint.value >= 60*60*24L); + remaining_x_pos = _PRGR_INFO_X(len); + } + } + #endif #endif } - const bool blink = get_blink(); - // Status Menu Font set_font(FONT_STATUSMENU); @@ -634,6 +655,8 @@ void MarlinUI::draw_status_screen() { u8g.drawBitmapP(STATUS_CHAMBER_X, chambery, STATUS_CHAMBER_BYTEWIDTH, chamberh, CHAMBER_BITMAP(CHAMBER_ALT())); #endif + const bool blink = ui.get_blink(); + #if DO_DRAW_FAN #if STATUS_FAN_FRAMES > 2 static bool old_blink; @@ -664,8 +687,7 @@ void MarlinUI::draw_status_screen() { if (PAGE_UNDER(6 + 1 + 12 + 1 + 6 + 1)) { // Extruders #if DO_DRAW_HOTENDS - LOOP_L_N(e, MAX_HOTEND_DRAW) - _draw_hotend_status((heater_id_t)e, blink); + LOOP_L_N(e, MAX_HOTEND_DRAW) _draw_hotend_status((heater_id_t)e, blink); #endif // Laser / Spindle @@ -757,74 +779,18 @@ void MarlinUI::draw_status_screen() { #endif // SDSUPPORT #if HAS_PRINT_PROGRESS - // // Progress bar frame - // - if (PAGE_CONTAINS(PROGRESS_BAR_Y, PROGRESS_BAR_Y + 3)) u8g.drawFrame(PROGRESS_BAR_X, PROGRESS_BAR_Y, PROGRESS_BAR_WIDTH, 4); - // // Progress bar solid part - // - if (PAGE_CONTAINS(PROGRESS_BAR_Y + 1, PROGRESS_BAR_Y + 2)) u8g.drawBox(PROGRESS_BAR_X + 1, PROGRESS_BAR_Y + 1, progress_bar_solid_width, 2); - if (PAGE_CONTAINS(EXTRAS_BASELINE - INFO_FONT_ASCENT, EXTRAS_BASELINE - 1)) { - - #if ALL(SHOW_SD_PERCENT, SHOW_REMAINING_TIME, ROTATE_PROGRESS_DISPLAY) - - if (prev_blink != blink) { - prev_blink = blink; - if (++progress_state >= 3) progress_state = 0; - } - - if (progress_state == 0) { - if (progress_string[0]) { - lcd_put_u8str(progress_x_pos, EXTRAS_BASELINE, progress_string); - lcd_put_lchar('%'); - } - } - else if (progress_state == 2 && estimation_string[0]) { - lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, F("R:")); - lcd_put_u8str(estimation_x_pos, EXTRAS_BASELINE, estimation_string); - } - else if (elapsed_string[0]) { - lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, F("E:")); - lcd_put_u8str(elapsed_x_pos, EXTRAS_BASELINE, elapsed_string); - } - - #else // !SHOW_SD_PERCENT || !SHOW_REMAINING_TIME || !ROTATE_PROGRESS_DISPLAY - - // - // SD Percent Complete - // - - #if ENABLED(SHOW_SD_PERCENT) - if (progress_string[0]) { - lcd_put_u8str(55, EXTRAS_BASELINE, progress_string); // Percent complete - lcd_put_lchar('%'); - } - #endif - - // - // Elapsed Time - // - - #if ENABLED(SHOW_REMAINING_TIME) - if (blink && estimation_string[0]) { - lcd_put_lchar(estimation_x_pos, EXTRAS_BASELINE, 'R'); - lcd_put_u8str(estimation_string); - } - else - #endif - lcd_put_u8str(elapsed_x_pos, EXTRAS_BASELINE, elapsed_string); - - #endif // !SHOW_SD_PERCENT || !SHOW_REMAINING_TIME || !ROTATE_PROGRESS_DISPLAY - } - - #endif // HAS_PRINT_PROGRESS + // Progress strings + if (PAGE_CONTAINS(EXTRAS_BASELINE - INFO_FONT_ASCENT, EXTRAS_BASELINE - 1)) + ui.rotate_progress(); + #endif // // XYZ Coordinates diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp index 492a79a311..9ed0d8a9d6 100644 --- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp +++ b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp @@ -40,12 +40,38 @@ // Lightweight Status Screen for Graphical Display // +/** One hotend layout + * ------------------ + * |⟱ xxx➜xxx° ✱xxx% + * |_ xxx➜xxx° Fxxx% + * ||||||||||R•xxx:xx + * | status string + * ------------------ + * + * hotend temp | fan speed + * bed temp | feedrate + * progress bar| progress time + * status string + * + * **************************** + * Two hotends layout + * ------------------ + * |⟱ xxx➜xxx° ✱xxx% + * |⟱ xxx➜xxx°||||||| + * |_ xxx➜xxx°Rxxx:xx + * | status string + * ------------------ + * + * hotend temp | fan speed + * hotend temp | progress bar + * bed temp | progress time + * status string + */ + #include "../../inc/MarlinConfigPre.h" #if ENABLED(LIGHTWEIGHT_UI) -#include "status_screen_lite_ST7920.h" - #include "../marlinui.h" #include "../fontutils.h" #include "../lcdprint.h" @@ -53,12 +79,13 @@ #include "../../module/motion.h" #include "../../module/printcounter.h" #include "../../module/temperature.h" +#include "../../libs/numtostr.h" #if ENABLED(SDSUPPORT) #include "../../sd/cardreader.h" #endif -#if ENABLED(LCD_SHOW_E_TOTAL) +#if ENABLED(LCD_SHOW_E_TOTAL) || HAS_PRINT_PROGRESS #include "../../MarlinCore.h" // for printingIsActive #endif @@ -72,6 +99,9 @@ #define DDRAM_LINE_3 0x08 #define DDRAM_LINE_4 0x18 +#include "status_screen_lite_ST7920.h" +extern ST7920_Lite_Status_Screen lightUI; + ST7920_Lite_Status_Screen::st7920_state_t ST7920_Lite_Status_Screen::current_bits; void ST7920_Lite_Status_Screen::cmd(const uint8_t cmd) { @@ -442,72 +472,6 @@ void ST7920_Lite_Status_Screen::draw_static_elements() { draw_fan_icon(false); } -/** - * Although this is undocumented, the ST7920 allows the character - * data buffer (DDRAM) to be used in conjunction with the graphics - * bitmap buffer (CGRAM). The contents of the graphics buffer is - * XORed with the data from the character generator. This allows - * us to make the progress bar out of graphical data (the bar) and - * text data (the percentage). - */ -void ST7920_Lite_Status_Screen::draw_progress_bar(const uint8_t value) { - #if HOTENDS == 1 - // If we have only one extruder, draw a long progress bar on the third line - constexpr uint8_t top = 1, // Top in pixels - bottom = 13, // Bottom in pixels - left = 12, // Left edge, in 16-bit words - width = 4; // Width of progress bar, in 16-bit words - #else - constexpr uint8_t top = 16 + 1, - bottom = 16 + 13, - left = 5, - width = 3; - #endif - const uint8_t char_pcnt = 100 / width; // How many percent does each 16-bit word represent? - - // Draw the progress bar as a bitmap in CGRAM - LOOP_S_LE_N(y, top, bottom) { - set_gdram_address(left, y); - begin_data(); - LOOP_L_N(x, width) { - uint16_t gfx_word = 0x0000; - if ((x + 1) * char_pcnt <= value) - gfx_word = 0xFFFF; // Draw completely filled bytes - else if ((x * char_pcnt) < value) - gfx_word = int(0x8000) >> (value % char_pcnt) * 16 / char_pcnt; // Draw partially filled bytes - - // Draw the frame around the progress bar - if (y == top || y == bottom) - gfx_word = 0xFFFF; // Draw top/bottom border - else if (x == width - 1) - gfx_word |= 0x0001; // Draw right border - else if (x == 0) - gfx_word |= 0x8000; // Draw left border - write_word(gfx_word); - } - } - - // Draw the percentage as text in DDRAM - #if HOTENDS == 1 - set_ddram_address(DDRAM_LINE_3 + 4); - begin_data(); - write_byte(' '); - #else - set_ddram_address(DDRAM_LINE_2 + left); - begin_data(); - #endif - - // Draw centered - if (value > 9) { - write_number(value, 4); - write_str(F("% ")); - } - else { - write_number(value, 3); - write_str(F("% ")); - } -} - void ST7920_Lite_Status_Screen::draw_fan_icon(const bool whichIcon) { set_ddram_address(DDRAM_LINE_1 + 5); begin_data(); @@ -592,22 +556,8 @@ void ST7920_Lite_Status_Screen::draw_fan_speed(const uint8_t value) { write_byte('%'); } -void ST7920_Lite_Status_Screen::draw_print_time(const duration_t &elapsed, char suffix) { - #if HOTENDS == 1 - set_ddram_address(DDRAM_LINE_3); - #else - set_ddram_address(DDRAM_LINE_3 + 5); - #endif - char str[7]; - int str_length = elapsed.toDigital(str); - str[str_length++] = suffix; - begin_data(); - write_str(str, str_length); -} - void ST7920_Lite_Status_Screen::draw_feedrate_percentage(const uint16_t percentage) { - // We only have enough room for the feedrate when - // we have one extruder + // We only have enough room for the feedrate when we have one extruder #if HOTENDS == 1 set_ddram_address(DDRAM_LINE_2 + 6); begin_data(); @@ -631,11 +581,9 @@ void ST7920_Lite_Status_Screen::draw_status_message() { write_str(str); while (slen < TEXT_MODE_LCD_WIDTH) { write_byte(' '); ++slen; } } - else { - // String is larger than the available space in screen. + else { // String is larger than the available space in ST7920_Lite_Status_Screen:: - // Get a pointer to the next valid UTF8 character - // and the string remaining length + // Get a pointer to the next valid UTF8 character and the string remaining length uint8_t rlen; const char *stat = ui.status_and_len(rlen); write_str(stat, TEXT_MODE_LCD_WIDTH); @@ -643,12 +591,12 @@ void ST7920_Lite_Status_Screen::draw_status_message() { // If the remaining string doesn't completely fill the screen if (rlen < TEXT_MODE_LCD_WIDTH) { uint8_t chars = TEXT_MODE_LCD_WIDTH - rlen; // Amount of space left in characters - write_byte(' '); // Always at 1+ spaces left, draw a space - if (--chars) { // Draw a second space if there's room + write_byte(' '); // Always at 1+ spaces left, draw a space + if (--chars) { // Draw a second space if there's room write_byte(' '); - if (--chars) { // Draw a third space if there's room + if (--chars) { // Draw a third space if there's room write_byte(' '); - if (--chars) write_str(str, chars); // Print a second copy of the message + if (--chars) write_str(str, chars); // Print a second copy of the message } } } @@ -715,11 +663,155 @@ bool ST7920_Lite_Status_Screen::indicators_changed() { return true; } +// Process progress strings +#if HAS_PRINT_PROGRESS + static char screenstr[8]; + + char * ST7920_Lite_Status_Screen::prepare_time_string(const duration_t &time, char prefix) { + static char str[6]; + memset(&screenstr, 0x20, 8); // fill with spaces to avoid artifacts, not doing right-justification to save cycles + screenstr[0] = prefix; + TERN_(HOTENDS == 1, screenstr[1] = 0x07;) // add bullet • separator when there is space + int str_length = time.toDigital(str); + memcpy(&screenstr[TERN(HOTENDS == 1, 2, 1)], str, str_length); //memcpy because we can't have terminator + return screenstr; + } + + void ST7920_Lite_Status_Screen::draw_progress_string(uint8_t addr, const char *str) { + set_ddram_address(addr); + begin_data(); + write_str(str, TERN(HOTENDS == 1, 8, 6)); + } + + #define PPOS (DDRAM_LINE_3 + TERN(HOTENDS == 1, 4, 5)) // progress string position, in 16-bit words + + #if ENABLED(SHOW_PROGRESS_PERCENT) + void MarlinUI::drawPercent() { lightUI.drawPercent(); } + void ST7920_Lite_Status_Screen::drawPercent() { + #define LSHIFT TERN(HOTENDS == 1, 0, 1) + const uint8_t progress = ui.get_progress_percent(); + memset(&screenstr, 0x20, 8); // fill with spaces to avoid artifacts + if (progress){ + memcpy(&screenstr[2 - LSHIFT], \ + TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(ui.get_progress_permyriad()), ui8tostr3rj(progress)), \ + TERN(PRINT_PROGRESS_SHOW_DECIMALS, 4, 3)); + screenstr[(TERN(PRINT_PROGRESS_SHOW_DECIMALS, 6, 5) - LSHIFT)] = '%'; + draw_progress_string(PPOS, screenstr); + } + } + #endif + #if ENABLED(SHOW_REMAINING_TIME) + void MarlinUI::drawRemain() { lightUI.drawRemain(); } + void ST7920_Lite_Status_Screen::drawRemain() { + const duration_t remaint = TERN0(SET_REMAINING_TIME, ui.get_remaining_time()); + if (printJobOngoing() && remaint.value) { + draw_progress_string( PPOS, prepare_time_string(remaint, 'R')); + } + } + #endif + #if ENABLED(SHOW_INTERACTION_TIME) + void MarlinUI::drawInter() { lightUI.drawInter(); } + void ST7920_Lite_Status_Screen::drawInter() { + const duration_t interactt = ui.interaction_time; + if (printingIsActive() && interactt.value) { + draw_progress_string( PPOS, prepare_time_string(interactt, 'C')); + } + } + #endif + #if ENABLED(SHOW_ELAPSED_TIME) + void MarlinUI::drawElapsed() { lightUI.drawElapsed(); } + void ST7920_Lite_Status_Screen::drawElapsed() { + if (printJobOngoing()) { + const duration_t elapsedt = print_job_timer.duration(); + draw_progress_string( PPOS, prepare_time_string(elapsedt, 'E')); + } + } + #endif + + /** + * Although this is undocumented, the ST7920 allows the character + * data buffer (DDRAM) to be used in conjunction with the graphics + * bitmap buffer (CGRAM). The contents of the graphics buffer is + * XORed with the data from the character generator. This allows + * us to make the progress bar out of graphical data (the bar) and + * text data (the percentage). + */ + void ST7920_Lite_Status_Screen::draw_progress_bar(const uint8_t value) { + #if HOTENDS == 1 + // If we have only one extruder, draw a long progress bar on the third line + constexpr uint8_t top = 1, // Top in pixels + bottom = 13, // Bottom in pixels + left = 8, // Left edge, in 16-bit words + width = 4; // Width of progress bar, in 16-bit words + #else + constexpr uint8_t top = 16 + 1, + bottom = 16 + 13, + left = 5, + width = 3; + #endif + const uint8_t char_pcnt = 100 / width; // How many percent does each 16-bit word represent? + + // Draw the progress bar as a bitmap in CGRAM + // This drawing is a mess and only produce readable result around 25% steps + // i.e. 74-76% look fine [|||||||||||||||||||||||| ], but 73% look like this: [|||||||||||||||| | ] + // meaning partially filled bytes produce only single vertical line, and i bet they're not supposed to! + LOOP_S_LE_N(y, top, bottom) { + set_gdram_address(left, y); + begin_data(); + LOOP_L_N(x, width) { + uint16_t gfx_word = 0x0000; + if ((x + 1) * char_pcnt <= value) + gfx_word = 0xFFFF; // Draw completely filled bytes + else if ((x * char_pcnt) < value) + gfx_word = int16_t(0x8000) >> (value % char_pcnt) * 16 / char_pcnt; // Draw partially filled bytes + + // Draw the frame around the progress bar + if (y == top || y == bottom) + gfx_word = 0xFFFF; // Draw top/bottom border + else if (x == width - 1) + gfx_word |= 0x0001; // Draw right border + else if (x == 0) + gfx_word |= 0x8000; // Draw left border + write_word(gfx_word); + } + } + + // // Draw the percentage as text in DDRAM + // #if HOTENDS == 1 + // set_ddram_address(DDRAM_LINE_3 + 4); + // begin_data(); + // write_byte(' '); + // #else + // set_ddram_address(DDRAM_LINE_2 + left); + // begin_data(); + // #endif + + // // Draw centered + // if (value > 9) + // write_number(value, 4); + // else + // write_number(value, 3); + // write_str(F("% ")); + } + + void ST7920_Lite_Status_Screen::update_progress(const bool forceUpdate) { + + // Since the progress bar involves writing + // quite a few bytes to GDRAM, only do this + // when an update is actually necessary. + + const uint8_t progress = ui.get_progress_percent(); + static uint8_t last_progress = 0; + if (forceUpdate || last_progress != progress/2) { + last_progress = progress/2; // Because progress bar turns out only 62||46px wide, we only need to redraw it every 2% + draw_progress_bar(progress); + } + } +#endif // HAS_PRINT_PROGRESS + void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) { if (forceUpdate || indicators_changed()) { const bool blink = ui.get_blink(); - const duration_t elapsed = print_job_timer.duration(); - duration_t remaining = TERN0(USE_M73_REMAINING_TIME, ui.get_remaining_time()); const uint16_t feedrate_perc = feedrate_percentage; const celsius_t extruder_1_temp = thermalManager.wholeDegHotend(0), extruder_1_target = thermalManager.degTargetHotend(0); @@ -736,30 +828,20 @@ void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) { TERN_(HAS_MULTI_HOTEND, draw_extruder_2_temp(extruder_2_temp, extruder_2_target, forceUpdate)); TERN_(HAS_HEATED_BED, draw_bed_temp(bed_temp, bed_target, forceUpdate)); + // Update the fan and bed animations uint8_t spd = thermalManager.fan_speed[0]; #if ENABLED(ADAPTIVE_FAN_SLOWING) if (!blink && thermalManager.fan_speed_scaler[0] < 128) spd = thermalManager.scaledFanSpeed(0, spd); #endif draw_fan_speed(thermalManager.pwmToPercent(spd)); - - // Draw elapsed/remaining time - const bool show_remaining = ENABLED(SHOW_REMAINING_TIME) && (DISABLED(ROTATE_PROGRESS_DISPLAY) || blink); - if (show_remaining && !remaining.second()) { - const auto progress = ui.get_progress_percent(); - if (progress) - remaining = elapsed.second() * (100 - progress) / progress; - } - if (show_remaining && remaining.second()) - draw_print_time(remaining, 'R'); - else - draw_print_time(elapsed); + if (spd) draw_fan_icon(blink); + TERN_(HAS_HEATED_BED, draw_heat_icon(bed_target > 0 && blink, bed_target > 0)); draw_feedrate_percentage(feedrate_perc); - // Update the fan and bed animations - if (spd) draw_fan_icon(blink); - TERN_(HAS_HEATED_BED, draw_heat_icon(bed_target > 0 && blink, bed_target > 0)); + // Update and draw progress strings + TERN_(HAS_PRINT_PROGRESS, ui.rotate_progress()); } } @@ -839,27 +921,6 @@ void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) { #endif } -void ST7920_Lite_Status_Screen::update_progress(const bool forceUpdate) { - #if EITHER(LCD_SET_PROGRESS_MANUALLY, SDSUPPORT) - - // Since the progress bar involves writing - // quite a few bytes to GDRAM, only do this - // when an update is actually necessary. - - static uint8_t last_progress = 0; - const uint8_t progress = ui.get_progress_percent(); - if (forceUpdate || last_progress != progress) { - last_progress = progress; - draw_progress_bar(progress); - } - - #else - - UNUSED(forceUpdate); - - #endif -} - void ST7920_Lite_Status_Screen::update(const bool forceUpdate) { cs(); update_indicators(forceUpdate); @@ -902,7 +963,7 @@ void ST7920_Lite_Status_Screen::clear_text_buffer() { } void MarlinUI::draw_status_screen() { - ST7920_Lite_Status_Screen::update(false); + lightUI.update(false); } // This method is called before each screen update and @@ -912,9 +973,9 @@ void MarlinUI::lcd_in_status(const bool inStatus) { static bool lastInStatus = false; if (lastInStatus == inStatus) return; if ((lastInStatus = inStatus)) - ST7920_Lite_Status_Screen::on_entry(); + lightUI.on_entry(); else - ST7920_Lite_Status_Screen::on_exit(); + lightUI.on_exit(); } #endif // LIGHTWEIGHT_UI diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h index 7fe878356b..d838ee1a3a 100644 --- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h +++ b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h @@ -75,7 +75,6 @@ class ST7920_Lite_Status_Screen { protected: static void draw_degree_symbol(uint8_t x, uint8_t y, const bool draw); static void draw_static_elements(); - static void draw_progress_bar(const uint8_t value); static void draw_fan_icon(const bool whichIcon); static void draw_heat_icon(const bool whichIcon, const bool heating); static void draw_temps(uint8_t line, const int16_t temp, const int16_t target, bool showTarget, bool targetStateChange); @@ -83,7 +82,12 @@ class ST7920_Lite_Status_Screen { static void draw_extruder_2_temp(const int16_t temp, const int16_t target, bool forceUpdate=false); static void draw_bed_temp(const int16_t temp, const int16_t target, bool forceUpdate=false); static void draw_fan_speed(const uint8_t value); - static void draw_print_time(const duration_t &elapsed, char suffix=' '); + #if HAS_PRINT_PROGRESS + static void draw_progress_bar(const uint8_t value); + static char* prepare_time_string(const duration_t &time, char prefix=' '); + static void draw_progress_string(uint8_t addr, const char *str); + static void update_progress(const bool forceUpdate); + #endif static void draw_feedrate_percentage(const uint16_t percentage); static void draw_status_message(); static void draw_position(const xyze_pos_t &pos, bool position_known=true); @@ -96,11 +100,18 @@ class ST7920_Lite_Status_Screen { static void update_indicators(const bool forceUpdate); static void update_position(const bool forceUpdate, bool resetChecksum); static void update_status_or_position(bool forceUpdate); - static void update_progress(const bool forceUpdate); public: static void update(const bool forceUpdate); static void on_entry(); static void on_exit(); static void clear_text_buffer(); + #if HAS_PRINT_PROGRESS + static void drawPercent(); + static void drawRemain(); + static void drawInter(); + static void drawElapsed(); + #endif }; + +extern ST7920_Lite_Status_Screen lightUI; diff --git a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp index df758da617..d6f3d859c6 100644 --- a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp @@ -733,7 +733,7 @@ void CrealityDWINClass::Draw_Print_Screen() { Update_Status_Bar(true); Draw_Print_ProgressBar(); Draw_Print_ProgressElapsed(); - TERN_(USE_M73_REMAINING_TIME, Draw_Print_ProgressRemain()); + TERN_(SET_REMAINING_TIME, Draw_Print_ProgressRemain()); Draw_Print_Filename(true); } @@ -759,7 +759,7 @@ void CrealityDWINClass::Draw_Print_ProgressBar() { DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_percent, Percent_Color), Color_Bg_Black, 133, 133, F("%")); } -#if ENABLED(USE_M73_REMAINING_TIME) +#if ENABLED(SET_REMAINING_TIME) void CrealityDWINClass::Draw_Print_ProgressRemain() { uint16_t remainingtime = ui.get_remaining_time(); @@ -4565,8 +4565,8 @@ void CrealityDWINClass::Start_Print(bool sd) { } else strcpy_P(filename, PSTR("Host Print")); - TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress(0)); - TERN_(USE_M73_REMAINING_TIME, ui.set_remaining_time(0)); + TERN_(SET_PROGRESS_PERCENT, ui.set_progress(0)); + TERN_(SET_REMAINING_TIME, ui.set_remaining_time(0)); Draw_Print_Screen(); } } @@ -4575,8 +4575,8 @@ void CrealityDWINClass::Stop_Print() { printing = false; sdprint = false; thermalManager.cooldown(); - TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress(100 * (PROGRESS_SCALE))); - TERN_(USE_M73_REMAINING_TIME, ui.set_remaining_time(0)); + TERN_(SET_PROGRESS_PERCENT, ui.set_progress(100 * (PROGRESS_SCALE))); + TERN_(SET_REMAINING_TIME, ui.set_remaining_time(0)); Draw_Print_confirm(); } @@ -4653,7 +4653,7 @@ void CrealityDWINClass::Screen_Update() { if (process == Print) { Draw_Print_ProgressBar(); Draw_Print_ProgressElapsed(); - TERN_(USE_M73_REMAINING_TIME, Draw_Print_ProgressRemain()); + TERN_(SET_REMAINING_TIME, Draw_Print_ProgressRemain()); } } diff --git a/Marlin/src/lcd/e3v2/jyersui/dwin.h b/Marlin/src/lcd/e3v2/jyersui/dwin.h index 8985647cd1..7e213a65e5 100644 --- a/Marlin/src/lcd/e3v2/jyersui/dwin.h +++ b/Marlin/src/lcd/e3v2/jyersui/dwin.h @@ -188,7 +188,7 @@ public: static void Draw_Print_Screen(); static void Draw_Print_Filename(const bool reset=false); static void Draw_Print_ProgressBar(); - #if ENABLED(USE_M73_REMAINING_TIME) + #if ENABLED(SET_REMAINING_TIME) static void Draw_Print_ProgressRemain(); #endif static void Draw_Print_ProgressElapsed(); diff --git a/Marlin/src/lcd/e3v2/marlinui/ui_status_480x272.cpp b/Marlin/src/lcd/e3v2/marlinui/ui_status_480x272.cpp index 8024085ef7..0bd1b2ff2a 100644 --- a/Marlin/src/lcd/e3v2/marlinui/ui_status_480x272.cpp +++ b/Marlin/src/lcd/e3v2/marlinui/ui_status_480x272.cpp @@ -374,11 +374,11 @@ void MarlinUI::draw_status_screen() { #if ENABLED(DWIN_MARLINUI_PORTRAIT) - // Portrait mode only shows one value at a time, and will rotate if ROTATE_PROGRESS_DISPLAY + // Portrait mode only shows one value at a time, and will rotate if many are enabled dwin_string.set(); char prefix = ' '; #if ENABLED(SHOW_REMAINING_TIME) - if (TERN1(ROTATE_PROGRESS_DISPLAY, blink) && print_job_timer.isRunning()) { + if (blink && print_job_timer.isRunning()) { time = get_remaining_time(); prefix = 'R'; } @@ -447,7 +447,7 @@ void MarlinUI::draw_status_screen() { //if (pb_solid < old_solid) DWIN_Draw_Rectangle(1, Color_Bg_Black, pb_left + 1 + pb_solid, pb_top + 1, pb_right - 1, pb_bottom - 1); // Erase the rest - #if ENABLED(SHOW_SD_PERCENT) + #if ENABLED(SHOW_PROGRESS_PERCENT) dwin_string.set(TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(progress), ui8tostr3rj(progress / (PROGRESS_SCALE)))); dwin_string.add('%'); DWIN_Draw_String( diff --git a/Marlin/src/lcd/e3v2/proui/dwin.cpp b/Marlin/src/lcd/e3v2/proui/dwin.cpp index 09c3ca9ab8..06768ed18f 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwin.cpp @@ -43,8 +43,8 @@ #if DISABLED(INDIVIDUAL_AXIS_HOMING_SUBMENU) #warning "INDIVIDUAL_AXIS_HOMING_SUBMENU is recommended with ProUI." #endif -#if DISABLED(LCD_SET_PROGRESS_MANUALLY) - #warning "LCD_SET_PROGRESS_MANUALLY is recommended with ProUI." +#if DISABLED(SET_PROGRESS_MANUALLY) + #warning "SET_PROGRESS_MANUALLY is recommended with ProUI." #endif #if DISABLED(STATUS_MESSAGE_SCROLLING) #warning "STATUS_MESSAGE_SCROLLING is recommended with ProUI." diff --git a/Marlin/src/lcd/extui/dgus/fysetc/DGUSDisplayDef.cpp b/Marlin/src/lcd/extui/dgus/fysetc/DGUSDisplayDef.cpp index a4c0997bf8..0e825c9e7c 100644 --- a/Marlin/src/lcd/extui/dgus/fysetc/DGUSDisplayDef.cpp +++ b/Marlin/src/lcd/extui/dgus/fysetc/DGUSDisplayDef.cpp @@ -63,7 +63,7 @@ const uint16_t VPList_Main[] PROGMEM = { VP_XPos, VP_YPos, VP_ZPos, VP_Fan0_Percentage, VP_Feedrate_Percentage, - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) + #if ENABLED(SET_PROGRESS_PERCENT) VP_PrintProgress_Percentage, #endif 0x0000 diff --git a/Marlin/src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.cpp b/Marlin/src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.cpp index 4c850183da..6e4c76ca68 100644 --- a/Marlin/src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.cpp +++ b/Marlin/src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.cpp @@ -63,7 +63,7 @@ const uint16_t VPList_Main[] PROGMEM = { VP_XPos, VP_YPos, VP_ZPos, VP_Fan0_Percentage, VP_Feedrate_Percentage, - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) + #if ENABLED(SET_PROGRESS_PERCENT) VP_PrintProgress_Percentage, #endif 0x0000 diff --git a/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp b/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp index 86920d6841..ae8d9565e3 100644 --- a/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp +++ b/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp @@ -135,7 +135,7 @@ const uint16_t VPList_Main[] PROGMEM = { VP_XPos, VP_YPos, VP_ZPos, VP_Fan0_Percentage, VP_Feedrate_Percentage, - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) + #if ENABLED(SET_PROGRESS_PERCENT) VP_PrintProgress_Percentage, #endif 0x0000 diff --git a/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp b/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp index be596c8740..5dc3861f65 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp @@ -39,7 +39,7 @@ #include "../../../feature/powerloss.h" #endif -#if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) +#if ENABLED(SET_REMAINING_TIME) #include "../../marlinui.h" #endif @@ -244,7 +244,7 @@ void disp_fan_speed() { } void disp_print_time() { - #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) + #if ENABLED(SET_REMAINING_TIME) const uint32_t r = ui.get_remaining_time(); sprintf_P(public_buf_l, PSTR("%02d:%02d R"), r / 3600, (r % 3600) / 60); #else diff --git a/Marlin/src/lcd/extui/ui_api.h b/Marlin/src/lcd/extui/ui_api.h index bf32c5703e..c2ce52ba4c 100644 --- a/Marlin/src/lcd/extui/ui_api.h +++ b/Marlin/src/lcd/extui/ui_api.h @@ -164,6 +164,9 @@ namespace ExtUI { #if ENABLED(SHOW_REMAINING_TIME) inline uint32_t getProgress_seconds_remaining() { return ui.get_remaining_time(); } #endif + #if ENABLED(SHOW_INTERACTION_TIME) + inline uint32_t getInteraction_seconds_remaining() { return ui.interaction_time; } + #endif #if HAS_LEVELING bool getLevelingActive(); diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index 2f30da001f..00b0d62e1a 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -79,11 +79,16 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; statusResetFunc_t MarlinUI::status_reset_callback; // = nullptr #endif -#if ENABLED(LCD_SET_PROGRESS_MANUALLY) - MarlinUI::progress_t MarlinUI::progress_override; // = 0 - #if ENABLED(USE_M73_REMAINING_TIME) +#if ENABLED(SET_PROGRESS_MANUALLY) + #if ENABLED(SET_PROGRESS_PERCENT) + MarlinUI::progress_t MarlinUI::progress_override; // = 0 + #endif + #if ENABLED(SET_REMAINING_TIME) uint32_t MarlinUI::remaining_time; #endif + #if ENABLED(SET_INTERACTION_TIME) + uint32_t MarlinUI::interaction_time; + #endif #endif #if HAS_MULTI_LANGUAGE @@ -153,7 +158,7 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; bool MarlinUI::lcd_clicked; #endif -#if EITHER(HAS_WIRED_LCD, DWIN_CREALITY_LCD_JYERSUI) +#if LCD_WITH_BLINK bool MarlinUI::get_blink() { static uint8_t blink = 0; @@ -1677,19 +1682,6 @@ void MarlinUI::init() { print_job_timer.start(); // Also called by M24 } - #if HAS_PRINT_PROGRESS - - MarlinUI::progress_t MarlinUI::_get_progress() { - return ( - TERN0(LCD_SET_PROGRESS_MANUALLY, (progress_override & PROGRESS_MASK)) - #if ENABLED(SDSUPPORT) - ?: TERN(HAS_PRINT_PROGRESS_PERMYRIAD, card.permyriadDone(), card.percentDone()) - #endif - ); - } - - #endif - #if HAS_TOUCH_BUTTONS // @@ -1723,6 +1715,38 @@ void MarlinUI::init() { #endif // HAS_DISPLAY +#if HAS_PRINT_PROGRESS + + MarlinUI::progress_t MarlinUI::_get_progress() { + return ( + TERN0(SET_PROGRESS_PERCENT, (progress_override & PROGRESS_MASK)) + #if ENABLED(SDSUPPORT) + ?: TERN(HAS_PRINT_PROGRESS_PERMYRIAD, card.permyriadDone(), card.percentDone()) + #endif + ); + } + + #if LCD_WITH_BLINK + typedef void (*PrintProgress_t)(); + void MarlinUI::rotate_progress() { // Renew and redraw all enabled progress strings + const PrintProgress_t progFunc[] = { + OPTITEM(SHOW_PROGRESS_PERCENT, drawPercent) + OPTITEM(SHOW_ELAPSED_TIME, drawElapsed) + OPTITEM(SHOW_REMAINING_TIME, drawRemain) + OPTITEM(SHOW_INTERACTION_TIME, drawInter) + }; + static bool prev_blink; + static uint8_t i; + if (prev_blink != get_blink()) { + prev_blink = get_blink(); + if (++i >= COUNT(progFunc)) i = 0; + (*progFunc[i])(); + } + } + #endif + +#endif // HAS_PRINT_PROGRESS + #if ENABLED(SDSUPPORT) #if ENABLED(EXTENSIBLE_UI) diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index d2e3708907..b1a98248bb 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -25,7 +25,6 @@ #include "../sd/cardreader.h" #include "../module/motion.h" #include "../libs/buzzer.h" - #include "buttons.h" #if ENABLED(TOUCH_SCREEN_CALIBRATION) @@ -36,7 +35,7 @@ #define MULTI_E_MANUAL 1 #endif -#if HAS_DISPLAY +#if HAS_PRINT_PROGRESS #include "../module/printcounter.h" #endif @@ -86,6 +85,7 @@ typedef bool (*statusResetFunc_t)(); #endif // HAS_WIRED_LCD #if EITHER(HAS_WIRED_LCD, DWIN_CREALITY_LCD_JYERSUI) + #define LCD_WITH_BLINK 1 #define LCD_UPDATE_INTERVAL TERN(HAS_TOUCH_BUTTONS, 50, 100) #endif @@ -303,19 +303,19 @@ public: #define PROGRESS_SCALE 1U #define PROGRESS_MASK 0x7F #endif - #if ENABLED(LCD_SET_PROGRESS_MANUALLY) + #if ENABLED(SET_PROGRESS_PERCENT) static progress_t progress_override; static void set_progress(const progress_t p) { progress_override = _MIN(p, 100U * (PROGRESS_SCALE)); } static void set_progress_done() { progress_override = (PROGRESS_MASK + 1U) + 100U * (PROGRESS_SCALE); } static void progress_reset() { if (progress_override & (PROGRESS_MASK + 1U)) set_progress(0); } #endif - #if ENABLED(SHOW_REMAINING_TIME) + #if EITHER(SHOW_REMAINING_TIME, SET_PROGRESS_MANUALLY) static uint32_t _calculated_remaining_time() { const duration_t elapsed = print_job_timer.duration(); const progress_t progress = _get_progress(); return progress ? elapsed.value * (100 * (PROGRESS_SCALE) - progress) / progress : 0; } - #if ENABLED(USE_M73_REMAINING_TIME) + #if ENABLED(SET_REMAINING_TIME) static uint32_t remaining_time; FORCE_INLINE static void set_remaining_time(const uint32_t r) { remaining_time = r; } FORCE_INLINE static uint32_t get_remaining_time() { return remaining_time ?: _calculated_remaining_time(); } @@ -323,12 +323,32 @@ public: #else FORCE_INLINE static uint32_t get_remaining_time() { return _calculated_remaining_time(); } #endif + #if ENABLED(SET_INTERACTION_TIME) + static uint32_t interaction_time; + FORCE_INLINE static void set_interaction_time(const uint32_t r) { interaction_time = r; } + FORCE_INLINE static void reset_interaction_time() { set_interaction_time(0); } + #endif #endif static progress_t _get_progress(); #if HAS_PRINT_PROGRESS_PERMYRIAD FORCE_INLINE static uint16_t get_progress_permyriad() { return _get_progress(); } #endif static uint8_t get_progress_percent() { return uint8_t(_get_progress() / (PROGRESS_SCALE)); } + #if LCD_WITH_BLINK + #if ENABLED(SHOW_PROGRESS_PERCENT) + static void drawPercent(); + #endif + #if ENABLED(SHOW_ELAPSED_TIME) + static void drawElapsed(); + #endif + #if ENABLED(SHOW_REMAINING_TIME) + static void drawRemain(); + #endif + #if ENABLED(SHOW_INTERACTION_TIME) + static void drawInter(); + #endif + static void rotate_progress(); + #endif #else static constexpr uint8_t get_progress_percent() { return 0; } #endif @@ -390,7 +410,7 @@ public: static void poweroff(); #endif - #if EITHER(HAS_WIRED_LCD, DWIN_CREALITY_LCD_JYERSUI) + #if LCD_WITH_BLINK static bool get_blink(); #endif diff --git a/Marlin/src/lcd/menu/menu.cpp b/Marlin/src/lcd/menu/menu.cpp index 9dd74988f3..7ae1078f4d 100644 --- a/Marlin/src/lcd/menu/menu.cpp +++ b/Marlin/src/lcd/menu/menu.cpp @@ -175,7 +175,7 @@ void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, co TERN_(HAS_TOUCH_BUTTONS, repeat_delay = BUTTON_DELAY_MENU); - TERN_(LCD_SET_PROGRESS_MANUALLY, progress_reset()); + TERN_(SET_PROGRESS_PERCENT, progress_reset()); #if BOTH(DOUBLECLICK_FOR_Z_BABYSTEPPING, BABYSTEPPING) static millis_t doubleclick_expire_ms = 0; diff --git a/Marlin/src/libs/numtostr.cpp b/Marlin/src/libs/numtostr.cpp index f4d47983d2..594255aea8 100644 --- a/Marlin/src/libs/numtostr.cpp +++ b/Marlin/src/libs/numtostr.cpp @@ -73,10 +73,10 @@ const char* i8tostr3rj(const int8_t x) { } #if HAS_PRINT_PROGRESS_PERMYRIAD - // Convert unsigned 16-bit permyriad to percent with 100 / 23 / 23.4 / 3.45 format + // Convert unsigned 16-bit permyriad to percent with 100 / 23.4 / 3.45 format const char* permyriadtostr4(const uint16_t xx) { if (xx >= 10000) - return "100"; + return " 100"; // space to keep 4-width alignment else if (xx >= 1000) { conv[3] = DIGIMOD(xx, 1000); conv[4] = DIGIMOD(xx, 100); diff --git a/buildroot/tests/SAMD51_grandcentral_m4 b/buildroot/tests/SAMD51_grandcentral_m4 index c8e08c19e6..f96e0b18cd 100755 --- a/buildroot/tests/SAMD51_grandcentral_m4 +++ b/buildroot/tests/SAMD51_grandcentral_m4 @@ -21,7 +21,7 @@ opt_enable ENDSTOP_INTERRUPTS_FEATURE S_CURVE_ACCELERATION BLTOUCH Z_MIN_PROBE_R FILAMENT_RUNOUT_SENSOR G26_MESH_VALIDATION MESH_EDIT_GFX_OVERLAY Z_SAFE_HOMING \ EEPROM_SETTINGS NOZZLE_PARK_FEATURE SDSUPPORT SD_CHECK_AND_RETRY \ REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER Z_STEPPER_AUTO_ALIGN ADAPTIVE_STEP_SMOOTHING \ - STATUS_MESSAGE_SCROLLING LCD_SET_PROGRESS_MANUALLY SHOW_REMAINING_TIME USE_M73_REMAINING_TIME \ + STATUS_MESSAGE_SCROLLING SET_PROGRESS_MANUALLY SHOW_REMAINING_TIME SET_REMAINING_TIME \ LONG_FILENAME_HOST_SUPPORT CUSTOM_FIRMWARE_UPLOAD M20_TIMESTAMP_SUPPORT \ SCROLL_LONG_FILENAMES BABYSTEPPING DOUBLECLICK_FOR_Z_BABYSTEPPING \ MOVE_Z_WHEN_IDLE BABYSTEP_ZPROBE_OFFSET BABYSTEP_ZPROBE_GFX_OVERLAY \ diff --git a/buildroot/tests/STM32F103RE_creality b/buildroot/tests/STM32F103RE_creality index f1478bc2c4..a3c52372ef 100755 --- a/buildroot/tests/STM32F103RE_creality +++ b/buildroot/tests/STM32F103RE_creality @@ -20,7 +20,7 @@ exec_test $1 $2 "Ender 3 v2 with JyersUI" "$3" use_example_configs "Creality/Ender-3 S1/STM32F1" opt_disable DWIN_CREALITY_LCD Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN AUTO_BED_LEVELING_BILINEAR CONFIGURATION_EMBEDDING CANCEL_OBJECTS FWRETRACT -opt_enable DWIN_LCD_PROUI INDIVIDUAL_AXIS_HOMING_SUBMENU LCD_SET_PROGRESS_MANUALLY STATUS_MESSAGE_SCROLLING \ +opt_enable DWIN_LCD_PROUI INDIVIDUAL_AXIS_HOMING_SUBMENU SET_PROGRESS_MANUALLY SET_PROGRESS_PERCENT STATUS_MESSAGE_SCROLLING \ SOUND_MENU_ITEM PRINTCOUNTER NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE FILAMENT_RUNOUT_SENSOR \ BLTOUCH Z_SAFE_HOMING AUTO_BED_LEVELING_UBL MESH_EDIT_MENU \ LIMITED_MAX_FR_EDITING LIMITED_MAX_ACCEL_EDITING LIMITED_JERK_EDITING BAUD_RATE_GCODE diff --git a/buildroot/tests/mega2560 b/buildroot/tests/mega2560 index 9cb50688cd..24f91c5f90 100755 --- a/buildroot/tests/mega2560 +++ b/buildroot/tests/mega2560 @@ -31,7 +31,7 @@ opt_enable AUTO_BED_LEVELING_UBL RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATU SDSUPPORT SDCARD_SORT_ALPHA USB_FLASH_DRIVE_SUPPORT AUTO_REPORT_SD_STATUS SCROLL_LONG_FILENAMES MEDIA_MENU_AT_TOP \ EEPROM_SETTINGS EEPROM_CHITCHAT GCODE_MACROS CUSTOM_MENU_MAIN FREEZE_FEATURE CANCEL_OBJECTS SOUND_MENU_ITEM \ MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE EXTRA_LIN_ADVANCE_K QUICK_HOME \ - LCD_SET_PROGRESS_MANUALLY PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME \ + SET_PROGRESS_MANUALLY SET_PROGRESS_PERCENT PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME \ ENCODER_NOISE_FILTER BABYSTEPPING BABYSTEP_XY NANODLP_Z_SYNC I2C_POSITION_ENCODERS M114_DETAIL exec_test $1 $2 "Azteeg X3 Pro | EXTRUDERS 5 | RRDFGSC | UBL | LIN_ADVANCE ..." "$3" @@ -42,7 +42,7 @@ use_example_configs AnimationExample opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO LCD_LANGUAGE jp_kana DEFAULT_EJERK 10 \ EXTRUDERS 5 TEMP_SENSOR_1 1 TEMP_SENSOR_2 5 TEMP_SENSOR_3 20 TEMP_SENSOR_4 1000 TEMP_SENSOR_BED 1 opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER LIGHTWEIGHT_UI SHOW_CUSTOM_BOOTSCREEN BOOT_MARLIN_LOGO_SMALL \ - LCD_SET_PROGRESS_MANUALLY PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES \ + SET_PROGRESS_MANUALLY SET_PROGRESS_PERCENT PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES \ SDSUPPORT LONG_FILENAME_WRITE_SUPPORT SDCARD_SORT_ALPHA NO_SD_AUTOSTART USB_FLASH_DRIVE_SUPPORT CANCEL_OBJECTS \ Z_PROBE_SLED AUTO_BED_LEVELING_UBL UBL_HILBERT_CURVE RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_VALIDATION ENABLE_LEVELING_FADE_HEIGHT \ EEPROM_SETTINGS EEPROM_CHITCHAT GCODE_MACROS CUSTOM_MENU_MAIN \ @@ -177,52 +177,52 @@ exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Greek" "$3" #opt_enable LCM1602 #exec_test $1 $2 "Stuff" "$3" -# -# Test Laser features with 12864 LCD -# -restore_configs -opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 0 LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 TEMP_SENSOR_1 0 SERIAL_PORT_2 2 \ - DEFAULT_AXIS_STEPS_PER_UNIT '{ 80, 80, 400 }' \ - DEFAULT_MAX_FEEDRATE '{ 300, 300, 5 }' \ - DEFAULT_MAX_ACCELERATION '{ 3000, 3000, 100 }' \ - MANUAL_FEEDRATE '{ 50*60, 50*60, 4*60 }' \ - AXIS_RELATIVE_MODES '{ false, false, false }' -opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT MEATPACK_ON_SERIAL_PORT_1 \ - LASER_FEATURE LASER_SAFETY_TIMEOUT_MS LASER_COOLANT_FLOW_METER AIR_EVACUATION AIR_EVACUATION_PIN AIR_ASSIST AIR_ASSIST_PIN LASER_SYNCHRONOUS_M106_M107 -exec_test $1 $2 "MEGA2560 RAMPS | Laser Options | 12864 | Meatpack | Fan Sync | SERIAL_PORT_2 " "$3" +# # +# # Test Laser features with 12864 LCD +# # +# restore_configs +# opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 0 LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 TEMP_SENSOR_1 0 SERIAL_PORT_2 2 \ +# DEFAULT_AXIS_STEPS_PER_UNIT '{ 80, 80, 400 }' \ +# DEFAULT_MAX_FEEDRATE '{ 300, 300, 5 }' \ +# DEFAULT_MAX_ACCELERATION '{ 3000, 3000, 100 }' \ +# MANUAL_FEEDRATE '{ 50*60, 50*60, 4*60 }' \ +# AXIS_RELATIVE_MODES '{ false, false, false }' +# opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT MEATPACK_ON_SERIAL_PORT_1 \ +# LASER_FEATURE LASER_SAFETY_TIMEOUT_MS LASER_COOLANT_FLOW_METER AIR_EVACUATION AIR_EVACUATION_PIN AIR_ASSIST AIR_ASSIST_PIN LASER_SYNCHRONOUS_M106_M107 +# exec_test $1 $2 "MEGA2560 RAMPS | Laser Options | 12864 | Meatpack | Fan Sync | SERIAL_PORT_2 " "$3" -# -# Test Laser features with 44780 LCD -# -restore_configs -opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 0 LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 TEMP_SENSOR_1 0 \ - DEFAULT_AXIS_STEPS_PER_UNIT '{ 80, 80, 400 }' \ - DEFAULT_MAX_FEEDRATE '{ 300, 300, 5 }' \ - DEFAULT_MAX_ACCELERATION '{ 3000, 3000, 100 }' \ - MANUAL_FEEDRATE '{ 50*60, 50*60, 4*60 }' \ - AXIS_RELATIVE_MODES '{ false, false, false }' -opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT PRINTCOUNTER I2C_AMMETER \ - LASER_FEATURE LASER_SAFETY_TIMEOUT_MS LASER_COOLANT_FLOW_METER AIR_EVACUATION AIR_EVACUATION_PIN AIR_ASSIST AIR_ASSIST_PIN -exec_test $1 $2 "MEGA2560 RAMPS | Laser Feature | Air Evacuation | Air Assist | Cooler | Laser Safety Timeout | Flowmeter | 44780 LCD " "$3" +# # +# # Test Laser features with 44780 LCD +# # +# restore_configs +# opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 0 LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 TEMP_SENSOR_1 0 \ +# DEFAULT_AXIS_STEPS_PER_UNIT '{ 80, 80, 400 }' \ +# DEFAULT_MAX_FEEDRATE '{ 300, 300, 5 }' \ +# DEFAULT_MAX_ACCELERATION '{ 3000, 3000, 100 }' \ +# MANUAL_FEEDRATE '{ 50*60, 50*60, 4*60 }' \ +# AXIS_RELATIVE_MODES '{ false, false, false }' +# opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT PRINTCOUNTER I2C_AMMETER \ +# LASER_FEATURE LASER_SAFETY_TIMEOUT_MS LASER_COOLANT_FLOW_METER AIR_EVACUATION AIR_EVACUATION_PIN AIR_ASSIST AIR_ASSIST_PIN +# exec_test $1 $2 "MEGA2560 RAMPS | Laser Feature | Air Evacuation | Air Assist | Cooler | Laser Safety Timeout | Flowmeter | 44780 LCD " "$3" -# -# Test redundant temperature sensors + MAX TC + Backlight Timeout -# -restore_configs -opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 1 \ - TEMP_SENSOR_0 -2 TEMP_SENSOR_REDUNDANT -2 \ - TEMP_SENSOR_REDUNDANT_SOURCE E1 TEMP_SENSOR_REDUNDANT_TARGET E0 \ - TEMP_0_CS_PIN 11 TEMP_1_CS_PIN 12 \ - LCD_BACKLIGHT_TIMEOUT_MINS 2 -opt_enable MPCTEMP MINIPANEL -opt_disable PIDTEMP -exec_test $1 $2 "MEGA2560 RAMPS | Redundant temperature sensor | 2x MAX6675 | BL Timeout" "$3" +# # +# # Test redundant temperature sensors + MAX TC + Backlight Timeout +# # +# restore_configs +# opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 1 \ +# TEMP_SENSOR_0 -2 TEMP_SENSOR_REDUNDANT -2 \ +# TEMP_SENSOR_REDUNDANT_SOURCE E1 TEMP_SENSOR_REDUNDANT_TARGET E0 \ +# TEMP_0_CS_PIN 11 TEMP_1_CS_PIN 12 \ +# LCD_BACKLIGHT_TIMEOUT_MINS 2 +# opt_enable MPCTEMP MINIPANEL +# opt_disable PIDTEMP +# exec_test $1 $2 "MEGA2560 RAMPS | Redundant temperature sensor | 2x MAX6675 | BL Timeout" "$3" -# -# Polargraph Config -# -use_example_configs Polargraph -exec_test $1 $2 "RUMBA | POLARGRAPH | RRD LCD" "$3" +# # +# # Polargraph Config +# # +# use_example_configs Polargraph +# exec_test $1 $2 "RUMBA | POLARGRAPH | RRD LCD" "$3" # # Language files test with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER @@ -239,8 +239,8 @@ exec_test $1 $2 "RUMBA | POLARGRAPH | RRD LCD" "$3" # # Test a basic DUAL_X_CARRIAGE configuration # -use_example_configs Formbot/T_Rex_3 -exec_test $1 $2 "Formbot/T_Rex_3 example configuration." "$3" +# use_example_configs Formbot/T_Rex_3 +# exec_test $1 $2 "Formbot/T_Rex_3 example configuration." "$3" # # BQ Hephestos 2 @@ -260,5 +260,20 @@ exec_test $1 $2 "Formbot/T_Rex_3 example configuration." "$3" #use_example_configs tvrrug/Round2 #exec_test $1 $2 "Stuff" "$3" +# +# Test progress display rotation +# +restore_configs +opt_set MOTHERBOARD BOARD_RAMPS_14_EFB +opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER \ + SET_PROGRESS_MANUALLY SET_PROGRESS_PERCENT SET_REMAINING_TIME SET_INTERACTION_TIME M73_REPORT \ + SHOW_PROGRESS_PERCENT SHOW_ELAPSED_TIME SHOW_REMAINING_TIME SHOW_INTERACTION_TIME PRINT_PROGRESS_SHOW_DECIMALS +exec_test $1 $2 "MEGA2560 RAMPS | 12864 | progress rotation" "$3" +opt_enable LIGHTWEIGHT_UI +exec_test $1 $2 "MEGA2560 RAMPS | 12864 LIGHTWEIGHT_UI | progress rotation" "$3" +opt_disable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER +opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER +exec_test $1 $2 "MEGA2560 RAMPS | 44780 | progress rotation" "$3" + # clean up restore_configs diff --git a/ini/features.ini b/ini/features.ini index d3d863ccd4..7e4a3f97be 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -201,7 +201,7 @@ AUTO_REPORT_POSITION = src_filter=+ REPETIER_GCODE_M360 = src_filter=+ HAS_GCODE_M876 = src_filter=+ HAS_RESUME_CONTINUE = src_filter=+ -LCD_SET_PROGRESS_MANUALLY = src_filter=+ +SET_PROGRESS_MANUALLY = src_filter=+ HAS_STATUS_MESSAGE = src_filter=+ HAS_LCD_CONTRAST = src_filter=+ HAS_GCODE_M255 = src_filter=+