SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By lsteele
#24383
Hi there,

I’ve got a SparkFun 5DOF IMU. The idea is to use it connected to a pic16f876a to produce a measure of angle for a robot. However, I’m running into a lot of difficulty getting steady values from the gyro.

I initially measure a gyro value while the imu is stationary, which I take to be the ‘zero’ value for the gyro (i.e. it’s not turning). The idea is I then subtract this value from subsequent readings of the gyro to produce a rate of rotation. To do this I have the PIC spit out values for the gyro rate of rotation to an LCD. Strangely while the gyro is stationary I get a value of 463. I’ve got an LM317 giving me 3.3 volts to power the IMU, and this is also fed to the PIC’s VREF+, so I would intuitively have expected the zero point of the gyro to halfway through the ADC’s range (10bit). Anyhow, the problem is if I then change the code to subtract this value from subsequent gyro readings I get a value of 1 or 2, not 0 as I would expect when the gyro’s not moving. Obviously this produces huge errors if I start summing the gyro rate to give me an angle. If I try changing the zero calibration value to compensate (e.g. to 465), sometimes it seems to settle down, sometimes not.

Incidentally, I should mention that I also have some pots connected to the pic’s other analogue channels, and I seem to get rock solid values from these (no jittering or anything) when I output them to the LCD.

Is this all likely to be down to power supply problems? I’ve have a 5v regulator powering the pic with smoothing caps as per the datasheet, and the aforementioned lm317 powering the imu, again with the recommended caps. Or does the solution lie with the VREF from the gyro? According to the data sheet for the IDG300, “VREF is a temperature independent voltage reference
that can be used as a reference for an ADC. There is offset between the zero rate output and VREF.â€
By NleahciM
#24385
It sounds like you are experiencing the wonderful thing called 'gyro drift'. The null value (the value corresponding to 0 angular velocity) drifts on inexpensive gyros. Typically people use kalman filters to fix this. Check out this thread for more info: http://www.sparkfun.com/cgi-bin/phpbb/v ... php?t=4273
By emf
#24395
lsteele wrote:Hi there,
Strangely while the gyro is stationary I get a value of 463. I’ve got an LM317 giving me 3.3 volts to power the IMU, and this is also fed to the PIC’s VREF+, so I would intuitively have expected the zero point of the gyro to halfway through the ADC’s range (10bit).
In the datasheet, it says the zero-rate output for the gyros is 1.5V, and that this value is not ratiometric to the supply voltage. Under ideal conditions, you should expect your zero-rates to be reading (1.5 / 3.3 * 1024) = 465, so your numbers are in the right ballpark.

As an aside, there's probably no reason to use 3.3V instead of 3V to power the gyro (except that you have a 3.3V regulator lying around). The gyro is specified down to 3V, and the accelerometer is specified to 2V, I think. Running at 3V would give you something like another 10% accuracy.
Anyhow, the problem is if I then change the code to subtract this value from subsequent gyro readings I get a value of 1 or 2, not 0 as I would expect when the gyro’s not moving. Obviously this produces huge errors if I start summing the gyro rate to give me an angle. If I try changing the zero calibration value to compensate (e.g. to 465), sometimes it seems to settle down, sometimes not.
As the other poster mentioned, you're not going to be able to get away with something as simple as just summing the angles coming off of the gyro to find out which way you're pointed. Depending on the application, you might be able to get away with something less than a full Kalman filter, but you definitely need a good bit of smarts in the software.

In addition to the usual drift problem, you'll also note that there are some pretty wide tolerances in the datasheet. The gyro is specified for 0 to 70 degrees C, and in that range, the datasheet says the zero-rate value may vary from 300mV in either direction. This gyro also doesn't give you a temperature sensor to allow you to correct for temperature. I don't know how realistic that is, but for the sake of argument let's say the temperature effect is only half as bad as they specify, and that it's linear: That would make each change of a degree C cause a 4mV change in the gyro reading, and a 10-bit ADC will see any change of 3mV or more.
Or does the solution lie with the VREF from the gyro? According to the data sheet for the IDG300, “VREF is a temperature independent voltage reference
that can be used as a reference for an ADC. There is offset between the zero rate output and VREF.â€
By lsteele
#24398
Hi,

Thanks for all the info.

I had realised that summing the gyro values wouldn't give me a solid angle in of itself because of drift - my idea was that since I get a value for angle from the gyro summing, and a value for angle from the accelerometer, if I were to scale these two readings so that for a given angle they were of the same magnitude (before the drift had really started to kick in), I'd be able to recalibrate the gyro derived angle with the accelerometer derived angle. I thought I could probably recalibrate a few times a second to keep the drift in check.

Obviously it had occurred to me to just use the accelerometer angle, but right now it's too crude in resolution for my purposes. (i.e. a change in angle of a degree or two is required for the ADC reading to change).

So it seems to me at this stage I should:

Give the IMU 3V and see if that helps.

