Hi all,
I spent a lot of time trying to read an EC11 rotary encoder, all code I found did not satisfy my idea of a truly reactive device, so I finally wrote my own code. Of course it uses 2 pins but only one pin with attached interrupts, the second one doesn't need interrupts; I found that useful, as they are not plethoric (with Uno and Nano33IoT I used). The code is compact and reactive enough for me, without reading errors or missing increment. Probably perfectible, comments are welcome.
Hope to be useful
/* Arduino Rotary Encoder Tester
* -----------------------------
* by O.Seston
*/
#define encoderPinA 3
#define encoderPinB 4
volatile int count;
void setup() {
pinMode (encoderPinA, INPUT);
pinMode (encoderPinB, INPUT);
attachInterrupt(digitalPinToInterrupt(encoderPinA), pulseFromA, CHANGE);
Serial.begin (9600);
}
void loop() {
static int lastCount, lastDelta;
if (count != lastCount){
if ((count - lastCount) * lastDelta < 1)
Serial.println("**********");
lastDelta = count - lastCount;
lastCount = count;
Serial.print("New count: ");
Serial.println(lastCount);
}
}
void pulseFromA(){
// It seems that we get better results with a little delay before reading pins,
// probably because of the stabilization delay of the signal.
// Also 4.7K pull-down resistors give better results than 10K and not better than 1K.
delayMicroseconds(50);
// We combine outputA and outputB of the encoder state to get a number between 0 and 3
// This number is used later to recognize valid sequences:
// - 2 (A high and B low) then 1 (A low and B high) --> increment (clockwise)
// - 3 (A high and B high) then 0 (A low and B low) --> decrement (anticlockwise)
byte state = ((digitalRead(encoderPinA) << 1) + digitalRead(encoderPinB));
// The starting sequence signals are saved in 2 bytes, because there can be several
// different consecutive start (this is noise of course),
// but at the moment we don't know which is the right one (we'll know that when
// we get the right closing state).
static byte start[2];
if (state >= 2) { // Save a starting sequence (2 or 3)
start[state - 2] = 1;
} else if (start[0] && state == 1) { // 2 (A high and B low) then 1 (A low and B high)
count++;
start[0] = start[1] = 0;
} else if (start[1] && !state) { // 3 (A high and B high) then 0 (A low and B low)
count--;
start[0] = start[1] = 0;
}
}