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:
See code snippet:
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.
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.
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: