@@ -67,8 +67,6 @@ MarlinUI ui;
67
67
68
68
constexpr uint8_t epps = ENCODER_PULSES_PER_STEP;
69
69
70
- #define BLOCK_CLICK_AFTER_MOVEMENT_MS 100
71
-
72
70
#if HAS_STATUS_MESSAGE
73
71
#if ENABLED(STATUS_MESSAGE_SCROLLING) && ANY(HAS_WIRED_LCD, DWIN_LCD_PROUI)
74
72
uint8_t MarlinUI::status_scroll_offset; // = 0
@@ -942,7 +940,6 @@ void MarlinUI::init() {
942
940
void MarlinUI::update () {
943
941
944
942
static uint16_t max_display_update_time = 0 ;
945
- static millis_t next_encoder_enable_ms = 0 ;
946
943
const millis_t ms = millis ();
947
944
948
945
#if LED_POWEROFF_TIMEOUT > 0
@@ -993,12 +990,7 @@ void MarlinUI::init() {
993
990
if (!touch_buttons) {
994
991
// Integrated LCD click handling via button_pressed
995
992
if (!external_control && button_pressed ()) {
996
- if (!wait_for_unclick) {
997
- if (ELAPSED (ms, next_encoder_enable_ms))
998
- do_click (); // Handle the click
999
- else
1000
- wait_for_unclick = true ;
1001
- }
993
+ if (!wait_for_unclick) do_click (); // Handle the click
1002
994
}
1003
995
else
1004
996
wait_for_unclick = false ;
@@ -1035,73 +1027,68 @@ void MarlinUI::init() {
1035
1027
uint8_t abs_diff = ABS (encoderDiff);
1036
1028
1037
1029
#if ENCODER_PULSES_PER_STEP > 1
1038
- #if HAS_TOUCH_SLEEP
1039
- static int8_t lastEncoderDiff;
1040
- if (lastEncoderDiff != encoderDiff) {
1041
- wakeup_screen ();
1042
- lastEncoderDiff = encoderDiff;
1043
- }
1044
- #endif
1030
+ // When reversing the encoder direction, a movement step can be missed because
1031
+ // encoderDiff has a non-zero residual value, making the controller unresponsive.
1032
+ // The fix clears the residual value when the encoder is idle.
1033
+ // Also check if past half the threshold to compensate for missed single steps.
1034
+ static int8_t lastEncoderDiff;
1035
+
1036
+ // Timeout? No decoder change since last check. 10 or 20 times per second.
1037
+ if (encoderDiff == lastEncoderDiff && abs_diff <= epps / 2 ) // Same direction & size but not over a half-step?
1038
+ encoderDiff = 0 ; // Clear residual pulses.
1039
+ else if (WITHIN (abs_diff, epps / 2 + 1 , epps - 1 )) { // Past half of threshold?
1040
+ abs_diff = epps; // Treat as a full step size
1041
+ encoderDiff = (encoderDiff < 0 ? -1 : 1 ) * abs_diff; // ...in the spin direction.
1042
+ }
1043
+ TERN_ (HAS_TOUCH_SLEEP, if (lastEncoderDiff != encoderDiff) wakeup_screen ());
1044
+ lastEncoderDiff = encoderDiff;
1045
1045
#endif
1046
1046
1047
1047
const bool encoderPastThreshold = (abs_diff >= epps);
1048
- if (encoderPastThreshold && TERN1 (IS_TFTGLCD_PANEL, !external_control)) {
1048
+ if (encoderPastThreshold || lcd_clicked) {
1049
+ if (encoderPastThreshold && TERN1 (IS_TFTGLCD_PANEL, !external_control)) {
1049
1050
1050
- #if ALL(HAS_MARLINUI_MENU, ENCODER_RATE_MULTIPLIER)
1051
+ #if ALL(HAS_MARLINUI_MENU, ENCODER_RATE_MULTIPLIER)
1051
1052
1052
- int32_t encoderMultiplier = 1 ;
1053
+ int32_t encoderMultiplier = 1 ;
1053
1054
1054
- if (encoderRateMultiplierEnabled) {
1055
- if (lastEncoderMovementMillis) {
1055
+ if (encoderRateMultiplierEnabled) {
1056
1056
const float encoderMovementSteps = float (abs_diff) / epps;
1057
- // Note that the rate is always calculated between two passes through the
1058
- // loop and that the abs of the encoderDiff value is tracked.
1059
- const float encoderStepRate = encoderMovementSteps / float (ms - lastEncoderMovementMillis) * 1000 ;
1060
-
1061
- if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100 ;
1062
- else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10 ;
1063
-
1064
- // Enable to output the encoder steps per second value
1065
- // #define ENCODER_RATE_MULTIPLIER_DEBUG
1066
- #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG)
1067
- SERIAL_ECHO_START ();
1068
- SERIAL_ECHOPGM (" Enc Step Rate: " , encoderStepRate);
1069
- SERIAL_ECHOPGM (" Multiplier: " , encoderMultiplier);
1070
- SERIAL_ECHOPGM (" ENCODER_10X_STEPS_PER_SEC: " , ENCODER_10X_STEPS_PER_SEC);
1071
- SERIAL_ECHOPGM (" ENCODER_100X_STEPS_PER_SEC: " , ENCODER_100X_STEPS_PER_SEC);
1072
- SERIAL_EOL ();
1073
- #endif
1074
- }
1075
1057
1076
- lastEncoderMovementMillis = ms;
1077
- } // encoderRateMultiplierEnabled
1058
+ if (lastEncoderMovementMillis) {
1059
+ // Note that the rate is always calculated between two passes through the
1060
+ // loop and that the abs of the encoderDiff value is tracked.
1061
+ const float encoderStepRate = encoderMovementSteps / float (ms - lastEncoderMovementMillis) * 1000 ;
1078
1062
1079
- #else
1063
+ if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100 ;
1064
+ else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10 ;
1080
1065
1081
- constexpr int32_t encoderMultiplier = 1 ;
1066
+ // Enable to output the encoder steps per second value
1067
+ // #define ENCODER_RATE_MULTIPLIER_DEBUG
1068
+ #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG)
1069
+ SERIAL_ECHO_START ();
1070
+ SERIAL_ECHOPGM (" Enc Step Rate: " , encoderStepRate);
1071
+ SERIAL_ECHOPGM (" Multiplier: " , encoderMultiplier);
1072
+ SERIAL_ECHOPGM (" ENCODER_10X_STEPS_PER_SEC: " , ENCODER_10X_STEPS_PER_SEC);
1073
+ SERIAL_ECHOPGM (" ENCODER_100X_STEPS_PER_SEC: " , ENCODER_100X_STEPS_PER_SEC);
1074
+ SERIAL_EOL ();
1075
+ #endif
1076
+ }
1082
1077
1083
- #endif // ENCODER_RATE_MULTIPLIER
1078
+ lastEncoderMovementMillis = ms;
1079
+ } // encoderRateMultiplierEnabled
1084
1080
1085
- int8_t fullSteps = encoderDiff / epps;
1086
- if (fullSteps != 0 ) {
1081
+ #else
1087
1082
1088
- #if ENABLED(ENCODER_RATE_MULTIPLIER)
1089
- static bool lastFwd;
1090
- const bool fwd = fullSteps > 0 ;
1091
- if (encoderMultiplier != 1 && fwd != lastFwd)
1092
- fullSteps *= -1 ; // Fast move and direction changed? Assume glitch.
1093
- else
1094
- lastFwd = fwd; // Slow move or lastFwd==fwd already. Remember dir.
1095
- #endif
1083
+ constexpr int32_t encoderMultiplier = 1 ;
1084
+
1085
+ #endif // ENCODER_RATE_MULTIPLIER
1086
+
1087
+ if (can_encode ()) encoderPosition += (encoderDiff * encoderMultiplier) / epps;
1096
1088
1097
- next_encoder_enable_ms = ms + BLOCK_CLICK_AFTER_MOVEMENT_MS;
1098
- encoderDiff -= fullSteps * epps;
1099
- if (can_encode () && !lcd_clicked)
1100
- encoderPosition += (fullSteps * encoderMultiplier);
1089
+ encoderDiff = 0 ;
1101
1090
}
1102
- }
1103
1091
1104
- if (encoderPastThreshold || lcd_clicked) {
1105
1092
reset_status_timeout (ms);
1106
1093
1107
1094
#if HAS_BACKLIGHT_TIMEOUT
@@ -1115,7 +1102,7 @@ void MarlinUI::init() {
1115
1102
#if LED_POWEROFF_TIMEOUT > 0
1116
1103
if (!powerManager.psu_on ) leds.reset_timeout (ms);
1117
1104
#endif
1118
- }
1105
+ } // encoder activity
1119
1106
1120
1107
#endif // HAS_ENCODER_ACTION
1121
1108
@@ -1413,10 +1400,9 @@ void MarlinUI::init() {
1413
1400
1414
1401
#if HAS_ENCODER_WHEEL
1415
1402
static uint8_t lastEncoderBits;
1416
- bool ignore = false ;
1417
1403
1418
1404
// Manage encoder rotation
1419
- #define ENCODER_SPIN (_E1, _E2 ) switch (lastEncoderBits) { case _E1: encoderDiff += encoderDirection; break ; case _E2: encoderDiff -= encoderDirection; break ; default : ignore = true ; }
1405
+ #define ENCODER_SPIN (_E1, _E2 ) switch (lastEncoderBits) { case _E1: encoderDiff += encoderDirection; break ; case _E2: encoderDiff -= encoderDirection; }
1420
1406
1421
1407
uint8_t enc = 0 ;
1422
1408
if (buttons & EN_A) enc |= B01;
@@ -1431,7 +1417,7 @@ void MarlinUI::init() {
1431
1417
#if ALL(HAS_MARLINUI_MENU, AUTO_BED_LEVELING_UBL)
1432
1418
external_encoder ();
1433
1419
#endif
1434
- if (!ignore) lastEncoderBits = enc;
1420
+ lastEncoderBits = enc;
1435
1421
}
1436
1422
1437
1423
#endif // HAS_ENCODER_WHEEL
0 commit comments