I'm using an Arduino Uno and two (3-pin) rotary encoders for a project. Since the loop takes a bit long and accuracy is important, I'd like to use interrupts to read the values from the rotary encoders. Also, pins 2 and 3 are occupied so I can't use hardware interrupts.
I'm using the Rotary library (github link) for the rotary encoders and the EnableInterrupt library (github link) for external interrupts. The Rotary library includes an interrupt example, but I couldn't manage to modify it to work with pin change interrupts. This is my current state (test code):
#include <EnableInterrupt.h>
#include <Rotary.h>
Rotary r = Rotary(2, 3);
void setup() {
Serial.begin(9600);
/* Original interrupt setup:
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
*/
enableInterrupt(2, interruptFunction, CHANGE);
enableInterrupt(3, interruptFunction, CHANGE);
}
void loop() {
}
void interruptFunction() {
Serial.println("Int. called");
unsigned char result = r.process();
if (result == DIR_NONE) {
// do nothing
}
else if (result == DIR_CW) {
Serial.println("ClockWise");
}
else if (result == DIR_CCW) {
Serial.println("CounterClockWise");
}
}
Everytime I turn the encoder for one step, the interruptFunction gets called a bunch of times (about 2~4) but the r.process() call never returns a value.
My current guess is that this has something to do with the rotary encoder outputting gray code, but I'm not quite sure how my approach differs from the Rotary interrupt example using hardware interrupts.
Hope you can help!
process()
of the Rotary Library is not a blocking function and only read the state of the 2 pins and compute an output. How you can say "but the r.process() call never returns a value." ?result
and do the print inside loop. In the ISR change a global variable to signal that you have a new value; reset it in theloop
after you do your thing.