Hi all! Having a problem with using rotary encoder. I'm updating a counter with a rotary encoder and displaying the value on a display. I'm having trouble figuring out how to read the encoder's value without being influenced by the execution time of the display (at least I believe this is what's happening).
When I turn the encoder slowly, it works great but when I go too fast, it skips some steps, like if the contact time was during the display update execution and the Arduino doesn't get it. I'm still a bit new to this so I might be in the wrong direction here ![]()
Here's the sketch :
#include <U8g2lib.h>;
U8G2_SH1107_PIMORONI_128X128_F_HW_I2C u8g2(U8G2_R0, 21, 20);
bool a_value;
bool b_value;
bool a_last_value;
volatile long counter_value = 0;
void update_rotary_encoder() {
a_value = digitalRead(2);
b_value = digitalRead(3);
// if the A value has changed and == 1
if (a_value != a_last_value && a_value) {
// check if going forward or backwards
if (a_value != b_value) {
counter_value++;
} else {
counter_value--;
}
}
a_last_value = a_value;
}
void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
pinMode(3, INPUT);
// setup the display
u8g2.begin();
u8g2.setFont(u8g2_font_6x10_mf);
// display the initial counter value
u8g2.clearBuffer();
u8g2.setCursor(4, 124);
u8g2.print(counter_value);
u8g2.sendBuffer();
// set the initial A value
a_last_value = digitalRead(2);
// set interrupts for the 2 encoder values
attachInterrupt(digitalPinToInterrupt(2), update_rotary_encoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(3), update_rotary_encoder, CHANGE);
}
void loop() {
// display the counter value
u8g2.clearBuffer();
u8g2.setCursor(4, 124);
u8g2.print(counter_value);
u8g2.updateDisplayArea(0, 14, 4, 2);
}
I've tried not using the interrupts and manually checking every loop for a value change but it doesn't get better.
EDIT :
I removed the second condition in the IF statement to have only
if (a_value != a_last_value) { ... }
and now it works perfectly except that it counts in doubles. I figure this is because it's now counting the start of stepping AND the end of stepping, so basically anytime the A value changes.
Any clue why the storing and comparing of the last A value would change something in the execution time enough to skip some values..?