Wiki2
RotaryEncoder

Rotary encoder

Behaviour during clockwise rotation (CW)

00
10, INT0
00, 10, 00, ... 10 (1 ms)
11, INT1
10, 11, 10, ... 11 (1 ms)
01, INT0
11, 01, 11, ... 01 (1 ms)
00, INT1
01, 00, 01, ... 00 (1 ms)

Behaviour during counter clockwise rotation (CCW)

00
01, INT1
00, 01, 00, ... 01 (1 ms)
11, INT0
01, 11, 01, ... 11 (1 ms)
10, INT1
11, 10, 11, ... 10 (1 ms)
00, INT0
10, 00, 10, ... 00 (1 ms)

States

prev (P) = previous stable state [00,01,10,11]
next (N) = next stable state [00,01,10,11]

On interrupt (INT0 or INT1)

Get next state 2 ms after last interrupt.

Get rotation from P and N.

P  N
=========
00 10 CW
10 11 CW
11 01 CW
01 00 CW
00 01 CCW
01 11 CCW
11 10 CCW
10 00 CCW
00 11 N/A
00 00 N/A
01 10 N/A
01 01 N/A
10 01 N/A
10 10 N/A
11 00 N/A
11 11 N/A

Using only previous and interrupt.

Delay 1 ms in interrupt routine so that interupts is not triggered by bounces. Interrupts are automatically disabled in the interrupt routine.

Next state is also clearly defined from interupt pin. You don’t need to read pins after delay.

P  IRQ         P'
=================
00 INT0 -> CW  10  
00 INT1 -> CCW 01
01 INT0 -> CCW 11
01 INT1 -> CW  00
10 INT0 -> CCW 00
10 INT1 -> CW  11
11 INT0 -> CW  01
11 INT1 -> CCW 10

References