diff --git a/Firmware/lcd.cpp b/Firmware/lcd.cpp index 5715ca97d..204ba73e9 100644 --- a/Firmware/lcd.cpp +++ b/Firmware/lcd.cpp @@ -546,14 +546,14 @@ void lcd_print(const char* s) while (*s) lcd_write(*(s++)); } -char lcd_print_pad(const char* s, uint8_t len) +uint8_t lcd_print_pad(const char* s, uint8_t len) { while (len && *s) { lcd_write(*(s++)); --len; } lcd_space(len); - return *s; + return len; } uint8_t lcd_print_pad_P(const char* s, uint8_t len) diff --git a/Firmware/lcd.h b/Firmware/lcd.h index 2a4682739..da509de07 100644 --- a/Firmware/lcd.h +++ b/Firmware/lcd.h @@ -56,7 +56,7 @@ extern void lcd_space(uint8_t n); extern void lcd_printNumber(unsigned long n, uint8_t base); extern void lcd_print(const char*); -extern char lcd_print_pad(const char* s, uint8_t len); +extern uint8_t lcd_print_pad(const char* s, uint8_t len); /// @brief print a string from PROGMEM with left-adjusted padding /// @param s string from PROGMEM. diff --git a/Firmware/mmu2.cpp b/Firmware/mmu2.cpp index 6969bb5c5..37bb72d6a 100644 --- a/Firmware/mmu2.cpp +++ b/Firmware/mmu2.cpp @@ -305,6 +305,8 @@ bool MMU2::VerifyFilamentEnteredPTFE() { } Disable_E0(); + TryLoadUnloadProgressbarEcho(); + TryLoadUnloadProgressbarDeinit(); if (fsensorState) { IncrementLoadFails(); diff --git a/Firmware/mmu2_reporting.cpp b/Firmware/mmu2_reporting.cpp index 09c62f4a8..ea14fdbea 100644 --- a/Firmware/mmu2_reporting.cpp +++ b/Firmware/mmu2_reporting.cpp @@ -1,4 +1,5 @@ #include "mmu2.h" +#include "mmu2_log.h" #include "mmu2_reporting.h" #include "mmu2_error_converter.h" #include "mmu2/error_codes.h" @@ -283,16 +284,29 @@ void ReportProgressHook(CommandInProgress cip, uint16_t ec) { } void TryLoadUnloadProgressbarInit() { - // Clear the status line - lcd_set_cursor(0, 3); - lcd_space(LCD_WIDTH); + lcd_clearstatus(); +} + +void TryLoadUnloadProgressbarDeinit() { + // Delay the next status message just so + // the user can see the results clearly + lcd_reset_status_message_timeout(); +} + +void TryLoadUnloadProgressbarEcho() { + char buf[LCD_WIDTH]; + lcd_getstatus(buf); + for (uint8_t i = 0; i < sizeof(buf); i++) { + // 0xFF is -1 when converting from unsigned to signed char + // If the number is negative, that means filament is present + buf[i] = (buf[i] < 0) ? '1' : '0'; + } + MMU2_ECHO_MSGLN(buf); } void TryLoadUnloadProgressbar(uint8_t col, bool sensorState) { - // Set the cursor position each time in case some other - // part of the firmware changes the cursor position - lcd_putc_at(col, 3, sensorState ? '-' : LCD_STR_SOLID_BLOCK[0]); - lcd_reset_status_message_timeout(); + lcd_insert_char_into_status(col, sensorState ? '-' : LCD_STR_SOLID_BLOCK[0]); + if (!lcd_update_enabled) lcdui_print_status_line(); } void IncrementLoadFails(){ diff --git a/Firmware/mmu2_reporting.h b/Firmware/mmu2_reporting.h index e03b15ddd..071dd545e 100644 --- a/Firmware/mmu2_reporting.h +++ b/Firmware/mmu2_reporting.h @@ -38,6 +38,12 @@ void ReportProgressHook(CommandInProgress cip, uint16_t ec); /// @brief Clear the status line and setup the LCD cursor void TryLoadUnloadProgressbarInit(); +/// @brief Clear the status line and setup the LCD cursor +void TryLoadUnloadProgressbarDeinit(); + +/// @brief Report the results to serial +void TryLoadUnloadProgressbarEcho(); + /// @brief Add one block to the progress bar /// @param col pixel position on the LCD status line, should range from 0 to (LCD_WIDTH - 1) /// @param sensorState if true, filament is not present, else filament is present. This controls which character to render diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index dbcd2edb9..c06196f09 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -78,6 +78,7 @@ static float manual_feedrate[] = MANUAL_FEEDRATE; /* LCD message status */ static LongTimer lcd_status_message_timeout; static uint8_t lcd_status_message_level; +static uint8_t lcd_status_message_idx = 0; static char lcd_status_message[LCD_WIDTH + 1]; /* !Configuration settings */ @@ -542,7 +543,7 @@ void lcdui_print_status_line(void) { { // If printing from SD, show what we are printing const char* longFilenameOLD = (card.longFilename[0] ? card.longFilename : card.filename); - if( lcd_print_pad(&longFilenameOLD[scrollstuff], LCD_WIDTH) ) + if( lcd_print_pad(&longFilenameOLD[scrollstuff], LCD_WIDTH) == 0) { scrollstuff++; } else { @@ -562,7 +563,11 @@ void lcdui_print_status_line(void) { case CustomMsg::M0Wait: // M0/M1 Wait command working even from SD case CustomMsg::FilamentLoading: // If loading filament, print status case CustomMsg::MMUProgress: // MMU Progress Codes - lcd_print_pad(lcd_status_message, LCD_WIDTH); + { + lcd_set_cursor(lcd_status_message_idx, 3); + const uint8_t padding = lcd_print_pad(&lcd_status_message[lcd_status_message_idx], LCD_WIDTH - lcd_status_message_idx); + lcd_status_message_idx = LCD_WIDTH - padding; + } break; case CustomMsg::MeshBedLeveling: // If mesh bed leveling in progress, show the status if (custom_message_state > 10) { @@ -684,6 +689,12 @@ void lcdui_print_status_screen(void) } +static void lcdui_refresh(uint8_t clear = true) +{ + clear ? lcd_refresh() : lcd_refresh_noclear(); + lcd_status_message_idx = 0; // Re-draw message from beginning +} + // Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent void lcd_status_screen() // NOT static due to using inside "Marlin_main" module ("manage_inactivity()") { @@ -727,13 +738,15 @@ void lcd_status_screen() // NOT static due to using ins ReInitLCD++; if (ReInitLCD == 30) { - lcd_refresh(); // to maybe revive the LCD if static electricity killed it. ReInitLCD = 0 ; + lcdui_refresh(); } else { if ((ReInitLCD % 10) == 0) - lcd_refresh_noclear(); //to maybe revive the LCD if static electricity killed it. + { + lcdui_refresh(false); //to maybe revive the LCD if static electricity killed it. + } } lcdui_print_status_screen(); @@ -988,7 +1001,7 @@ void lcd_commands() void lcd_return_to_status() { - lcd_refresh(); // to maybe revive the LCD if static electricity killed it. + lcdui_refresh(); // to maybe revive the LCD if static electricity killed it. menu_goto(lcd_status_screen, 0, true); menu_depth = 0; eFilamentAction = FilamentAction::None; // i.e. non-autoLoad @@ -5759,7 +5772,7 @@ void lcd_sdcard_menu() if (_md->isDir) lcd_print(LCD_STR_FOLDER[0]); - if( lcd_print_pad(&_md->scrollPointer[_md->offset], len) ) + if( lcd_print_pad(&_md->scrollPointer[_md->offset], len) == 0) { _md->lcd_scrollTimer.start(); _md->offset++; @@ -7039,6 +7052,7 @@ static void lcd_updatestatus(const char *message, bool progmem = false) strncpy(lcd_status_message, message, LCD_WIDTH); lcd_status_message[LCD_WIDTH] = 0; + lcd_status_message_idx = 0; // Print message from beginning SERIAL_PROTOCOLLNRPGM(MSG_LCD_STATUS_CHANGED); @@ -7052,6 +7066,23 @@ void lcd_setstatus(const char* message) lcd_updatestatus(message); } +void lcd_insert_char_into_status(uint8_t position, const char message) +{ + if (position > LCD_WIDTH - 1) return; + lcd_status_message[position] = message; + lcd_draw_update = 1; // force redraw +} + +void lcd_clearstatus() +{ + memset(lcd_status_message, 0, sizeof(lcd_status_message)); + lcd_status_message_idx = 0; +} + +void lcd_getstatus(char buf[LCD_WIDTH]) { + strncpy(buf, lcd_status_message, LCD_WIDTH); +} + void lcd_setstatuspgm(const char* message) { if (lcd_message_check(LCD_STATUS_NONE)) @@ -7243,7 +7274,7 @@ void menu_lcd_lcdupdate_func(void) lcd_return_to_status(); lcd_draw_update = 2; } - if (lcd_draw_update == 2) lcd_clear(); + if (lcd_draw_update == 2) lcdui_refresh(); if (lcd_draw_update) lcd_draw_update--; lcd_next_update_millis = _millis() + LCD_UPDATE_INTERVAL; } diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 4c1b92729..c340fef95 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -20,6 +20,13 @@ void ultralcd_init(); #define LCD_STATUS_DELAYED_TIMEOUT 4000 // Set the current status message (equivalent to LCD_STATUS_NONE) +void lcdui_print_status_line(void); +void lcd_clearstatus(); + +/// @brief Copy the contents of lcd_status_message +/// @param buf destination buffer +void lcd_getstatus(char buf[LCD_WIDTH]); +void lcd_insert_char_into_status(uint8_t position, const char message); void lcd_setstatus(const char* message); void lcd_setstatuspgm(const char* message); void lcd_setstatus_serial(const char* message);