This guide is intended to everyone interested in in using Accelerometers and Gyroscopes as well as combination IMU devices (Inertial Measurement Unit) in their electronics projects

We'll cover:

- What does an accelerometer measure?
- What does a gyroscope (aka gyro) measure?
- How to convert analog-to-digital (ADC) readings that you get from these sensor to physical units (those would be g for accelerometer, deg/s for gyroscope)
- How to combine accelerometer and gyroscope readings in order to obtain accurate information about the inclination of your device relative to the ground plane

Throughout the article I will try to keep the math to the minimum. If you know what Sine/Cosine/Tangent are then you should be able to understand and use these ideas in your project no matter what platform you're using: Arduino, Propeller, Basic Stamp, Atmel chips, Microchip PIC, etc.

There are people out there who believe that you need complex math in order to make use of an IMU unit (complex FIR or IIR filters such as Kalman filters, Parks-McClellan filters, etc). You can research all those and achieve wonderful but complex results. My way of explaining things require just basic math. I am a great believer in simplicity. I think a system that is simple is easier to control and monitor, besides many embedded devices do not have the power and resources to implement complex algorithms requiring matrix calculations.

I'll use as an example a new IMU unit, the Acc_Gyro Accelerometer + Gyro IMU. We'll use parameters of this device in our examples below. This unit is a good device to start with because it consists of 2 devices:

- LIS331AL (data sheet) - a triaxial 2G accelerometer

- LPR550AL (data sheet) - a dual-axis pitch and roll, 500 deg/sec gyroscope

Together they represent a 5-Degrees of Freedom Inertial Measurement Unit. Now that's a fancy name! Nevertheless, behind the fancy name is a very useful combination device that we'll cover and explain in detail in this guide.

To understand this unit we'll start with the accelerometer. When thinking about accelerometers it is often useful to image a box in shape of a cube with a ball inside it. You may imagine something else like a cookie or a donut , but I'll imagine a ball:

If we take this box in a place with no gravitation fields or for that matter with no other fields that might affect the ball's position - the ball will simply float in the middle of the box. You can imagine the box is in outer-space far-far away from any cosmic bodies, or if such a place is hard to find imagine at least a space craft orbiting around the planet where everything is in weightless state . From the picture above you can see that we assign to each axis a pair of walls (we removed the wall Y+ so we can look inside the box). Imagine that each wall is pressure sensitive. If we move suddenly the box to the left (we accelerate it with acceleration 1g = 9.8m/s^2), the ball will hit the wall X-. We then measure the pressure force that the ball applies to the wall and output a value of -1g on the X axis.

Please note that the accelerometer will actually detect a force that is directed in the opposite direction from the acceleration vector. This force is often called Inertial Force or Fictitious Force . One thing you should learn from this is that an accelerometer measures acceleration indirectly through a force that is applied to one of it's walls (according to our model, it might be a spring or something else in real life accelerometers). This force can be caused by the acceleration , but as we'll see in the next example it is not always caused by acceleration.

If we take our model and put it on Earth the ball will fall on the Z- wall and will apply a force of 1g on the bottom wall, as shown in the picture below:

In this case the box isn't moving but we still get a reading of -1g on the Z axis. The pressure that the ball has applied on the wall was caused by a gravitation force. In theory it could be a different type of force - for example, if you imagine that our ball is metallic, placing a magnet next to the box could move the ball so it hits another wall. This was said just to prove that in essence accelerometer measures force not acceleration. It just happens that acceleration causes an inertial force that is captured by the force detection mechanism of the accelerometer.

While this model is not exactly how a MEMS sensor is constructed it is often useful in solving accelerometer related problems. There are actually similar sensors that have metallic balls inside, they are called tilt switches, however they are more primitive and usually they can only tell if the device is inclined within some range or not, not the extent of inclination.

So far we have analyzed the accelerometer output on a single axis and this is all you'll get with a single axis accelerometers. The real value of triaxial accelerometers comes from the fact that they can detect inertial forces on all three axes. Let's go back to our box model, and let's rotate the box 45 degrees to the right. The ball will touch 2 walls now: Z- and X- as shown in the picture below:

The values of 0.71 are not arbitrary, they are actually an approximation for SQRT(1/2). This will become more clear as we introduce our next model for the accelerometer.

In the previous model we have fixed the gravitation force and rotated our imaginary box. In last 2 examples we have analyzed the output in 2 different box positions, while the force vector remained constant. While this was useful in understanding how the accelerometer interacts with outside forces, it is more practical to perform calculations if we fix the coordinate system to the axes of the accelerometer and imagine that the force vector rotates around us.

