diff --git a/Marlin/Version.h b/Marlin/Version.h index 2ca028ebc562..3c0cc959209c 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-01-10" +//#define STRING_DISTRIBUTION_DATE "2024-01-11" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/gcode/config/M92.cpp b/Marlin/src/gcode/config/M92.cpp index 347de3bdea2d..2f33be63a1dc 100644 --- a/Marlin/src/gcode/config/M92.cpp +++ b/Marlin/src/gcode/config/M92.cpp @@ -98,6 +98,7 @@ void GcodeSuite::M92() { void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/) { report_heading_etc(forReplay, F(STR_STEPS_PER_UNIT)); #if NUM_AXES + #define PRINT_EOL SERIAL_ECHOPGM_P(LIST_N(DOUBLE(NUM_AXES), PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]), SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]), @@ -112,12 +113,11 @@ void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/ #endif #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS) + #define PRINT_EOL SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS])); #endif - #if NUM_AXES || (HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)) - SERIAL_EOL(); - #endif + if (ENABLED(PRINT_EOL)) SERIAL_EOL(); #if ENABLED(DISTINCT_E_FACTORS) for (uint8_t i = 0; i < E_STEPPERS; ++i) { diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index f134f53e5f6f..1bf88818d2de 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-01-10" + #define STRING_DISTRIBUTION_DATE "2024-01-11" #endif /** diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index 73094761822d..dfb2a8d47c06 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -67,8 +67,6 @@ MarlinUI ui; constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; -#define BLOCK_CLICK_AFTER_MOVEMENT_MS 100 - #if HAS_STATUS_MESSAGE #if ENABLED(STATUS_MESSAGE_SCROLLING) && ANY(HAS_WIRED_LCD, DWIN_LCD_PROUI) uint8_t MarlinUI::status_scroll_offset; // = 0 @@ -942,7 +940,6 @@ void MarlinUI::init() { void MarlinUI::update() { static uint16_t max_display_update_time = 0; - static millis_t next_encoder_enable_ms = 0; const millis_t ms = millis(); #if LED_POWEROFF_TIMEOUT > 0 @@ -993,12 +990,7 @@ void MarlinUI::init() { if (!touch_buttons) { // Integrated LCD click handling via button_pressed if (!external_control && button_pressed()) { - if (!wait_for_unclick) { - if (ELAPSED(ms, next_encoder_enable_ms)) - do_click(); // Handle the click - else - wait_for_unclick = true; - } + if (!wait_for_unclick) do_click(); // Handle the click } else wait_for_unclick = false; @@ -1035,73 +1027,68 @@ void MarlinUI::init() { uint8_t abs_diff = ABS(encoderDiff); #if ENCODER_PULSES_PER_STEP > 1 - #if HAS_TOUCH_SLEEP - static int8_t lastEncoderDiff; - if (lastEncoderDiff != encoderDiff) { - wakeup_screen(); - lastEncoderDiff = encoderDiff; - } - #endif + // When reversing the encoder direction, a movement step can be missed because + // encoderDiff has a non-zero residual value, making the controller unresponsive. + // The fix clears the residual value when the encoder is idle. + // Also check if past half the threshold to compensate for missed single steps. + static int8_t lastEncoderDiff; + + // Timeout? No decoder change since last check. 10 or 20 times per second. + if (encoderDiff == lastEncoderDiff && abs_diff <= epps / 2) // Same direction & size but not over a half-step? + encoderDiff = 0; // Clear residual pulses. + else if (WITHIN(abs_diff, epps / 2 + 1, epps - 1)) { // Past half of threshold? + abs_diff = epps; // Treat as a full step size + encoderDiff = (encoderDiff < 0 ? -1 : 1) * abs_diff; // ...in the spin direction. + } + TERN_(HAS_TOUCH_SLEEP, if (lastEncoderDiff != encoderDiff) wakeup_screen()); + lastEncoderDiff = encoderDiff; #endif const bool encoderPastThreshold = (abs_diff >= epps); - if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) { + if (encoderPastThreshold || lcd_clicked) { + if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) { - #if ALL(HAS_MARLINUI_MENU, ENCODER_RATE_MULTIPLIER) + #if ALL(HAS_MARLINUI_MENU, ENCODER_RATE_MULTIPLIER) - int32_t encoderMultiplier = 1; + int32_t encoderMultiplier = 1; - if (encoderRateMultiplierEnabled) { - if (lastEncoderMovementMillis) { + if (encoderRateMultiplierEnabled) { const float encoderMovementSteps = float(abs_diff) / epps; - // Note that the rate is always calculated between two passes through the - // loop and that the abs of the encoderDiff value is tracked. - const float encoderStepRate = encoderMovementSteps / float(ms - lastEncoderMovementMillis) * 1000; - - if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100; - else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10; - - // Enable to output the encoder steps per second value - //#define ENCODER_RATE_MULTIPLIER_DEBUG - #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG) - SERIAL_ECHO_START(); - SERIAL_ECHOPGM("Enc Step Rate: ", encoderStepRate); - SERIAL_ECHOPGM(" Multiplier: ", encoderMultiplier); - SERIAL_ECHOPGM(" ENCODER_10X_STEPS_PER_SEC: ", ENCODER_10X_STEPS_PER_SEC); - SERIAL_ECHOPGM(" ENCODER_100X_STEPS_PER_SEC: ", ENCODER_100X_STEPS_PER_SEC); - SERIAL_EOL(); - #endif - } - lastEncoderMovementMillis = ms; - } // encoderRateMultiplierEnabled + if (lastEncoderMovementMillis) { + // Note that the rate is always calculated between two passes through the + // loop and that the abs of the encoderDiff value is tracked. + const float encoderStepRate = encoderMovementSteps / float(ms - lastEncoderMovementMillis) * 1000; - #else + if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100; + else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10; - constexpr int32_t encoderMultiplier = 1; + // Enable to output the encoder steps per second value + //#define ENCODER_RATE_MULTIPLIER_DEBUG + #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG) + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("Enc Step Rate: ", encoderStepRate); + SERIAL_ECHOPGM(" Multiplier: ", encoderMultiplier); + SERIAL_ECHOPGM(" ENCODER_10X_STEPS_PER_SEC: ", ENCODER_10X_STEPS_PER_SEC); + SERIAL_ECHOPGM(" ENCODER_100X_STEPS_PER_SEC: ", ENCODER_100X_STEPS_PER_SEC); + SERIAL_EOL(); + #endif + } - #endif // ENCODER_RATE_MULTIPLIER + lastEncoderMovementMillis = ms; + } // encoderRateMultiplierEnabled - int8_t fullSteps = encoderDiff / epps; - if (fullSteps != 0) { + #else - #if ENABLED(ENCODER_RATE_MULTIPLIER) - static bool lastFwd; - const bool fwd = fullSteps > 0; - if (encoderMultiplier != 1 && fwd != lastFwd) - fullSteps *= -1; // Fast move and direction changed? Assume glitch. - else - lastFwd = fwd; // Slow move or lastFwd==fwd already. Remember dir. - #endif + constexpr int32_t encoderMultiplier = 1; + + #endif // ENCODER_RATE_MULTIPLIER + + if (can_encode()) encoderPosition += (encoderDiff * encoderMultiplier) / epps; - next_encoder_enable_ms = ms + BLOCK_CLICK_AFTER_MOVEMENT_MS; - encoderDiff -= fullSteps * epps; - if (can_encode() && !lcd_clicked) - encoderPosition += (fullSteps * encoderMultiplier); + encoderDiff = 0; } - } - if (encoderPastThreshold || lcd_clicked) { reset_status_timeout(ms); #if HAS_BACKLIGHT_TIMEOUT @@ -1115,7 +1102,7 @@ void MarlinUI::init() { #if LED_POWEROFF_TIMEOUT > 0 if (!powerManager.psu_on) leds.reset_timeout(ms); #endif - } + } // encoder activity #endif // HAS_ENCODER_ACTION @@ -1413,10 +1400,9 @@ void MarlinUI::init() { #if HAS_ENCODER_WHEEL static uint8_t lastEncoderBits; - bool ignore = false; // Manage encoder rotation - #define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: encoderDiff += encoderDirection; break; case _E2: encoderDiff -= encoderDirection; break; default: ignore = true; } + #define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: encoderDiff += encoderDirection; break; case _E2: encoderDiff -= encoderDirection; } uint8_t enc = 0; if (buttons & EN_A) enc |= B01; @@ -1431,7 +1417,7 @@ void MarlinUI::init() { #if ALL(HAS_MARLINUI_MENU, AUTO_BED_LEVELING_UBL) external_encoder(); #endif - if (!ignore) lastEncoderBits = enc; + lastEncoderBits = enc; } #endif // HAS_ENCODER_WHEEL diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index c57eb00bb4cf..833923f7b3eb 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -3743,9 +3743,7 @@ void MarlinSettings::reset() { // // M92 Steps per Unit // - #if ENABLED(EDITABLE_STEPS_PER_UNIT) - gcode.M92_report(forReplay); - #endif + TERN_(EDITABLE_STEPS_PER_UNIT, gcode.M92_report(forReplay)); // // M203 Maximum feedrates (units/s)