I have to admit, Ioannis, the code was grabbed from an example here and implemented on my side using a Grayhill encoder which only triggered the interrupt once per detent. Works perfectly with that device, With the CUI ACZ11, I added the check on the ISRCounter but it **does** work - both CW & CCW rotations are captured correctly.
I tried CCW rotation again last night and it does seem to get confused every once in a while - either decrements by 2 or sometimes even increments. Doesn't happen often enough to be too much of a problem, but I would like to make the code as efficient as possible.
Not sure what else I can do in the ISR, though. If I only need one edge to check the rotation direction then I could do as Henrik suggested and turn off 2 of the edge interrupts; that way, it would only hit the ISR twice. I could do the RotEncDir determination on the first interrupt then set a flag to ignore the 2nd interrupt, then reset those after the 2nd.
I stil cannot see how this piece of code can be true:
If you follow what Henrik has posted on that pulse train diagram at #21, you will see that after the above XOR, the IF RotEncDir = 1 statement will always fail and the ELSE will be executed.Code:RotEncDir = New_Bits.1 ^ Old_Bits.0 IF RotEncDir = 1 Then
Ioannis
The New_Bits will be the same for A & B, but the Old_Bits should still have PORTA.0 (B pin of encoder) as 1 for the last falling edge interrupt, won't it?
I don't think so after the 4 step counter. At that moment both will be zero.
Ioannis
But experimentally it works, both for CW & CCW. I'd love to optimize this code for full quad cycle encoders like the CUI ACZ11 one I'm using, but I'm at a loss as to what to change (other than trying Henrik's suggestion of reducing the number of edges to 2 from 4).
Bookmarks