INT1. Perfect! Listing 2 shows all that needs to be done to
capture these pulses from the motor.

Note that I am using both interrupt lines to capture
each phase of the encoder, and that I count each rising
edge. This gives me 360 tics per revolution which is
pretty decent. However, if I had two motors — which is
quite reasonable — then I’d want to use an interrupt for
each motor. In this case, I would not capture the second
phase — only the first for each motor. This reduces my
resolution to 180 tics per revolution, or two degrees per
tic. Still not too bad. Look at ISR(INT0_vect). You see that
I set the motor direction by looking at the logic level of
the second quadrature phase. Let’s discuss that a little. In
Figure 6, I show the phase relationship between the two
quadrature encoder outputs. By examining these pulse
trains, you can see how easy it is to determine the motor
direction.

ISR(INT0_vect) is triggered at point A in Figure 6; at
the same time the ISR looks at the other quadrature line to
determine the direction of the wheel turn. At point B,
ISR(INT1_vect) is triggered and the tic count is incremented
again. To get perfect symmetry in the wheel encoder count,
we really should trigger at the falling edge of the pulse
after point A; where I trigger it now is off by 0.5 degrees.

}

It still works pretty well, however.

How do we know the direction? Look at the two sets
of pulse trains in Figure 6. When going forward, the INT0
ISR triggers at point A. At this time, we look at the other
phase and see that it is logic low. We’ll call this forward.
When we look at the reverse pulse train pair, we see that at

/*
Go forward and back the same distance
to see how the encoders work. I am using
5cm diameter wheels giving a 15.71cm
rollout (circumference). Going 1000 tics,
when we count a tic every 1 degree means
1000/360 = 2.78 revolutions. 2.78 times
15.71 = 43.6cm distance traveled.
}
We hit it dead on.
}
*/

/*
Now let’s just twiddle the motors back
and forth to see the direction changes.
*/
while(1)
{