Quote:
|
Originally Posted by Dave Scheck
Absolutely, you need to catch both the rising and falling edge.... ...Watching only one edge will definately not work for the normal usage.
|
Just to pile on, and expand a bit on what Alan says above, you only need to interrupt on one edge. Here's the entire interrupt handler from some code I wrote:
Code:
void Left_Encoder_Int_Handler(void)
{
// The left encoder's phase-A signal just transitioned
// from zero to one, causing this interrupt service
// routine to be called. We know that the encoder just
// rotated one count or "tick" so now check the logical
// state of the phase-B signal and increment or decrement
// the Left_Encoder_Count variable.
if (LEFT_ENCODER_PHASE_B_PIN ==0)
{
Left_Encoder_Count -= LEFT_ENCODER_TICK_DELTA;
}
else
{
Left_Encoder_Count += LEFT_ENCODER_TICK_DELTA;
}
}
LEFT_ENCODER_TICK_DELTA is #define'd as either 1 or -1. This works great for velocity control and most of the time for position control. If I remember correctly, several months ago Alan mentioned that he had a problem using this scheme in his position control application because his mechanism would sometimes stop right on a tick mark and generate a bunch of spurious interrupts, which would
cause problems because the phase-b signal might change before the ISR could read it. In this case you need to add some hysteresis in the form of a state machine to track the states and increment/decrement the counter correctly. This approach increases reliability at the cost of greatly increasing the time spent in the ISR, which will decrease the maximum tick-tracking rate of your encoder software. I'll add this capability to my encoder code in the near future and update the documentation.
-Kevin