diff --git a/Firmware/mmu2.cpp b/Firmware/mmu2.cpp index be8843a1a..7b6304d03 100644 --- a/Firmware/mmu2.cpp +++ b/Firmware/mmu2.cpp @@ -256,23 +256,14 @@ bool MMU2::RetryIfPossible(ErrorCode ec) { bool MMU2::VerifyFilamentEnteredPTFE() { planner_synchronize(); - if (WhereIsFilament() == FilamentState::NOT_PRESENT) + if (WhereIsFilament() != FilamentState::AT_FSENSOR) return false; - uint8_t fsensorState = 0; - uint8_t fsensorStateLCD = 0; - uint8_t lcd_cursor_col = 0; // MMU has finished its load, push the filament further by some defined constant length // If the filament sensor reads 0 at any moment, then report FAILURE - const float delta_mm = MMU2_CHECK_FILAMENT_PRESENCE_EXTRUSION_LENGTH - logic.ExtraLoadDistance(); - - // The total length is twice delta_mm. Divide that length by number of pixels - // available to get length per pixel. - // Note: Below is the reciprocal of (2 * delta_mm) / LCD_WIDTH [mm/pixel] - const float pixel_per_mm = 0.5f * float(LCD_WIDTH) / (delta_mm); - - TryLoadUnloadProgressbarInit(); + const float tryload_length = MMU2_CHECK_FILAMENT_PRESENCE_EXTRUSION_LENGTH - logic.ExtraLoadDistance(); + TryLoadUnloadReporter tlur(tryload_length); /* The position is a triangle wave // current position is not zero, it is an offset @@ -284,7 +275,7 @@ bool MMU2::VerifyFilamentEnteredPTFE() { // in the slope's sign or check the last machine position. // y(x) // ▲ - // │ ^◄────────── delta_mm + current_position + // │ ^◄────────── tryload_length + current_position // machine │ / \ // position │ / \◄────────── stepper_position_mm + current_position // (mm) │ / \ @@ -295,42 +286,23 @@ bool MMU2::VerifyFilamentEnteredPTFE() { // pixel # */ + bool filament_inserted = true; // expect success // Pixel index will go from 0 to 10, then back from 10 to 0 // The change in this number is used to indicate a new pixel // should be drawn on the display - uint8_t dpixel1 = 0; - uint8_t dpixel0 = 0; for (uint8_t move = 0; move < 2; move++) { - extruder_move(move == 0 ? delta_mm : -delta_mm, MMU2_VERIFY_LOAD_TO_NOZZLE_FEED_RATE); + extruder_move(move == 0 ? tryload_length : -tryload_length, MMU2_VERIFY_LOAD_TO_NOZZLE_FEED_RATE); while (planner_any_moves()) { - // Wait for move to finish and monitor the fsensor the entire time - // A single 0 reading will set the bit. - fsensorStateLCD |= (WhereIsFilament() == FilamentState::NOT_PRESENT); - fsensorState |= fsensorStateLCD; // No need to do the above comparison twice, just bitwise OR - - // Always round up, you can only have 'whole' pixels. (floor is also an option) - dpixel1 = ceil((stepper_get_machine_position_E_mm() - planner_get_current_position_E()) * pixel_per_mm); - if (dpixel1 - dpixel0) { - dpixel0 = dpixel1; - if (lcd_cursor_col > (LCD_WIDTH - 1)) lcd_cursor_col = LCD_WIDTH - 1; - TryLoadUnloadProgressbar(lcd_cursor_col++, fsensorStateLCD); - fsensorStateLCD = 0; // Clear temporary bit - } + filament_inserted = filament_inserted && (WhereIsFilament() == FilamentState::AT_FSENSOR); + tlur.Progress(filament_inserted); safe_delay_keep_alive(0); } } - - Disable_E0(); - TryLoadUnloadProgressbarEcho(); - TryLoadUnloadProgressbarDeinit(); - - if (fsensorState) { + if (!filament_inserted) { IncrementLoadFails(); - return false; - } else { - // else, happy printing! :) - return true; } + + return filament_inserted; } bool MMU2::ToolChangeCommonOnce(uint8_t slot) { diff --git a/Firmware/mmu2_reporting.cpp b/Firmware/mmu2_reporting.cpp index 844fe5fe5..ac037aeb9 100644 --- a/Firmware/mmu2_reporting.cpp +++ b/Firmware/mmu2_reporting.cpp @@ -295,30 +295,32 @@ void ReportProgressHook(CommandInProgress cip, ProgressCode ec) { } } -void TryLoadUnloadProgressbarInit() { - lcd_clearstatus(); +TryLoadUnloadReporter::TryLoadUnloadReporter(float delta_mm) +: dpixel0(0) +, dpixel1(0) +, lcd_cursor_col(0) +, pixel_per_mm(0.5F * float(LCD_WIDTH) / (delta_mm)) +{ + // Clear the status line + lcd_set_cursor(0, 3); + lcd_space(LCD_WIDTH); } -void TryLoadUnloadProgressbarDeinit() { - // Delay the next status message just so - // the user can see the results clearly +void TryLoadUnloadReporter::Render(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(); } -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'; +void TryLoadUnloadReporter::Progress(bool sensorState){ + // Always round up, you can only have 'whole' pixels. (floor is also an option) + dpixel1 = ceil((stepper_get_machine_position_E_mm() - planner_get_current_position_E()) * pixel_per_mm); + if (dpixel1 - dpixel0) { + dpixel0 = dpixel1; + if (lcd_cursor_col > (LCD_WIDTH - 1)) lcd_cursor_col = LCD_WIDTH - 1; + Render(lcd_cursor_col++, sensorState); } - MMU2_ECHO_MSGLN(buf); -} - -void TryLoadUnloadProgressbar(uint8_t col, bool sensorState) { - 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 0549db2d6..5705efc47 100644 --- a/Firmware/mmu2_reporting.h +++ b/Firmware/mmu2_reporting.h @@ -47,19 +47,24 @@ void ReportErrorHook(CommandInProgress cip, ErrorCode ec, uint8_t es); /// Called when the MMU sends operation progress update void ReportProgressHook(CommandInProgress cip, ProgressCode ec); -/// @brief Clear the status line and setup the LCD cursor -void TryLoadUnloadProgressbarInit(); +struct TryLoadUnloadReporter { + TryLoadUnloadReporter(float delta_mm); + void Progress(bool sensorState); -/// @brief Clear the status line and setup the LCD cursor -void TryLoadUnloadProgressbarDeinit(); +private: + /// @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 + void Render(uint8_t col, bool sensorState); -/// @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 -void TryLoadUnloadProgressbar(uint8_t col, bool sensorState); + uint8_t dpixel1; + uint8_t dpixel0; + // The total length is twice delta_mm. Divide that length by number of pixels + // available to get length per pixel. + // Note: Below is the reciprocal of (2 * delta_mm) / LCD_WIDTH [mm/pixel] + float pixel_per_mm; + uint8_t lcd_cursor_col; +}; /// Remders the sensor status line. Also used by the "resume temperature" screen. void ReportErrorHookDynamicRender();