|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
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 */
|
|
#2
|
|||
|
|||
|
Re: Troublesome encoder ISR
How fast are they spinning? What COULD be happening is you are spinning them fast enough that when you check for direction (I assume Quadrature Encoders based on a and b in your code) you have already transitioned too far. The only real solution would be slow it down. Turn the encoders by hand to see if this is happening then too. Hope this helps.
|
|
#3
|
|||
|
|||
|
Re: Troublesome encoder ISR
They're spinning pretty slowly -- the 'bot takes several seconds to move a meter, and the shaft it's on has a sprocket quite a bit larger than that on the wheels' shaft (48 teeth encoder/motor shaft : 15 teeth wheel shaft, IIRC), which slows down the tick rate on the encoder even more if I'm not mistaken.
Also, when my ISR is simply "++encoderCount", it accurately counts the number of ticks (but without sense of direction, obviously). My direction-aware ISR isn't enormously complicated; it doesn't seem like enough to make it miss ticks, though I certainly could be mistaken. Next time I have access to the machine I'll experiment with turning the shaft, though. Thank you for your reply. I'll let you know if I figure it out. |
|
#4
|
||||
|
||||
|
Re: Troublesome encoder ISR
I know this will only give you 1/4 the resolution you want, but does at least this work?
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 == aMask)
{
if(a) // a transitioned high
{
if(b) // b is high
++encoderCount;
else // b is low
--encoderCount;
}
}
oldPORTB = PORTB;
INTCONbits.RBIF = 0; /* and clear the interrupt flag */
-Shawn T. Lim... Last edited by Mr. Lim : 19-11-2008 at 22:09. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Encoder help | E_Unit | Electrical | 5 | 16-02-2007 11:02 |
| Encoder Death | rfolea | Programming | 8 | 14-02-2007 14:06 |
| Encoder Problems | bjimster1 | Programming | 2 | 10-02-2007 08:04 |
| Encoder Hookup | kutty18 | Electrical | 4 | 22-01-2005 12:17 |
| encoder.c | Gary Bonner | Programming | 2 | 14-01-2005 13:41 |