@mikerj.
All interrupt driven encoder routines have blind spots, my simple approach may miscount for noise events shorter than the interrupt latency, the state table approach will miscount on noise then usually fix itself on the next pulse.
My simple approach works flawlessly with hall effects and a manual CNC input encoder wheel, except in extreme EMI conditions.
And adding an RC filter followed by a schmidt trigger (such that the time constant is longer than the interrupt latency) will result in 100% accuracy.
An added bonus of the simple approach is it easily "calibrated" , i.e. so it will count 0.995 counts or 1.024 pulses per count (or convert from mm to inches, whatever)
I use the LS3677 encoder interfaces on my big machine controllers, these are almost perfect, but a little analog tweaking minimises the rare occurance of "metastability bias with simultaneous EMI on both channels".
I did develop a state machine encoder interface back in 2008 (prior to using the LS3677), but I think these have been around for ages. Mine was a bit like the Arduino approach.
http://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino I left_shift the Achannel into ABindex, then left_shift the Bchannel in. Then mask off top nibble, the lower four bits are now oldA,oldB,newA,newB , this is a pointer into a lookup tabel that has the three possible results of 16 state transitions, +1,-1, or 0,
... so the relevant line of coding is....
Count = count + LUT(ABindex)So that's 4 lines of code all up, and given that I could use a state type encoder, I prefer to use the simpler approach, and adding an analog RC filter is no additional burden to the dozens of ferrite beads/TVS's/PTC's that already populate the PCBs.