I use that code with an optical encoder to convert from quartature to up/down pulses and it tracks the encoder perfectly to >200k edges per second.
Yeah, that's what I thought. We're not using the exact same device. I noticed such irregularities when I was switching between my own encoders (2 different batches).


It might not have a detent at every quadrature state but it sure must "go thru" them.
Oh definitely. I even see them display on the LCD when I turn my encoder REAL slow.


If you are at 00 and go to 11, which direction did it turn? There's no way to know unless also decoding the 10/01 states in between the detents - and you are doing that.
Yup, that's why I check the Current state against the Previous state. I only increase/decrease my counter on 00 and 11, cause that's where the encoder has a physical detent. A user turning the knob doesn't care about intermediate steps; only that the device actuates by one position when the knob goes click.


Take your logic analyzer capture and measure the time between the rising edges of channel A and B respectively.
The pulsewidth of channel A is 11ms but the time between the edges on A and B is much shorter than 5.5ms due to the fact that the phase shift is far from 90° on your encoder. Lets say it's 2ms...
The fastest interval between wiper A and B is on a drop, and it's 3.88ms


How long does your LCDoutput subroutine take?
~1.92ms


Note that the final product will use a dedicated PIC to display data on LCDs, and a separate PIC to process incoming encoder signals.

I'm only using the LCD alongside the encoder to help me understand how the encoder is behaving.