Please have a look at the model above, I preserved the colors of the axes so you can make a mental transition from the previous model to the new one. Just imagine that each axis in the new model is perpendicular to the respective faces of the box in the previous model. The vector R is the force vector that the accelerometer is measuring (it could be either the gravitation force or the inertial force from the examples above or a combination of both). Rx, Ry, Rz are projection of the R vector on the X,Y,Z axes. Please notice the following relation:

R^2 = Rx^2 + Ry^2 + Rz^2 ** (Eq. 1)**

which is basically the equivalent of the Pythagorean theorem in 3D.

Remember that a little bit earlier I told you that the values of SQRT(1/2) ~ 0.71 are not random. If you plug them in the formula above, after recalling that our gravitation force was 1 g we can verify that:

1^2 = (-SQRT(1/2) )^2 + 0 ^2 + (-SQRT(1/2))^2

simply by substituting R=1, Rx = -SQRT(1/2), Ry = 0 , Rz = -SQRT(1/2) in **Eq.1**

After a long preamble of theory we're getting closer to real life accelerometers. The values Rx, Ry, Rz are actually linearly related to the values that your real-life accelerometer will output and that you can use for performing various calculations.

Before we get there let's talk a little about the way accelerometers will deliver this information to us. Most accelerometers will fall in two categories: digital and analog. Digital accelerometers will give you information using a serial protocol like I2C , SPI or USART, while analog accelerometers will output a voltage level within a predefined range that you have to convert to a digital value using an ADC (analog to digital converter) module. I will not go into much detail about how ADC works, partly because it is such an extensive topic and partly because it is different from one platform to another. Some microcontroller will have a built-in ADC modules some of them will need external components in order to perform the ADC conversions. No matter what type of ADC module you use you'll end up with a value in a certain range. For example a 10-bit ADC module will output a value in the range of 0..1023, note that 1023 = 2^10 -1. A 12-bit ADC module will output a value in the range of 0..4095, note that 4095 = 2^12-1.

Let's move on by considering a simple example, suppose our 10bit ADC module gave us the following values for the three accelerometer channels (axes):

AdcRx = 586

AdcRy = 630

AdcRz = 561

Each ADC module will have a reference voltage, let's assume in our example it is 3.3V. To convert a 10bit adc value to voltage we use the following formula:

VoltsRx = AdcRx * Vref / 1023

A quick note here: that for 8bit ADC the last divider would be 255 = 2 ^ 8 -1 , and for 12bit ADC last divider would be 4095 = 2^12 -1.

Applying this formula to all 3 channels we get:

VoltsRx = 586 * 3.3V / 1023 =~ 1.89V (we round all results to 2 decimal points)

VoltsRy = 630 * 3.3V / 1023 =~ 2.03V

VoltsRz = 561 * 3.3V / 1023 =~ 1.81V

Each accelerometer has a zero-g voltage level, you can find it in specs, this is the voltage that corresponds to 0g. To get a signed voltage value we need to calculate the shift from this level. Let's say our 0g voltage level is VzeroG = 1.65V. We calculate the voltage shifts from zero-g voltage as follows::

DeltaVoltsRx = 1.89V - 1.65V = 0.24V

DeltaVoltsRy = 2.03V - 1.65V = 0.38V

DeltaVoltsRz = 1.81V - 1.65V = 0.16V

We now have our accelerometer readings in Volts , it's still not in g (9.8 m/s^2), to do the final conversion we apply the accelerometer sensitivity, usually expressed in mV/g. Lets say our Sensitivity = 478.5mV/g = 0.4785V/g. Sensitivity values can be found in accelerometer specifications. To get the final force values expressed in g we use the following formula:

Rx = DeltaVoltsRx / Sensitivity

Rx = 0.24V / 0.4785V/g =~ 0.5g

Ry = 0.38V / 0.4785V/g =~ 0.79g

Rz = 0.16V / 0.4785V/g =~ 0.33g

We could of course combine all steps in one formula, but I went through all the steps to make it clear how you go from ADC readings to a force vector component expressed in g.

Rx = (AdcRx * Vref / 1023 - VzeroG) / Sensitivity **(Eq.2**)

Ry = (AdcRy * Vref / 1023 - VzeroG) / Sensitivity

