Example gyro code released.

Is the BEI gyro really illegal to use? I am a rookie engineer this year and see that Kevin Watson has included configuration for it in his navigation code. Our team coach handed me the sensor, from last year’s kit, and I have begun wiring it in. IF illegal, why? I saw that the BEI gyro can be purchased on the web. Wouldn’t a team just
count it’s price in the electronics price of it’s parts or is there some rule about past electronics parts. It seems awfully silly to have to not be able to reuse last year’s electronic parts.

No one seems to know what dollar amount to assign to the BEI gyro. I fired-off an e-mail to the FIRST engineering staff seeking clarification, but haven’t gotten a reply (I suspect they’re kinda busy <grin>).


I asked for a quote direct from systron, and this is the respons I got:

Dear Mr. Ross:

Thank you for your interest in Systron Donner Inertial Division. The cost
for qty 1 AQRS is $325 each. Please note that Systron Donner has a $500
minimum order policy.

I have attached a data sheet for the LCG50. These units run $198 each for
qty 1-3.

Please let me know if I can be of further assistance. I will be happy to
provide a formal quotation.

Have a great day!


Adrienne Warren
Marketing Coordinator
Systron Donner Inertial Division
(925) 671-6699 PH (925) 671-6647 FAX
[email protected]
Website: www.systron.com

Okay, the semi-official, over-the-back-fence reading I got on the subject is that the BEI GyroChip gyro cannot be used if you purchase it new. It can, however, be used if you can find a source that will sell you a “used” one for less than $200. I suppose that if a team, for fundraising purposes, sold one of their gyros to a parent for anything less than $200 and that parent donated the gyro back to the school that would be kosher. Teams might also consider selling gyros to other teams. These are very nice gyros and I would really like to see teams use 'em instead of letting 'em collect dust next to the pile of broken drill motors in the storage cabinet.


Be careful about trying to get around the accounting rules by “selling” last year’s used BEI gyro to a team member and selling it back to your (or another) team. See rule <R19>.



How is it that you never seem to sleep, yet function as a (pretty) normal person who manages to keep the entire FIRST manual in your head <grin>?

Here’s R19:

“<R19> Individual COMPONENTS retrieved from previous robots and used on 2005 robots must have their undepreciated cost included in the 2005 robot cost accounting, and applied to the overall cost limits.”

Two things come to mind: 1) There are lots of BEI gyros around that have not been “retrieved from previous robots” and 2) Who knows what the undepreciated value of the BEI gyros is? FIRST certainly didn’t pay >$200 for each one. If you can establish a value by purchasing one “used”, I don’t see a problem. Here’s Q&A #1318:

