Skip to content

#3875 fix for rotary reverse direction dead spot #3895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

nmorse
Copy link

@nmorse nmorse commented Dec 30, 2020

It is possible that the quarter counter can get out of sync with the quadrature pins. By checking the new_state, instead of just the quarter counter, it stays in sync with the rotary encoding.

During testing I was able to recreate the bug and saw that the quarter count would sometimes count (from a settled click position to next encoder position) 2, 3, 4, 1 and back to 2. In this mode it does a position increment mid way through the quadrature cycle and it works fine if it is always increasing or always decreasing. When the encoder reverses it does not pass 4, instead it counts down 2, 1, 0, -1, -2 (which will not decrement the position).

This PR changes the conditions for a position increment or decrement, to only fire when the encoder is at the settled state.

It is possible that the `quarter` counter can get out of sync with the quadrature pins. By checking the new_state, instead of just the quarter counter, it stays in sync with the rotary encoding. adafruit#3875
@dhalbert
Copy link
Collaborator

Thank you for working on this. Happy to review and test when you're done.

@nmorse nmorse marked this pull request as ready for review December 30, 2020 02:34
@nmorse
Copy link
Author

nmorse commented Dec 30, 2020

all done except that one test failed, humph !?

@dhalbert
Copy link
Collaborator

all done except that one test failed, humph !?

That was a network problem at GitHub; we can ignore that.

@@ -51,10 +51,10 @@ static void _intr_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {

// logic from the atmel-samd port: provides some damping and scales movement
// down by 4:1.
if (self->quarter >= 4) {
if (self->quarter > 0 && new_state == 2) {
Copy link
Author

@nmorse nmorse Dec 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh a finer point might be to refactor this to be ever so slightly more efficient:

  1. switch the order of the conditional (new_state == 2 && self->quarter > 0) because the quarter will be non-zero more often than the state is 2
  2. I guess to go even further it could be refactored with an outer if clause and an inner case, perhaps like this:
if (new_state == 2 && self->quarter != 0) {
    if (self->quarter > 0) { // increment
        ...
    } else { // decrement 
        ...
    }
}

What do you think @dhalbert or anyone else?

@dhalbert
Copy link
Collaborator

Take a look also at https://github.com/adafruit/circuitpython/blob/48de52c8ab62fae93e1382cb774802828cf92edd/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c, which implements the same thing (the nrf version is a rewrite; I wrote the atmel-samd version and it was reworked for nrf). I tested the atmel-samd version and it may suffer from the same issue. I have a rotary encoder volume control that uses the atmel-samd version .Also see whether you think one version is clearer than the other.

@nmorse
Copy link
Author

nmorse commented Dec 30, 2020

nice, I am looking and learning vocab (like detent) and will keep looking at them both to compare, fun.

@tannewt tannewt requested a review from dhalbert December 30, 2020 19:27
@nmorse
Copy link
Author

nmorse commented Dec 31, 2020

closing this PR for now. will be taking another tact on this fix to handle inverted pins etc.

@nmorse nmorse closed this Dec 31, 2020
@nmorse nmorse deleted the patch-1 branch January 16, 2021 15:28
@dhalbert
Copy link
Collaborator

I am going to look at this whole issue again, reviewing the current implementation, and I hope come up with a reference implementation that can be ported easily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants