thanks
Searching for “encoder” gives you 280 matches..
viewtopic.php?f=18&t=15&p=21
enum { PinA=PB4, PinB=PB5, IPINMODE=INPUT_PULLUP };
static byte abOld; // Initialize state
volatile int count; // current rotary count
int old_count; // old rotary count
void setup() {
pinMode(PinA, IPINMODE);
pinMode(PinB, IPINMODE);
attachInterrupt(PinA, pinChangeISR, CHANGE); // Set up pin-change interrupts
attachInterrupt(PinB, pinChangeISR, CHANGE);
abOld = count = old_count = 0;
Serial.begin(115200);
Serial.println("Starting Rotary Encoder Test");
}
// On interrupt, read input pins, compute new state, and adjust count
void pinChangeISR() {
enum { upMask = 0x66, downMask = 0x99 };
byte abNew = (digitalRead(PinA) << 1) | digitalRead(PinB);
byte criterion = abNew^abOld;
if (criterion==1 || criterion==2) {
if (upMask & (1 << (2*abOld + abNew/2)))
count++;
else count--; // upMask = ~downMask
}
abOld = abNew; // Save new state
}
void loop() {
if (old_count != count) {
Serial.print(millis());
Serial.print(" ");
Serial.println(count);
old_count = count;
}
}
You can find more illustrations here http://olliesworkshops.blogspot.com/201 … witch.html
How did you measure that?
We use much faster signalling (ie SPI, I2C) with similar cabling, no crosstalk issues mentioned in past..
You can measure it with an oscilloscope or a logic analyzer. Please take a look of the logi analyzer screenshots on my blog post where there observations are demonstrated.
[Ollie – Wed May 30, 2018 4:37 pm] –
The interrupt method doesn’t work with the mechanical encoders due to noise and cross-talk. An RC filter could be used to address that, but it can be difficult to find a balance between filtering and missing high speed real pulses. My own conclusion is that only a software filter with polling works. In a F103C8, my application is polling at 10 kHZ speed without causing any noticeable CPU load.You can find more illustrations here http://olliesworkshops.blogspot.com/201 … witch.html
I have never had a skipped reading with that code and a KY-040, I did put a couple of low value tantalum capacitors as insurance.

http://www.bourns.com/docs/product-data … f8c470f5_1
Here is an example how the polling and decision on the change was made (ENA and ENB are the inputs):
encstat = rl (encstat); // shift encstat two bits left to get previous...
encstat = rl (encstat); // ...encoder sample in bits 3..2
encstat &= 0b00001100; // strip garbage other than bits 3..2
//
encstat_tmp = 0b00000000;
encstat_tmp.0 = ENA;
encstat_tmp.1 = ENB;
//
encstat |= encstat_tmp & 0b00000011; // put current encoder sample in bits 1..0
if (ENC_TYPE_QD)
{
switch (encstat){
case 0b0000: goto enc_done; // 00 -> 00 = no change
case 0b0001: goto enc_inc; // 00 -> 01 = increment
case 0b0010: goto enc_dec; // 00 -> 10 = decrement
case 0b0011: goto enc_done; // 00 -> 11 = illegal, ignore
case 0b0100: goto enc_dec; // 01 -> 00 = decrement
case 0b0101: goto enc_done; // 01 -> 01 = no change
case 0b0110: goto enc_done; // 01 -> 10 = illegal, ignore
case 0b0111: goto enc_inc; // 01 -> 11 = increment
case 0b1000: goto enc_inc; // 10 -> 00 = increment
case 0b1001: goto enc_done; // 10 -> 01 = illegal, ignore
case 0b1010: goto enc_done; // 10 -> 10 = no change
case 0b1011: goto enc_dec; // 10 -> 11 = decrement
case 0b1100: goto enc_done; // 11 -> 00 = illegal, ignore
case 0b1101: goto enc_dec; // 11 -> 01 = decrement
case 0b1110: goto enc_inc; // 11 -> 10 = increment
case 0b1111: goto enc_done; // 11 -> 11 = no change
}
}
[madias – Wed May 30, 2018 3:59 pm] –
You can try out my code I’ve written some years ago
viewtopic.php?f=18&t=15&p=21
Thanks Madias, I’ve already seen your post and tried it but couldn’t get it to work. But that is probably due to my lack of coding skills.
[Manny – Wed May 30, 2018 4:15 pm] –
enum { PinA=PB4, PinB=PB5, IPINMODE=INPUT_PULLUP };
......
old_count = count;
}}