Q:From ID 1118: The Gyros from previous year’s kits appears to cost $300USD and therefore exceeding <R44> limit of $200USD for electronic components. (http://fastascent.com/Projects/Attitude_Control/Rate_Gyro_s/rate_gyro_s.html)

A:If that is the price, clearly R44 excludes them from being used. Find a used BEI gyro or find a cheaper gyro of another brand.

Here, the FIRST folks are clearly giving the okay to use one that is “used”.


Kevin, even if it is donated, it must be accounted for at the fair market value (section Also, the person you purchase it from must meet the qualifications of a VENDOR (section 5.2), meaning they must have a federal tax id and must make their products availible to all FIRST teams.

I don’t beleive your scenario meets any of these qualifications.

When FIRST says it’s ok to get it used, I beleive you still have to get it per the other rules.

Question 1352 will hopefully clarify this.

ID: 1352 Section: Status: Unanswered Date Posted: 1/25/2005
Q: I’m trying to clarify and the answer to quesion 1318. Are there restrictions to buying used parts and accounting for the used price? Does the seller still have to meet the requirements of a VENDOR? Anything else we should know?

“…section…”? “…must have a federal tax id…”?!? When I start to feel like I should call the family lawyer to get a ruling on something, I quickly lose interest in the proceedings. I’m gonna go back to my corner and write some more code…



Is there any reason why the edubot encoder code from your website won’t work with the Hall effect sensors?


I have tried the ADXRS300EB and the BEI gyrochip AQRS-0075-xxx
(two different units) with some problems.
I have measured a nominal 2.5 volts for both sensors and when
physically swinging both gryo’s in opposite directions see the voltage
swing up/down as expected. So, from a gross standpoint, gyro’s are
The software outputs a gyro bias of 4144? When, I swing the
gryo 180 degrees in one direction, slowly, and return to zero I cannot
get the gyro to indicate zero.
Have set #define to ADXRS300EB setting and #define to AQRS0075
and played with scaling factor without success.
Turned out long term Bias calculation - close to short term bias.
After powering up and gyro reading 0 degrees for 4 or 5 samples,
I swing the gryo 180 degrees slowly and return to zero.
Any suggestions, Kevin.

BTW, I really believe the ADXRS300 EB scaling is not 5 mv /degree/sec
but 7.5 mV/degree/sec. Plus/minus 300 degrees over 4.5 volt range,
is 300 degrees over 2.25 volt range (2.5 to 4.75 or 2.5 to 0.25 volts).
or 2250 mV/300 degrees which is 7.5 mV/deg.

Scaling for Plus/Minus 75 degrees/ second is 30 mV/deg/sec
Scaling for Plus/Minus 150 degrees/second is 15 mV/deg/sec
scaling for plus/minus 300 degrees/second is 7.5 mV/deg/sec

To gain a few extra bits of precision, I oversample the analog output by a factor of eight and maintain that precision throughout all calculations. The bias should be around 8*512=4096. Sample rate and number of samples per update are both configurable by changing a few #defines in gyro.h.

How far from zero is it?

Yes, just for grins, run the sampling rate up to 1600Hz and change the samples per update to 32 and try again. I’ve found it helpful to use a pushbutton(s) to force a bias calculation and/or heading angle reset. This code in the 38Hz control loop will do this for you:

static unsigned char old_io3_state = 1;
static unsigned char old_io4_state = 1;

// did user just push the bias calculation button?
if(rc_dig_in03 == 0 && old_io3_state == 1)

// did the user just release the bias calculation button?
if(rc_dig_in03 == 1 && old_io3_state == 0)

// did user just push the reset button?
if(rc_dig_in04 == 0 && old_io4_state == 1)
// reset the gyro angle to zero

// save the current button states
old_io3_state = rc_dig_in03;
old_io4_state = rc_dig_in04;

Nope. It’s 5.0 (+/- 0.4) mV/deg/sec.


Kevin, downloaded your new 01/30/05 code and everything seems to work right now. Bias was 32382. (512 * 64 samples per update = 32768)
32768(2.5 volts) -32282(Bias)=486. 486/64 = 7.59 a/d counts * 5 mV/count = 38 mV above 2.50. Null bias should equal 2.538 volts. Verfied with DVM. Hooray!
Sampling rate was 1600 Hz, samples per update
rate set to 64, ADXRS300EB utilized, #define TENTHS__OF_A_DEGREE.
#define GYRO_CAL_FACTOR = 1000/1000 (no change).

Simple 180 degree spin test executed. Learn bias at 0 degrees, verify
for 4/5 readings on terminal that angle = 0 degrees. Next, spun gyro 180 degrees - reading about 900 counts (90 degrees * 10 counts/degree).
Return to 0 degree position - read 0 counts (plus/minus 30 - remember,
very coarse test).

Next, tried the GEI GYROCHIP AQRS_00075. Changed the #define GYROCHIP_75 at top of gyro.h. Same spin test gave similiar results. Spun
360 degrees and back - similiar results. Sampling rate 1600 Hz, samples per update rate equal 64, #define TENTHS_OF_A_DEGREE, #define GYRO_CAL_FACTOR = 1000/1000 (no change).

Did you work some new magic in the new 01/30/05 software release, or do
you think the 1600 Hz, samples = 64 is what made this work? I did not
have time last night to experiment with various settings. I tried the
01/22/05 software and found my head bloody from beating it against the
wall to make it work. BTW, thanks for responding to previous e-mail and
publishing 01/30/05 release.

No, not really. In the earlier code/readme.txt, I documented a way to integrate the bias over a longer period of time and then set the bias using Set_Gyro_Bias(). The latest code just automates this process. The real magic will come when I get a Kalman Filter integrated into the code.

Probably both. The new code, out-of-the-box, does a much better job of calculating the bias. Sampling at a higher frequency and down sampling with more samples also helps. I’d advise setting the sample rate to be as low as possible while still getting the performance you need.


Hi, I just wanted to let you know we implemented your code with the ADXRS300EB last weekend and it has been performing perfectly all week. Thanks for the excellent work :). Now the camera is another story…


Well, as Nietzsche said: That which does not kill us, makes us stronger <grin>.


Isn’t Nietzsche dead?:wink:

Yeah, but I doubt it was the camera that did him in <grin>.


i used your gyro code with a ADXRS300. The user_routines.c executes pretty good, the gyro bias is mostly stable there is almost no change in angle. But the autonomous mode is giving us a lot of trouble. I am trying to accomplish two tasks, one give robot an angle and have to turn, like turn(90) and it should turn 90 degree, The other thing is being able to go in a straight line with out drifting. But after about 2-3 seconds in the autonomous i encounter an runtime error( the program state starts blinking red). Here is my user_routines_fast.c please take a look and help me out. :slight_smile:

void User_Autonomous_Code(void)
/* Initialize all PWMs and Relays when entering Autonomous mode, or else it
will be stuck with the last values mapped from the joysticks. Remember,
even when Disabled it is reading inputs from the Operator Interface.
pwm01 = pwm02 = pwm03 = pwm04 = pwm05 = pwm06 = pwm07 = pwm08 = 127;
pwm09 = pwm10 = pwm11 = pwm12 = pwm13 = pwm14 = pwm15 = pwm16 = 127;
relay1_fwd = relay1_rev = relay2_fwd = relay2_rev = 0;
relay3_fwd = relay3_rev = relay4_fwd = relay4_rev = 0;
relay5_fwd = relay5_rev = relay6_fwd = relay6_rev = 0;
relay7_fwd = relay7_rev = relay8_fwd = relay8_rev = 0;

while (autonomous_mode) /* DO NOT CHANGE! /
if (statusflag.NEW_SPI_DATA) /
26.2ms loop area /
Getdata(&rxdata); /
DO NOT DELETE, or you will be stuck here forever! */

    /* Add your own autonomous code here. */

  if (counter &lt; sec(2) )
  else if( counter &lt; sec(4) )



    Putdata(&txdata);   /* DO NOT DELETE, or you will get no PWM outputs! */



  • FUNCTION NAME: Process_Data_From_Local_IO
  • PURPOSE: Execute user’s realtime code.
  • You should modify this routine by adding code which you wish to run fast.
  • It will be executed every program loop, and not wait for fresh data
  • from the Operator Interface.
  • CALLED FROM: main.c
  • ARGUMENTS: none
  • RETURNS: void
    void Process_Data_From_Local_IO(void)
    Add code here that you want to be executed every program loop. */



  • FUNCTION NAME: Serial_Char_Callback
  • PURPOSE: Interrupt handler for the TTL_PORT.
  • CALLED FROM: user_SerialDrv.c
  • Argument             Type    IO   Description
  • --------             ----    --   -----------
  • data        unsigned char    I    Data received from the TTL_PORT
  • RETURNS: void

void Serial_Char_Callback(unsigned char data)
/* Add code to handle incomming data (remember, interrupts are still active) */



  • FUNCTION NAME: move_Forward, move_Backward, pause
  • PURPOSE: Routine handling (name speaks for it self)
  • CALLED FROM: user_routines_fast.c
  • ARGUMENTS: none
  • RETURNS: none
    void move_Forward(void)

void move_Backward(void)

void pause(void)

void set_Right(int value)

void set_Left(int value)


  • PURPOSE: Handles the program loop so that we work in terms of seconds.
  • CALLED FROM: user_routines_fast.c
  • Argument                 Type     Description
  • --------                 ----     -----------
  • number_of_seconds        int      The amount of seconds to be converted
    int sec( int number_of_seconds)
    return number_of_seconds

void turn_Right(int angle)

int temp_gyro_rate= Get_Gyro_Rate();
int temp_gyro_bias= Get_Gyro_Bias();
int temp_gyro_angle = (int)Get_Gyro_Angle();

if ( ((int)Get_Gyro_Rate) > angle)

while( temp_gyro_angle < angle )

  temp_gyro_rate= Get_Gyro_Rate();
  temp_gyro_bias= Get_Gyro_Bias();
  temp_gyro_angle = (int)Get_Gyro_Angle();	

  printf("Gyro Bias=%d\r", temp_gyro_bias);
  printf("Gyro Rate=%d\r", temp_gyro_rate);
  printf("Gyro Angle=%d\r", temp_gyro_angle);
  printf("Gyro Required Angle=%d\r", angle);


I tried working last night with all three gyros and none worked
like the last time. So, first time was bad. Second time was like
a good dream. Third time was bad again.

Gryo angle had drift and bias reported unusual numbers. Voltmeter
on output agreed with gyro angle drift output. I can’t remember
the number right now (like 3.0 volts). At one point I measured
a solid 4.98 volts powering one of the gyro’s over the PWM

Same laptop. software, gyros, FRC controller – the works.

Has there been any reported FRC_Board sensitivity to electical noise
like issues? Should I be extra careful with noise sources? Should
I get away from using A/d channel 01?

I didn’t have any caps to place on output to see if that would help
to stabilize the gyro output. Will all three gyros flaky performance,
however, I am leaning away from viewing the gyro’s as the problem
but the FRC controller.

Have you tried same software on multiple platforms yourself and/or
seen strange problems like this on FRC controllers?

I hope some of the high school student’s end up reading this thread
so that they can see how difficult it can be to make what seems to
be something simple work properly.

Follow up to previous message.

I went home to try the gyro software on a new controller.
So, same software, gyro, different FRC controller.
Gyro operational again. Rotate 180 degrees and get
1800 on display. Return slowly to 0 degrees, get
0 on display. No gyro drift.

I suspect some funny issues with the FRC controller
that we are using in our old robot. When I get a chance,
I will power up the 2005 FRC controller and see what
happens with the gyro.

I will continue to explore different angles as to the reason
for the differing results and update this message accordingly.