Encoder library bouncing

Status
Not open for further replies.

eduardo

Active member
Hi.
I have spent several hours with encoder problems using teensy 2.0.
The encoder is used for user interface input and has a very small stepsize (ALPS). Unfortunately I have to adapt my SW to a given HW and the pins are 9 & 10, so no IRQ can be used. Aditionally the loop takes quite some time for other tasks.
What I observe is that rotating fast with two fingers I can make the encoder lib count crazy stuff. Sometimes even in the opposite direction.
Turning slowly helps.
I know that there is basically no easy solution for my problem having a fixed pinning.

Some small changes in the encoder lib make it notably more stable if you need only one count for each full gray code stepping (4 states) which is the typical case for user IFs.
The rough idea is:

  • increment/decrement counting only when both switches are closed.

  • when only one switch is opened suppress saving the state.
Of course this reduces countings from 4 per step to one and is probably no good idea for people using fast IRQ driven encoders with motors and so on.
See code snippet:
Code:
#ifndef USE_OLD_ENCODER_WITHOUT_DEBOUNCING
        if (p1val) state |= 4;
        if (p2val) state |= 8;
        switch (state)
        {
        case 1:
            arg->position++;
            arg->state = (state >> 2);
            return;
        case 2:
            arg->position--;
            arg->state = (state >> 2);
            return;
        case 4:
        case 8:
            // no state update here!
            return;
        default:
            arg->state = (state >> 2);
            return;
        }
#else
        if (p1val) state |= 4;
        if (p2val) state |= 8;
        arg->state = (state >> 2);
        switch (state)
        {
        case 1: case 7: case 8: case 14:
            arg->position++;
            return;
        case 2: case 4: case 11: case 13:
            arg->position--;
            return;
        case 3: case 12:
            arg->position += 2;
            return;
        case 6: case 9:
            arg->position -= 2;
            return;
        }
#endif

Some time ago I have written a state machine & IRQ driven encoder lib for EFM32. I found out f.e. that correct coding gives perfect inherent debouncing if you have two IRQs. There is a nice commented lib that explains that on http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
It does not support IRQ however.
 
Last edited:
Forgot to mention that the line
Code:
#if defined(__AVR__)
above the mentioned code snippet must be deactivated otherwise the block is not active on the teensy 2.0
 
Status
Not open for further replies.
Back
Top