Rz = (AdcRz * Vref / 1023 - VzeroG) / Sensitivity

We now have all 3 components that define our inertial force vector, if the device is not subject to other forces other than gravitation, we can assume this is the direction of our gravitation force vector. If you want to calculate inclination of device relative to the ground you can calculate the angle between this vector and Z axis. If you are also interested in per-axis direction of inclination you can split this result into 2 components: inclination on the X and Y axis that can be calculated as the angle between gravitation vector and X / Y axes. Calculating these angles is more simple than you might think, now that we have calculated the values for Rx,Ry and Rz. Let's go back to our last accelerometer model and do some additional notations:

The angles that we are interested in are the angles between X,Y,Z axes and the force vector R. We'll define these angles as Axr, Ayr, Azr. You can notice from the right-angle triangle formed by R and Rx that:

cos(Axr) = Rx / R , and similarly :

cos(Ayr) = Ry / R

cos(Azr) = Rz / R

We can deduct from **Eq.1** that R = SQRT( Rx^2 + Ry^2 + Rz^2).

We can find now our angles by using arccos() function (the inverse cos() function ):

Axr = arccos(Rx/R)

Ayr = arccos(Ry/R)

Azr = arccos(Rz/R)

We've gone a long way to explain the accelerometer model, just to come up to these formulas. Depending on your applications you might want to use any intermediate formulas that we have derived. We'll also introduce the gyroscope model soon, and we'll see how accelerometer and gyroscope data can be combined to provide even more accurate inclination estimations.

But before we do that let's do some more useful notations:

cosX = cos(Axr) = Rx / R

cosY = cos(Ayr) = Ry / R

cosZ = cos(Azr) = Rz / R

This triplet is often called Direction Cosine , and it basically represents the unit vector (vector with length 1) that has same direction as our R vector. You can easily verify that:

SQRT(cosX^2 + cosY^2 + cosZ^2) = 1

This is a nice property since it absolve us from monitoring the modulus(length) of R vector. Often times if we're just interested in direction of our inertial vector, it makes sense to normalize it's modulus in order to simplify other calculations.

<p>Hi,<br><br>Can the sensor read low values of acceleration less than or a fraction of g? Say 0.2g? Thanks</p>

<p>Whata a great tutorial, I have one question though, what is the meaning of the "T" in the equation:</p><p>Axz(n) = Axz(n-1) + RateAxz(n) * T</p>

<p>thank you so much. You explain problem very clearly.</p>

<p>Very nice explanation.</p>

Great work

<p>Great tutorial.</p>

<p>Very nice. Thank you</p>

<p>Very nice and simple tutorial! Hope I will manage with it well :)</p><p>Thanks!</p>

<p>Hi ! Thanks for this very detailed instructable ! </p><p>But can you tell me how to convert Accelerometer data to Frequency to measure vibration ? is there a way ? </p><p>Regards. </p>

<p>Thank you very much! It helped a lot! :D</p>

<p>thanks for sharing good tutorial</p>

<p>Nice tutorial! i actually came here because i didn't understand why quadricopters use accelerator and why it is related to angle! but anyway, this page only helped me understand but i still wonder why don't they use a gyroscope ? isn't it easier?! whats the problem with that?!</p>

esta bien padre<br>

this info is priceless, great job...<br> 1 question: I am using the Razor 6DOF from sparkfun.com... it is an IMU with a 3 axis accel, an X/Y axis gyro, and a Z axis gyro all on one chip.<br><br>My question is that since all three chips are on the same board (flat), will the gyro work in this configuration or should I get separate accelerometer and gyro, placed at 90 degree angles to make this work?<br><br>here is a link to the board I have:<br>http://www.sparkfun.com/commerce/product_info.php?products_id=10010<br><br>Thanks in advance for any help

Check my guide: <a href="http://arduino.cc/forum/index.php/topic,58048.msg417140.html#msg417140">http://arduino.cc/forum/index.php/topic,58048.msg417140.html#msg417140</a><br> It is based on the Razor 6DOF chip from sparkfun.<br> <br>

<p>Is it possible to do some kind of 3d visualization with just an accelerometer? </p><p>This video shows a real-time model rotating using Qt with a LIS3DH Accelerometer and a Gyro : <iframe allowfullscreen="" frameborder="0" height="281" src="//www.youtube.com/embed/E2vSNgl-yv0" width="500"></iframe></p><p>What visualization can be done with just the LIS2DH alone?</p>

<p>You can properly use something Processing to do that as well.</p>

