Browse Source

Fix encoder reverse, partial steps handling (#18694)

Mark Langezaal 3 years ago
parent
commit
d96691f8ad
No account linked to committer's email address
1 changed files with 25 additions and 2 deletions
  1. 25
    2
      Marlin/src/lcd/ultralcd.cpp

+ 25
- 2
Marlin/src/lcd/ultralcd.cpp View File

@@ -896,7 +896,30 @@ void MarlinUI::update() {
896 896
       if (TERN0(REPRAPWORLD_KEYPAD, handle_keypad()))
897 897
         RESET_STATUS_TIMEOUT();
898 898
 
899
-      const float abs_diff = ABS(encoderDiff);
899
+      uint8_t abs_diff = ABS(encoderDiff);
900
+
901
+      #if ENCODER_PULSES_PER_STEP > 1
902
+        // When reversing the encoder direction, a movement step can be missed because
903
+        // encoderDiff has a non-zero residual value, making the controller unresponsive.
904
+        // The fix clears the residual value when the encoder is reversed.
905
+        // Also check if past half the threshold to compensate for missed single steps.
906
+        static int8_t lastEncoderDiff;
907
+        int8_t prevDiff = lastEncoderDiff;
908
+        lastEncoderDiff = encoderDiff;  // Store before updating encoderDiff to save actual steps
909
+
910
+        // When not past threshold, and reversing... or past half the threshold
911
+        if (WITHIN(abs_diff, 1, (ENCODER_PULSES_PER_STEP) - 1)  // Not past threshold
912
+          && (abs_diff > (ENCODER_PULSES_PER_STEP) / 2          // Passed half the threshold? Done! Call it a full step.
913
+            || (ABS(encoderDiff - prevDiff) >= (ENCODER_PULSES_PER_STEP)  // A big change when abs_diff is small implies reverse
914
+                && ABS(prevDiff) < (ENCODER_PULSES_PER_STEP)    // ...especially when starting from a partial or no step.
915
+               )
916
+             )
917
+        ) {
918
+          abs_diff = ENCODER_PULSES_PER_STEP;
919
+          encoderDiff = (encoderDiff < 0 ? -1 : 1) * abs_diff;  // Treat as full step
920
+        }
921
+      #endif
922
+
900 923
       const bool encoderPastThreshold = (abs_diff >= (ENCODER_PULSES_PER_STEP));
901 924
       if (encoderPastThreshold || lcd_clicked) {
902 925
         if (encoderPastThreshold) {
@@ -906,7 +929,7 @@ void MarlinUI::update() {
906 929
             int32_t encoderMultiplier = 1;
907 930
 
908 931
             if (encoderRateMultiplierEnabled) {
909
-              const float encoderMovementSteps = abs_diff / (ENCODER_PULSES_PER_STEP);
932
+              const float encoderMovementSteps = float(abs_diff) / (ENCODER_PULSES_PER_STEP);
910 933
 
911 934
               if (lastEncoderMovementMillis) {
912 935
                 // Note that the rate is always calculated between two passes through the

Loading…
Cancel
Save