View Single Post
  #1   Spotlight this post!  
Unread 14-11-2008, 17:15
pogenwurst pogenwurst is offline
Ubuntu User
AKA: Brian
FRC #2007 (Robots of the Round Table)
Team Role: Leadership
 
Join Date: Jan 2008
Rookie Year: 2007
Location: Duluth, GA
Posts: 78
pogenwurst is on a distinguished road
Send a message via AIM to pogenwurst
Troublesome encoder ISR

I'm having trouble with the encoder interupt routine I wrote yielding incorrect results. The tick count increases overall, but along the way the count "rolls back" despite the shaft turning in the same direction.

Would anyone care to make a quick check of it for me? It may just be a silly mistake, but I've gone over it again and again and still can't see where I've gone wrong.

A little background:
-> I'm only using one encoder, and resolution is very important for the task at hand, so I'm using the interrupt on digital inputs 3-6 (channel A is in 3, channel B is in 4) so that I can count the ticks for both channels and on both rising and falling transitions.
-> This is on a Vex controller, so I'm using the IFI code, not Kevin's.
-> The following code is contained within the appropriate conditional branch for interrupts 3-6.
-> "encoderCount" is a global volatile signed long, and oldPORTB is a global unsigned char (I use it nowhere but the ISR, so it needn't be indicated as volatile, correct?).

Code:
	const unsigned char aMask = 0x10;
	const unsigned char bMask = 0x20;

	unsigned char a = (PORTB & aMask) == aMask;
	unsigned char b = (PORTB & bMask) == bMask;

	if((PORTB ^ oldPORTB) == aMask)
	{
		if(a)						// a transitioned high
		{
			if(b)					// b is high
				++encoderCount;
			else					// b is low
				--encoderCount;
		}

		else						// a transitioned low
		{
			if(!b)					// b is low
				++encoderCount;
			else					// b is high
				--encoderCount;
		}
	}

	else if((PORTB ^ oldPORTB) == bMask)
	{
		if(b)						// b transitioned high
		{
			if(!a)					// a is low
				++encoderCount;
			else					// a is high
				--encoderCount;
		}

		else						// b transitioned low
		{
			if(a)					// a is high
				++encoderCount;
			else					// a is low
				--encoderCount;
		}
	}

	oldPORTB = PORTB;

	INTCONbits.RBIF = 0;     /*     and clear the interrupt flag         */
Thanks for any help you can offer