Try and confirm if temperature changes are causing the change in the gyro's rest voltage. (It's pretty cold here at the moment, so opening the window for a few minutes should effect a pretty big change!)

Your points about the lack of temperature sensor in the gyro make me wonder if it's possible to use this board for this purpose... Or can something like a Kalman filter resolve all these problems?

Thanks again - any more suggestions are appreciated.
By bungalow_steve
#24423
lsteele wrote:Hi,



Thanks again - any more suggestions are appreciated.
You need temperature calibration if your goal is to measure absolute angles, the IDG300 chip was originally designed for image stabilization applications (steady cams) were you only need to know rate changes (previous rate - current rate), and thus it doesn't need an internal temperature sensor to calibrate rate offsets out.

So you can either add a temperature sensor (glue it to the top of the chip) and/or keep the temperature constant (glue a small heating element to the top of the chip and keep it heated at a constant temp, if you can spare the power).

The Analog devices ADXRS gyros have internal temp sensors and claim you can get the drift down to 70 degrees/hour over temperature, so if you added a temp sensor that is probably what you can expect with the IDG300 gyro.

A kalman filter will help but not magically resolve these problems. The kalman filter optimally combines (or fuses) redundant information into a single reading, but if both redundant inputs suck (ie., your gyro sum and accelerometer outputs), the output of the kalman filter will suck too....
By emf
#24425
lsteele wrote:Hi,
I had realised that summing the gyro values wouldn't give me a solid angle in of itself because of drift
Great. As long as you're willing to do a bit of work, you should be able to get some respectable data out of the IMU.
Obviously it had occurred to me to just use the accelerometer angle, but right now it's too crude in resolution for my purposes. (i.e. a change in angle of a degree or two is required for the ADC reading to change).
What kind of precision do you need? If I get my IMU to give me an angle within a degree or two, I'll be very happy :-) I haven't considered how to get more accurate readings because I don't really need them.

My initial reaction is that when your robot is at rest, you're never going to have a more accurate reading than your accelerometer gives you. I didn't understand the details of your plan for managing the drift of the gyro, but I guess I don't see how you're going to get much more accurate data from the gyro. When you first power up, the only information you have about your absolute angles is from the accelerometer, and I don't see how you can correct that with a rate sensor. I've seen people do stranger things, though...

I was just trying to figure out what kind of accuracy you should expect, here's what I came up with: at 3.3V, your ADC resolution is about 3.2mV. The gyro gives you 2mV/degree/second, so (worst case) your ADC could be giving you the zero-rate reading when the robot is rotating at 1.6 degrees per second. If the gyro ADC reading was the zero-rate value for one minute straight, you could truly have not rotated, or you could be lying on your side. The accelerometer gives you 330mV/g, so your ADC could sense slightly better than .01g increments. If you're nearly level, you should be able to sense angles as small as arcsin(0.01) = 0.57 degrees.

Do these numbers look right to you?
Give the IMU 3V and see if that helps.
That should give you 10% better gyro readings, but it won't help the accelerometer readings. Don't expect this to make much of a noticable difference to you, but consider it when you build a new board.

You could try oversampling the accelerometer and see if you can get a few more bits of precision.
Try and confirm if temperature changes are causing the change in the gyro's rest voltage. (It's pretty cold here at the moment, so opening the window for a few minutes should effect a pretty big change!)
I'm definitely curious to see how this test turns out.
Your points about the lack of temperature sensor in the gyro make me wonder if it's possible to use this board for this purpose... Or can something like a Kalman filter resolve all these problems?
Not positive, but I think a Kalman filter would keep track of the zero-rate value for you. [edit: the Kalman filter doesn't track the zero-rate value. The example Kalman filter linked above looks like it tracks the gyro bias by comparing the filter's angle estimate by the gyro's angle estimate and nudging future gyro results in the appropriate direction) I don't think it would do much to increase the precision of the readings.
By lsteele
#24435
Thanks again - this is all very interesting.

I'm trying to build a balancing robot.

I had an early version which used servos and a stick connected to a pot to calculate angle. This setup worked very well, though due to the limited speed of the servos it couldn't recover from anything more than gentle disturbances (caused by me). Left to it's own devices it would balance indefinitely.

Now I'm trying to use a gyro and some proper gearbox motors. I'm using an equation of the form P*angle - D*angleRate to calculate torque. Initially I didn't use the gyro at all, just the accelerometer to calculate the angle and angleRate. At low values for my P & D constants the robot looked like it was close to balancing, but the motor wasn't moving fast enough to bring it upright. The problem I had was that as I increased the size of the P constant, because this was derived from the accelerometer derived angle, I got abrupt changes in motor speed as the accelerometer value increasing by a single ADC tick - this is what I meant about the accelerometer-only angle reading being too crude.
When you first power up, the only information you have about your absolute angles is from the accelerometer, and I don't see how you can correct that with a rate sensor. I've seen people do stranger things, though...
Yes, I realise I have to use the accelerometer to give me an absolute measure of angle. But because of the problems I mentioned above I though maybe I could use the gyro to increase the subtlety of my moment-to-moment angle measurement. I.e., get an angle value from the accelerometer, then start summing gyro outputs (at a regular interval) for a short time and add this gyro derived change in angle to the accelerometer angle. Then after a short interval (perhaps a fraction of a second) get another accelerometer value for the angle and start again.

I've tried this, but right now the fact that I don't have an dependable value for the zero value of the gyro is making this impossible.
You could try oversampling the accelerometer and see if you can get a few more bits of precision.
Is oversampling in this case averaging a number of values? This had occurred to me - I'll give it a go.
(glue a small heating element to the top of the chip and keep it heated at a constant temp, if you can spare the power).
I like this idea! I'll look into it.
By emf
#24485
lsteele wrote:I'm trying to build a balancing robot.
Ah, now it's making more sense. I've always wanted to try making one of those...

Now I'm trying to use a gyro and some proper gearbox motors. I'm using an equation of the form P*angle - D*angleRate to calculate torque. Initially I didn't use the gyro at all, just the accelerometer to calculate the angle and angleRate. At low values for my P & D constants the robot looked like it was close to balancing, but the motor wasn't moving fast enough to bring it upright.
The problem I had was that as I increased the size of the P constant, because this was derived from the accelerometer derived angle, I got abrupt changes in motor speed as the accelerometer value increasing by a single ADC tick - this is what I meant about the accelerometer-only angle reading being too crude.
Ok... I can start to see how you would need very accurate angle measurements now. Especially for the accelerometer-based angleRate...
But because of the problems I mentioned above I though maybe I could use the gyro to increase the subtlety of my moment-to-moment angle measurement.
Got it. My brain was hung up on thinking that you cared mostly about the absolute angle.
I've tried this, but right now the fact that I don't have an dependable value for the zero value of the gyro is making this impossible.
Assuming this is something like temperature drift, I don't have a lot of good ideas on how to get rid of the variation, it would just be a matter of making your software realize that a zero-change had occurred and correct for it before the robot hit the ground. The heater approach might minimize the problem, but you'll probably still have to deal with it at some degree. More ADC bits would also give you a little more time to react to the drift, but it wouldn't change the nature of the problem.
Is oversampling in this case averaging a number of values? This had occurred to me - I'll give it a go.
I was thinking of a trick I read here:

http://www.atmel.com/dyn/resources/prod ... oc8003.pdf

which basically lets you get n extra bits of precision by combining 4^n readings. It requires a bit of noise in the input. I seem to remember getting enough noise in my ADC readings to make it work, but I never tried it. It sounds like your readings might be more steady than mine. If you program in assembly, the microchip's application maestro can generate code for this sort of oversampling, although it looks pretty easy to do by hand.

I'll also mention here that I noticed that the output impedance of the accelerometer is a good bit higher than the ADC on the PIC is supposed to handle. I'm pretty sure this isn't causing any problems for you, but it's something I noticed when I was reading through the docs.
By lsteele
#24637
Wow, this is tough.

I've spent quite a bit of time trying implement the scheme I outlined in a previous post, namely trying to grab values from the gyro for moment-to-moment balancing while periodically using an accelerometer to provide a new angle value then using the gyro from there, and so on. This has proven pretty unsuccessful so far. In an effort to understand how rapidly the gyro values were drifting I've tried having the robot balance using the gyro alone. This has produced the best results so far, but the robot typically doesn't stay balancing for more than 5 or 6 seconds before the drift becomes too significant.

This makes me wonder whether this gyro is a suitable device for this application. The gyro has a range of +/- 500 deg/sec, which is pretty big. Some of the Analog Device's gyros go down to as low as 75 deg/sec, which seems much more suitable. Certainly accounts I've read on the internet suggest people have got robots to balance successfully using gyros alone for up to a minute before the drift proves too substantial.

With regard to the temperature considerations, I'm not convinced that they're a big factor in my difficulties right now: To cope with long-term (i.e. over the course of the day) temperature variations I'm having the PIC average null values from the gyro over a period of a few seconds when it's turned on to get a value null value for the gyro. The area where I'm doing this has a pretty constant temperature, and I think this is a reasonable short-term solution to the temperature issue.

One huge complication is that is very hard to get a handle on what the problems are - I can output my calculated angles to an LCD, and sometimes they seem reasonable, but once the robot's turned on I can't tell what it thinks 'up' is at a given moment, so it's tough to tell if it's the measurement of angle that's messing things up or the balancing algorithm.

It's occurred to me that the best strategy might be to build a mechanism to let the IMU rotate through an angle, along with a pot to give an absolute measurement. I could have this pump data serially via a pic to my PC so I can plot true angle against measured angle, and get a handle on how big the errors are and on how things like measurement rate, rate of rotation etc affect things.

With that in mind can anyone suggest a program that would allow me to easily record and plot this data?

And what's the consensus on the gyro - would I be better off with a different device?

Thanks again for all the input.