IMU 6DOF Questions

Hey guys,

I just got my 6DOF board in (http://www.sparkfun.com/products/10121) and I’m having some issues working with the values. Is there a simple way to do this? I’ve been trying to follow the code here: http://www.varesano.net/blog/fabio/my-f … processing, but I’m having a hard time telling which is X, Y, Z on each of the sensors. I’m trying to map the accelerometer values to -127-128, but the values it shows keep changing. I’m trying to build a mouse using this board, and it’s entirely too sensitive at the moment. Any help would be greatly appreciated.

Thanks!

The most straight forward way is to look at the board and note the chips’ orientations. Then look at each chip datasheet - it will tell you how x/y/z align with the chip package.

Thanks for the response! One last question then: what units are the data measured in? I’d like to convert the gyro units into degrees and the accelerometer units into inches or meters if possible. I tried looking at the datasheet but had no luck - they seem to have the units, but I feel like those units don’t make sense with the readings I get when I use it, as they seem much too high. Thanks!

From the gyro’s datasheet …

Digital-output X-, Y-, and Z-Axis angular rate sensors (gyros) on one integrated circuit with a sensitivity of 14.375 LSBs per °/sec and a full-scale range of ±2000°/sec.

So the scale factor is 1/14.375 or about 0.07 deg/sec per LSB.

The accelerometer is a tad more confusing as you can have either a varying resolution or a fixed 10 bits of resolution, which in turn means the LSB has value that varies with the full scale range choosen. The value of the LSB can vary from 3.9 mG/LSB with +/- 2Gs FSR to 31.2 mG/LSB with +/- 16Gs FSR. If you choose to have the resolution vary from 10-13 bits then the LSB is always worth 3.9 mG. Take care to know how you’ve set the justify bit so as to know which bit in the 2 bytes read in is the LSB.

I’m not much of a science guy - I wish I was, but alas, it’s not for me. I’m having a hard time making sense of that. What do you mean by LSB?

I think I’m using ±8 resolution, based on the code in the link I posted above; there’s a left bit shift in the function where I’m reading the sensor data that shifts the data 8 bits.

Don’t get me wrong, I really, greatly appreciate your post. I just don’t get how to use that data to get a measurement like inches or regular degrees.

gehrc:
I’m not much of a science guy - I wish I was, but alas, it’s not for me. I’m having a hard time making sense of that. What do you mean by LSB?

I think I’m using ±8 resolution, based on the code in the link I posted above; there’s a left bit shift in the function where I’m reading the sensor data that shifts the data 8 bits.

Don’t get me wrong, I really, greatly appreciate your post. I just don’t get how to use that data to get a measurement like inches or regular degrees.

LSB is shorthand for Least Significant Bit. The scale factors above are what you’d multiply the readings by to convert them from counts to degrees/second or G’s (where 1G = ~32.2 feet/sec/sec). But I think you have a bigger problem. A gyro measures rotational rate, deg/sec, not rotational position, deg. Accelerometers measure acceleration, how fast the speed of something is changing, not the distance something has travelled**. You won’t get degrees or inches/feet from reading such devices. You’ll need to perform an operation known as integration on the values read from these devices to get those units. I suspect you don’t have the background needed for me to easily explain that operation to you. Maybe I can look at the link you posted but perhaps you can look at the code and see what parts you understand and what parts you don’t.

**So you may well be thinking, “Hey my board is just sitting there, not moving, let alone accelerating. Why is it reporting something nonzero ?” Well to get a little bit sciencey on you recall Mr Newton said F=mA where F is a force and A is an acceleration. These type of accelerometers measure acceleration by sensing the force applied to them and, just a gravity exerts a force on you to hold you to the ground, gravity is exerting a force on your IMU board even as it just sits there. It’s that force that’s being measured and reported by the IMU.

gehrc:
I think I’m using ±8 resolution, based on the code in the link I posted above; there’s a left bit shift in the function where I’m reading the sensor data that shifts the data 8 bits.

Both devices, the gyro and accelerometer, output their data in 2 bytes for each axis. My guess is the code you’re looking at combines those 2 bytes by taking the Most Significant Byte, left shifting it 8 bits and then adding the Least Significant Byte to that result. This reults in a 16 bit word that has the reading in it. You would then multiply that word by the aforementioned scale factors to get deg/sec or G’s.

{1G is one “gravity unit”, the amount of force exerted by the Earth’s gravity. A milliG, mG, is 1/1000th of 1G}

The only code I really has a question on was the following:

result[0] = (((int)buff[1]) << 8) | buff[0];

result[1] = (((int)buff[3])<< 8) | buff[2];

result[2] = (((int)buff[5]) << 8) | buff[4];

Which is where the program gets the data. I can use it properly because my project is working, this is just the only place where I’m not sure what exactly is happening (other than shifting buff to the left 8 bits).

Surprisingly, I do know how to do integrals (I forgot about those, it’s been a while), so I need to figure out how to write that code into my sketch now. Thanks so much for all your awesome help!!

That code is doing what I described above, taking 2 bytes and (re)combining them into a single 16 bit word.

I’m not sure why your “mouse” is too sensitive, other than I don’t think the code was to make a mouse per se but rather a pointing system that tracks what the IMU is doing … and in that regard the less lag between the PC reconstruction and the IMU motion, the better. What are you doing to convert the tracking system into a “mouse” ?

It looks like you’re making progress. A couple of thoughts.

Integrating the accelerometer or gyro data will probably not get you what you want because of measurement and sampling errors. They tend to accumulate (often called drift). One source of this is DC bias which you can offset but you have to figure out what it is. You can set up your IMU position so it maximizes a given axis. best to do that in a small swivel base vise or something similar. That should represent 1G and you can figure out exactly what value it should be (from the datasheet). The reality vs theory is your offset. repeat for the other 2 channels. Unfortunately, it’s not that simple because accelerometers are usually pretty noisy so you will need to do some pretty heavy filtering. I use a simple IIR filter

val = f*raw_val + (1-f)*val

where f is in the range 0…1 (yes, floating point). In other words most of the current value is based on previous samples. I do this in Processing on my PC.

By the way, your “sensitive” point may be related to noise. I have one accelerometer (Kionix) that is super noisy(~5 LSBs) and takes a lot of filtering. An f of .05 calms it down but that means I need to have a pretty high sample rate for it to be responsive to movement. The higher the sample rate, the more the noise. sigh… such is engineering.

Okay cool, thanks!. I actually fixed the sensitivity issue. I have two functions: one evaluates the Y value, the other the X. Essentially, I have a local variable in each that assumes the current value of the axis, then it adds the difference between the current value and the value the sensor is currently reading. Afterwards it divides that by 5, which seems to have solved the sensitivity. I found a firmware that makes the computer think the Arduino is a mouse, so the output is seen as the coordinates. So I’ve had that all working perfectly so far, but now I wanted to incorporate the gyroscope. I’m going to keep working with this and see if I can achieve the result I was going for. Is the IIR (acronym?) filter you mentioned supposed to prevent the noise or fix the drift? Or were you referring to the same thing there?

Thanks so much!

It is used to filter out the higher frequency components - in this case, noise. IIR stands for infinite impulse response. Wikipedia has a nice treatment of it http://en.wikipedia.org/wiki/Infinite_impulse_response. In general, an IMU is going to be a lot about filtering.

Have you looked at FreeIMU?

Never heard of it, but after a Google I realized the person who made it is the one that I got the code to read from my sensor lol. What does it do?

http://www.varesano.net/topic/freeimu

Originally it was an IMU board and sw to drive. He’s hacked in support for several IMUs from sparkfun including, I think, the one you have. I’ve seen videos of him demonstrating some PC SW talking to the board so that might be interesting.

Oh awesome! Does it handle those issues you mentioned, or does it just make it easier to read the data from the board. It does indeed support the board I have, so I’ll probably end up implementing it. Thanks for posting this!

sorry, you’ve reach the limit of my understanding on his stuff.

gehrc:
Oh awesome! Does it handle those issues you mentioned, or does it just make it easier to read the data from the board. It does indeed support the board I have, so I’ll probably end up implementing it. Thanks for posting this!

From what I can tell from another thread here, the FreeIMU software is an outgrowth of the 6DOF software you linked to in the OP. The same guy did both. The main difference (that I can see) is that the newer software incorporates a 3 axis magnetometer with the accelerometer and gyro (so it’s a 9DOF). Now it may do other good things relative to filtering and use of the 6DOF components, I don’t know. I don’t know what happens if you try to use FreeIMU with only a 6DOF set of sensors. :?:

http://www.varesano.net/blog/fabio/init … -hmc5843-a

BTW if you read the above you’ll find reference to Sebastian Madgwick, who has a number of informative posts here re: IMU usage.

But to my thinking all of the software above makes a [AHRS not a “mouse”. I’m not sure if I’ve understood what you’ve done so far but I think it’s using the accelerometer as a tilt sensor and using the amount of tilt in the X and Y directions as X and Y cursor positions. I would think that using an AHRS to get tilt/attitude would open you up to the cursor position drifting as a result of gyro biases. Perhaps after calibration this effect is small enough not to matter and the rate smoothing the gyros can give you help tame and accelerometer noise. Got me there.](Attitude and heading reference system - Wikipedia)

FreeIMU software is an outgrowth of the 6DOF software you linked to in the OP

No it’s not. The FreeIMU library uses a completely different algorithm than the one used in the 6DOF post. FreeIMU library implement a complete AHRS filter including other handy functions for quaternions/angles translations and communication helpers. The 6DOF post instead only computes attitude (pitch and roll) by fusing gyro and acc. The algorithms are very different.

Yes, the FreeIMU library only helps you in finding the yaw pitch roll angles, then translating into mouse movement is your job.

I do have a prototype of this, written in python. See attached files (pretty old code - can’t remember if it’s still compatible with the current library… but should serve as reference pretty well).