Gyro inconsistencies...

After two days of testing, I’m pretty sure our gyro gives slightly different output, depending on which direction it’s turning. For instance…





These are outputs given after resetting the angle to zero and slowly turning the gyro exactly 180 degrees. As you can see, the clockwise direction is quite near perfect, but the other direction is always off. You can also see that both directions are very consistent. If I re-calibrate based on the counter-clockwise direction, then the clockwise direction is consistently off.

I’m not really that worried about 3 degrees, but what I’ve found is that because of this, when the gyro turns far from zero, it doesn’t go back to zero at the same position, and I can easily see that error compounding very quickly, particularly since the gyro seems to be less consistent the faster I turn it, and I doubt the robot will want to turn as slowly and carefully as I am.

Is this really all that strange? Should I just reset the heading to zero whenever I actually need to use it? Should we perhaps invest in a better quality gyro?

Settings and such…

ADC Sample Rate of 1600Hz
32 ADC Samples per Update
Deadband set to 16 (Deadband and Bias double when resolution goes from 2048 to 4096)
Using ADXRS150


We are just now getting to the GYRO. I am not sure if you’ve seen this link from the Killer Bees Team but this is where we are starting for our Gyro primer.

After this weekend I should be able to let you know more once we get the gyro up and running. Also, the GYRO from last years KOP had a faster response in terms of measuring DPS (Degrees Per Second). Could measurement lag be causing your measurement anomaly?

Please let us know how it works out, and if you wouldn’t mind sharing your Gyro code we would like to see it.


Remember that this is a Yaw Rate Gyro, key word being Rate. This gives an output in degrees per second, so in other words it measures how FAST the sensor is being turned - NOT how much it has turned.

If you multiply the rate times time, then you get amount of turn. But, how you do that multiplication can introduce errors if the rate is not exactly constant. That could be the source of your error, perhaps.

Try to eliminate that source of error by turning at as constant a rate as possible, and not very slowly - about 90 degrees per second is probably a good rate.

EDIT: Make sure you’re turning the gyro about it’s real axis, which is not the axis of the PC Board!


Perhaps I should have mentioned that I’m using Kevin Watson’s background gyro code (gyro.c and gyro.h) as well as Kevin’s ADC code.

And although the gyro is turning slowly and not at a constant rate, that shouldn’t make much difference, since I’m the one turning it both times and I’ve been taking care to be consistent in that respect. Plus, since the individual sets of numbers (clockwise and counter-clockwise) are so consistent, that suggests that the error is internal, not external.

I just thought someone with more experience working with the gyros might have come across this before.

A couple of things to keep in mind about gyros -

  1. you could be experiencing an error due to nonlinearity (although the 1.5% difference between your CW and CCW results is a bit higher than the spec for the gyro)

  2. you may still have some residual offset error in the gyro (most likely in my opinion)

  3. your gyro may be “leaning” when turning CW instead of CCW (or vice versa) and causing an effective gain change (but again 1.5% is a bit high since the “lean” would have to be about 10 deg of tilt (cos(10) = 0.985))

I’d recommend running the same tests that you’ve been doing (specifically duration of time) but without any physical rotation. I’m guessing that you’ll observe a non-zero heading at the end of the time interval (probably 1.5 degrees).


No, the time span is only just a few seconds, and it takes a couple minutes for the heading to change when immobile.

I’ll dig out another gyro or two from our sensor box tomorrow and see what kind of results I get.

I don’t know the details of Kevin’s code but I wouldn’t be surprised if the code “ignores” small non-zero readings. That is a very simple but technically insufficient way to keep from “runaway” due to integration of a small non-zero output.

The proper way to dedrift a gyro is to use an absolute reference (eg compass and inclinometer). Since an absolute reference is typically too expensive for applications like ours, a SW solution with a band clamp is often used (as in Kevin’s code?).

I’ll bet that there’s still a non-zero offset in the readings but it’s being masked by a nonlinear bit of SW.

There is another possible culprit - ADC resolution. This could be affecting either the null cancellation or the value that’s reported when it’s actually spinning. Depending on the rate at which the gyro is rotating and a number of other factors, ADC resolution could come into play. I’d be very surprised, however, since there is almost certainly more “noise” in the gyro output than ADC resolution and the effective resolution is usually fine.


