Log in

View Full Version : Get_Gyro_Angle() overflows beyond about -20000 deci-decgrees?


gnormhurst
29-02-2008, 20:02
I'm trying to make an approximate lap counter by dividing the accumulated gyro angle by 360 (or 3600, since I'm working in decidegrees).

It works up to 5 laps, then the gyro value seems to wrap around to the positive side and start decreasing. I'm using long ints for the calculations. Here is a simplified version of the code....

long int gyroAngle;
unsigned int numLaps = 0;

gyroAngle = Get_Gyro_Angle();
if ( gyroAngle < 0L ) gyroAngle = -gyroAngle; //absolute value.

numLaps = (unsigned int) ( (gyroAngle) / (long int)3600);
printf( "gyro: %5ld LAPS = %2d\r\n", (gyroAngle), (int)numLaps );


// etc.....

I looked at the gyro.c code briefly. Get_Gyro_Angle() (below) returns a long int, but there's a bunch of #defined constants, not all of which sport the decorative "L" at the end. (BTW, does "L" make a literal into a short int (16) or a long int (32)? I checked the compiler manual and didn't see it defined.)

long Get_Gyro_Angle(void)
{
// Return the calculated gyro angle to the caller.
return(((gyro_angle * GYRO_SENSITIVITY * 5L) / (ADC_RANGE * ADC_UPDATE_RATE)) * GYRO_CAL_FACTOR);
}


Why can't I get big values out of Get_Gyro_Angle()? e.g. 6 laps = 6 * -3600 = -21600.

Joe Ross
29-02-2008, 20:18
I'm trying to make an approximate lap counter by dividing the accumulated gyro angle by 360 (or 3600, since I'm working in decidegrees).

It works up to 5 laps, then the gyro value seems to wrap around to the positive side and start decreasing. I'm using long ints for the calculations. Here is a simplified version of the code....

long int gyroAngle;
unsigned int numLaps = 0;

gyroAngle = Get_Gyro_Angle();
if ( gyroAngle < 0L ) gyroAngle = -gyroAngle; //absolute value.

numLaps = (unsigned int) ( (gyroAngle) / (long int)3600);
printf( "gyro: %5ld LAPS = %2d\r\n", (gyroAngle), (int)numLaps );


// etc.....

I looked at the gyro.c code briefly. Get_Gyro_Angle() (below) returns a long int, but there's a bunch of #defined constants, not all of which sport the decorative "L" at the end. (BTW, does "L" make a literal into a short int (16) or a long int (32)? I checked the compiler manual and didn't see it defined.)

long Get_Gyro_Angle(void)
{
// Return the calculated gyro angle to the caller.
return(((gyro_angle * GYRO_SENSITIVITY * 5L) / (ADC_RANGE * ADC_UPDATE_RATE)) * GYRO_CAL_FACTOR);
}


Why can't I get big values out of Get_Gyro_Angle()? e.g. 6 laps = 6 * -3600 = -21600.

gyro_angle * GYRO_SENSITIVITY * 5L is overflowing a long. Kevin's latest gyro code gives a little more headroom by rearranging the order operations are done to not overflow as early.

gnormhurst
29-02-2008, 20:31
Okay, I'll check out Kevin's newer code....

BTW, for my current code I dereferenced the macros and got

long Get_Gyro_Angle(void)
{
// Return the calculated gyro angle to the caller.
return(((gyro_angle * GYRO_SENSITIVITY * 5L) / (ADC_RANGE * ADC_UPDATE_RATE)) * GYRO_CAL_FACTOR);
// translates to:
//return(((gyro_angle * 800L * 5L) / (1024L * ADC_SAMPLE_RATE/(ADC_SAMPLES_PER_UPDATE * NUM_ADC_CHANNELS))) * 958/1000);
// which translates to ...
//return(((gyro_angle * 800L * 5L) / (1024L * 200/(4 * 1))) * 958/1000);


}
I guess I could make my own Get_Gyro_Angle_Low_Resolution() that doesn't use such a large value for GYRO_SENSITIVITY.

gnormhurst
29-02-2008, 23:11
I've seen the gyro.c,h code in the new 3.0 compatible code. I am using 2.4. Can I just drop the gyro.c,h files into my code and expect everything to be fine? Or are there 3.0/2.4 issues?