<p>Would this work with the Kionix accelerometers - the list is at http://www.kionix.com/accelerometers. They seem pretty cheap through DigiKey, and heard good things about them</p>

<p>Would this work with the Kionix accelerometers - the list is at http://www.kionix.com/accelerometers. They seem pretty cheap through DigiKey, and heard good things about them</p>

<p>If using a Digital Accelerometer are the first few steps necessary? Do you still need to incorperate a 0g voltage level? Is that the same as the zero g offset. I don't see a 0g voltage level in the data sheet. Thank you.</p>

<p>This is a so great tutorial and explanation! Thanks you! It makes me have a general picture of accelerator and gyroscope.</p>

<p>Great Job!! Thanks so much for your explanation</p>

<p>thanks for the beauty-full tutorial..it helps me a lot...God bless You</p>

Very nice explanation! Thank you very much. Right now I know how to use an accelerometer correctly.

i have a very basic doubt regarding the device placement of gyro and accelerometer+manganometer. Are they not required to be place on the exact center of PCB to get best performance. Do we compromise performance of devices by placing it offset to center. And is there particular measurement to place gyro and accelerometer apart?

Hello, <br>i am at the very first stage.i am just taking raw values from the accelerometer of GY-85IMU,it uses ADXL345. <br>But the problem is that it is giving me same value on Z-axis in every orientation. <br>This is the code: <br> <br>#include <br>#include <br>#include <br>#include <br>#include <br>#include <br>#include <br>#include <br> <br>//#define DEBUG <br>#include "DebugUtils.h" <br>#include "CommunicationUtils.h" <br>#include "FreeIMU.h" <br>#include <br>#include <br> <br>int raw_values[9]; <br>float conv_values[9]; <br>float ypr[3]; // yaw pitch roll <br>char str[256]; <br>float val[9]; <br>float values[9]; <br> <br>FreeIMU my3IMU = FreeIMU(); <br>//The command from the PC <br>char cmd; <br> <br>void setup() { <br> Serial.begin(115200); <br> Wire.begin(); <br> my3IMU.init(true); <br> <br> // LED <br> pinMode(13, OUTPUT); <br>} <br> <br> <br>void loop() { <br> <br> for(uint16_t i=0; i<500; i++) <br> { <br> my3IMU.getRawValues(raw_values); <br> Serial.print('\n'); <br> Serial.print("RAccX="); Serial.print(raw_values[0]); Serial.print(" "); <br> Serial.print("RAccY="); Serial.print(raw_values[1]); Serial.print(" "); <br> Serial.print("RAccZ="); Serial.print(raw_values[2]); Serial.print(" "); <br> Serial.print('\n'); <br> Serial.print('\n'); <br> <br> } <br> <br> <br>while(1){}; <br>} <br> <br>can u tell me what is the problemm???

i am currently using mote modules MTM-CM5000 and MTM-CM3000 for data transmission and recieving along radio for a accelerometer.Output of my accelerometer can be see on oscilloscope which show me all data including voltage ,humidity,radioactivity etc all in graph form on my pc. MTS-EX1000 is also used for voltage amplification purpose.Except to all of these raw data output i only want to know about how to calculate the frequency that my accelerometer is sensing here. Thankx..

when I looked in the specifications of LIS302DL I found sensitivity = 18mg/digit, 72mg/digit and ZeroG level =? <br>here is the link please if anyone can help me determine the necessary specifications LIS purpose of applying the above formulas <br>""http://www.digikey.com/product-search/en/sensors-transducers/accelerometers/1966355?k=m7"" <br>thinks <br>

Hello <br> I configured the accelerometer LIS302 DL card STM32F4 it shows me results between 0 and 255, and I just need to display the measurements in mm / s ^ 2 for the three axes. <br>I have read the above, I think it can help me a lot but on the voltage I do not know what value I should use. <br>if it can help me to convert the measured values of the different axes, for example (0, 55.230, 245 ...) <br>((it attached a screen printed on running my application)) <br>thank you <br>

Where is the Code OF gyro ?? <br> <br>Plzz

Hi there! I have got one question: I am doing my project in android application which will give altitude, rotational movement to its users, so this information is applicable for me to using at java coding or matlab coding? or any other needed, can you please explain me! Thanks. <br>Moin.

