Fix encoder reverse, partial steps handling (#18694)

This commit is contained in:
Mark Langezaal 2020-07-20 00:20:35 +02:00 committed by GitHub
parent cfc36684aa
commit d96691f8ad
Signed by: GitHub
GPG key ID: 4AEE18F83AFDEB23

View file

@ -896,7 +896,30 @@ void MarlinUI::update() {
if (TERN0(REPRAPWORLD_KEYPAD, handle_keypad())) if (TERN0(REPRAPWORLD_KEYPAD, handle_keypad()))
RESET_STATUS_TIMEOUT(); RESET_STATUS_TIMEOUT();
const float abs_diff = ABS(encoderDiff); uint8_t abs_diff = ABS(encoderDiff);
#if ENCODER_PULSES_PER_STEP > 1
// 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 reversed.
// Also check if past half the threshold to compensate for missed single steps.
static int8_t lastEncoderDiff;
int8_t prevDiff = lastEncoderDiff;
lastEncoderDiff = encoderDiff; // Store before updating encoderDiff to save actual steps
// When not past threshold, and reversing... or past half the threshold
if (WITHIN(abs_diff, 1, (ENCODER_PULSES_PER_STEP) - 1) // Not past threshold
&& (abs_diff > (ENCODER_PULSES_PER_STEP) / 2 // Passed half the threshold? Done! Call it a full step.
|| (ABS(encoderDiff - prevDiff) >= (ENCODER_PULSES_PER_STEP) // A big change when abs_diff is small implies reverse
&& ABS(prevDiff) < (ENCODER_PULSES_PER_STEP) // ...especially when starting from a partial or no step.
)
)
) {
abs_diff = ENCODER_PULSES_PER_STEP;
encoderDiff = (encoderDiff < 0 ? -1 : 1) * abs_diff; // Treat as full step
}
#endif
const bool encoderPastThreshold = (abs_diff >= (ENCODER_PULSES_PER_STEP)); const bool encoderPastThreshold = (abs_diff >= (ENCODER_PULSES_PER_STEP));
if (encoderPastThreshold || lcd_clicked) { if (encoderPastThreshold || lcd_clicked) {
if (encoderPastThreshold) { if (encoderPastThreshold) {
@ -906,7 +929,7 @@ void MarlinUI::update() {
int32_t encoderMultiplier = 1; int32_t encoderMultiplier = 1;
if (encoderRateMultiplierEnabled) { if (encoderRateMultiplierEnabled) {
const float encoderMovementSteps = abs_diff / (ENCODER_PULSES_PER_STEP); const float encoderMovementSteps = float(abs_diff) / (ENCODER_PULSES_PER_STEP);
if (lastEncoderMovementMillis) { if (lastEncoderMovementMillis) {
// Note that the rate is always calculated between two passes through the // Note that the rate is always calculated between two passes through the