Quote:
Originally Posted by UnderDark
The VEX encoders send a binary string. You should only increment distance when the latest value is different from the previous value.
Code:
unsigned int distance = 0;
char encOld = 0;
.
.
.
if((char)rc_dig_int1 != encOld)
distance++;
encOld = rc_dig_int1;
|
This code isn't using an interrupt handler, and so it can miss transitions. If you want to use an interrupt handler to count ticks as they come in, here are some instructions on how to modify the default code. The following assumes that you're hooking up two encoders, right side connected to interrupt pin 1 and the left side connected to interrupt pin 2. It should be clear how to modify things if your setup is different. Using the higher numbered interrupt pins is a bit more work since they used a share interrupt instead of the nice dedicated interrupts for pins 1 and 2.
To get the encoder values, just look at the two globals. It would be better to wrap that lookup in code that disable interrupts, so you don't risk having the value change in the middle of reading it. I can post that bit of code later, but I need to run right now.
user_routines.c
---------------
in the function "User_Initialization" add this line:
Code:
EnableInterrupts();
user_routines.h
---------------
in the Function Prototypes section, add these lines:
Code:
extern volatile int g_distMotorLeft;
extern volatile int g_distMotorRight;
void EnableInterrupts(void);
user_routines_fast.c
--------------------
below this line:
/*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/
add these lines:
Code:
volatile int g_distMotorLeft = 0;
volatile int g_distMotorRight = 0;
replace the entire InterruptHandlerLow function with a new version and two more functions:
Code:
void InterruptHandlerLow ()
{
unsigned char int_byte;
if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) /* The INT2 pin is RB2/DIG I/O 1. */
{
INTCON3bits.INT2IF = 0;
++g_distMotorRight;
}
else if (INTCON3bits.INT3IF && INTCON3bits.INT3IE) /* The INT3 pin is RB3/DIG I/O 2. */
{
INTCON3bits.INT3IF = 0;
++g_distMotorLeft;
}
else if (INTCONbits.RBIF && INTCONbits.RBIE) /* DIG I/O 3-6 (RB4, RB5, RB6, or RB7) changed. */
{
int_byte = PORTB; /* You must read or write to PORTB */
INTCONbits.RBIF = 0; /* and clear the interrupt flag */
} /* to clear the interrupt condition. */
}
void ResetEncoders()
{
g_distMotorLeft = 0;
g_distMotorRight = 0;
}
void EnableInterrupts()
{
// interrupt 2, which is pin 1
TRISBbits.TRISB2 = 1; // make sure pin is configured as an input
INTCON3bits.INT2IP = 0; // interrupt is low priority
INTCON2bits.INTEDG2 = 1; // trigger on rising edge
INTCON3bits.INT2IF = 0; // make sure interrupt flag is clear before enabling
INTCON3bits.INT2IE = 1; // enable the interrupt
// interrupt 3, which is pin 2
TRISBbits.TRISB3 = 1; // make sure pin is configured as an input
INTCON2bits.INT3IP = 0; // interrupt is low priority
INTCON2bits.INTEDG3 = 1; // trigger on rising edge
INTCON3bits.INT3IF = 0; // make sure interrupt flag is clear before enabling
INTCON3bits.INT3IE = 1; // enable the interrupt
}