I have a question: If we have a board with a 3-axis (x,y,z) gyroscope and a 2-axis (x,y) accelerometer is there any way to virtualize the z-axis of accelerometer with a mathematical algorithm through software since our board is missing the z-axis accelerometer? Even if it cannot be done precisely, can we estimate a range for z-accel? <br> <br>Thanks a bunch! <br> <br>

thanks for the info, i'm going to use a 5dof imu img500/adxl335, output frm them are analog for balancing my bot sould i have to build an another filter circuit like complementary filter?<br>if so how can we give the change in time rate values in our codes?(dt)<br>help me out with this <br>thank you

You can use a simple RC filter if the outputs are analog from the chip. <br> <br>To find da/dt, sample two value and subtract them. <br>Divide the result by the time passed between the two samples. <br> <br>da/dt = (Sample-1 - Sample-2) / (1 / Sampling-Frequency) <br> <br>You can get rid fo the division by using a factor k same as (1 / Sampling-Frequency). <br> <br>da/dt = (Sample-1 - Sample-2)

Hi guys,<br><br>I will make a project measurin tremor characteristics of parkinson diseased patients. To do this I need to use a sensor that can measure the movements accurately and sensitively. In the beginnin of my research I was ok with using only accelerometer but when I read more, I realized that using both accelerometer and gryo would give much better results. I will be working in arduino. Can anyone suggest me accelerometer and gryo boards to purchase? Shall I purchase acc_gyro imu board? or I shall buy them seperately?<br><br>Thanks in advance..

You can buy a board through Ebay based on "MPU-6050" or "MPU-6000" which is a gyroscope and accelerometer in the same chip. <br> <br>The cross talk is minimal and it is cheaper to buy them in the same package (my thought).

Thank you for the post,it is really interesting. I just have a question. Why should we have to divise each quantity Rx,Ry,Rz by R? What does it mean? <br>My second question is about the force Rx,Ry,Rz. I thought that only tangential forces from the accelerometer had to be add the the angle. Is Rx, Ry,Rz the tangentiel forces??

R is the resultant vector of the three component vectors, Rx, Ry and Rz. <br> <br>R^2 = Rx^2 + Ry^2 + Rz^2 <br>=> R = SQRT(Rx^2 + Ry^2 + Rz^2) <br> <br>You need this division to measure the contribution of a component (Rx, Ry or Rz) to the resultant vector, R. R will incline towards the component having the higher value. If Rx, Ry and Rz have the same lengths (same acceleration in all axes), the resultant vector (R) will point precisely in their middle. <br> <br>Thus to find the angle between Rx, Ry or Rz and R, you need: <br>Axr = arccos(Rx/R) <br>Ayr = arccos(Ry/R) <br>Azr = arccos(Rz/R) <br> <br>Yes, Rx, Ry and Rz are tangential.

Hi, great instructable! <br> <br>I gave a question concerning the angles extracted from the accelerometer: It seems there is a hidden assumptions that the reading of the accelerations will always be done while stationary (or not moving). This is not true to most mobile/airborne applications. <br>In these cases there is also an additional external acceleration (like the acceleration of the car or an aircraft turning in a wide angle) and then the assumption about the total 1g vector size isn't right. <br>What am I missing? <br> <br>Thanks <br>Gabriel

You can always read the "bias" value by keeping the chip static. The datasheet must be providing this value as well. I think, it does not drift that much with time and thus you can always subtract a constant value from the readings. <br> <br>There is no hidden assumption here. If it is static, you will get 0 after the "bias" subtraction.

Guys, <br>can anybody tell me how can i get negative readings for x,y,z, axis from accelerometer ? i mean it show me just + value in x axes or other too. but not -(negative). so how i know if i made opposing motion

Read it above at, "Let's say our 0g voltage level is VzeroG = 1.65V". <br> <br>If your reading is less than the zero-g value, you are accelerating in the negative direction.

Great Explanation . . .

Very helpful! I used this instructable to interpret data for a model airplane autopilot. I would like to add that if you are struggling to convert your accelerometer into degrees you should investigate the atan2() function. <br>somethings like: <br>pitch (in degrees) = atan2[x(in g's),y(in g's)] + pi

Thank you so much for posting this information! It would've had taken me days to figure this stuff out on my own.

Thank u very much !!! it was an awesome piece of informations!!

thanks a lot this really helped me

Fantastic Information. Thank you for dumbing it down to a hobbist level instead of an engineer tech babble.

superb!!!!!!!!!!!<br>

This is a really good instructable! It really contains everything you need to know to start with those sensors. It answered a lot of my questions!<br><br>Thanks