This is exactly what my code does, although Jake’s deadband setting of sixteen DN seems excessive. I strongly suspect there is something wrong with Jake’s gyro because the code works really well with the gyros I have on hand (several ADXRS150s, two ADXRS300s, one Systron Donner from the 2005 KOP, and several Silicon Sensing Systems’ CRS03s). As I mentioned here, I have a CRS03 that ran for nearly two hours with less than two degrees of drift using the default ADC settings. One of my ADXRS150s will do nearly as well as that CRS03. Jake, if you can, try a different gyro because what you’re seeing isn’t typical behavior.


What is your rotation rate? How fast are you turning 180 degrees?

Maybe you’re getting close to saturation. Aren’t the gyros set for 90 deg/sec max rate this year or are they really set for 150 deg/sec?


This year’s gyro is actually set to 80 deg/sec, but I was using one of the older years, at 150 deg/sec.

The 16 for deadband is actually the defualt of 8 that you provided, since I raised the ADC resolution from 2048 to 4096. The gyro bias doubled in the same way when I raised the resolution.

I’ll probably end up putting the ADC back to default, because raising the update rate and resolution doesn’t seem to have made any difference.

I know we have some other ADXRS150’s from past years somewhere, I just need to go find them tomorrow. We had to call of building for today.

Thanks for the input, everyone. In the end, I think the bulk of what I’ll use the gyro for is to back up the basic driving output (our frame tends to pull slightly to the right) for which I’ll only need to use the rate. As a programmer, little problems like this just tend to bug me if I can’t explain them.

I plugged in this year’s brand new gyro and it’s the same story. Clockwise and Counter-clockwise measurements are consistently about 2.5 degrees apart from each other. It must have something to do with how I’m mounting and testing it. I’m just going to calibrate it for counter-clockwise, which will be the main turning direction this year, and leave it at that.

Thanks for all the help, everyone.

keep in mind that those readings are in 10ths of a degree, so you have to knock off the last digit. both directions are pretty near 180 degrees (179,180)

Which is another reason why I’m not going to worry about it.

If you get two gyros with the same specs, what if you mounted one with its axis of rotation opposite the other (i.e. upside down)? That way, while one was rotating CCW around its axis, the other would be rotating CW. You could probably implement some software error elimination by averaging the two ouputs or only taking the reading from the one that is currently rotating in the ‘correct’ direction.

If I cared that much, I would just implement two GYRO_CAL_FACTOR’s, one for each direction.

I will almost guarantee that the problem is caused by asymmetry in the ADC and being augmented by the dead band.

In general, any dead band on an integrator is not a good idea if you want accuracy in your results. See this whitepaper:

It’s been our experience that with a good bias routine you can expect less than 1/2 degree of heading drift over 15 seconds worth of autonomous operation. Just be sure to have a lot of resolution in your bias calculation.

Here is what I would suggest for a simple solution:

  • For the bias routine, check the status of the disabled flag. As long as the robot is disabled, do a moving sum of the last 64 A/D samples. Make sure it is a moving sum, not average - this will make sense after the next step. See the following example code (put it in user_routines.c function Process_Data_From_Master_uP()):

if (disabledMode)
    bias = bias - biasBuffer[biasCounter] + gyroADC;
    biasBuffer[biasCounter] = gyroADC;
    if (biasCounter > 63)
         biasCounter = 0;

just be sure to initialize all values in biasBuffer to 0 during code initialization.

  • After the bias routine, take your A/D samples and multiply them by 64 (i.e. shift the bits left by 6 so that the bits are in the upper most bits of the variable.) The A/D reading is now in the same resolution as your bias. Now just subtract the bias from the left-justified A/D reading.

  • Use the above bias adjusted value in your integral. Use a 32-bit variable for the integral. DO NOT right shift the new bias adjusted A/D reading or else you’ll lose all of the resolution you gained in the bias.

Doing this should keep your heading drift very minimal over 15 seconds while it doesn’t have the asymmetry problems associated with dead bands.

Good luck.

Chris has it right here. The dead band is the source of the symmetry problem. We sample our gyro at 152 hz and compute the integral using the trapezoid rule in 256ths. We use the average of many 128 sample sums, hard coded in, for the bias. The result is a drift of only a tenth of a degree or two for the 15 second autonomous period, with good symmetry.