# Accelerometer Calculation Question

June 11, 2009

I've been playing with a IMU board(ADXL320/ADXRS401 IMU datasheet) from sparkfun.com. This consists of both a gyroscope, ADXRS401 and a Accelerometer, ADXL320. So far I've been playing with the accelerometer readings, trying to understand how to use it for measuring tilt etc.

The accelerometer will output analog volt values based on the orientation of the x and y axis of the board. For example if we look at the Y-axis it will output, according to the datasheet, 2.5V when laying flat on a table - perpendicular to the earth's surface. The output will change 312mV/g change. Lets say we'd like to figure out the angle of the y-axis at a given voltage. We should be able to calculate g of a tilt based on the voltage change, and angle based on g. It's easiest to explain this by doing an example, but first some constants

- Zero(0) g of the y-axis is equal to 2.41V on my board according to the measurments i did with a multimeter during testing.
- Acceleration is 312mV/g.

So if we say that y-axis returns 2.61V and we'd like to find the degree for that volt. We remember our zero g point and calculations go like this:

`2.61 - 2.41 = 0.2+ volt`

proportional to zero g.

Now we can calculate g based on those numbers since we know that acceleration is 312mV/g at 5v:

`0.2 / 0.312 = 0.641g`

Since we have found g we can now figure out the angle using this formula:

` sin^(-1)(0.641) = 0.6958 radians `

All that is left is to convert radians into an angle.

`(180 / PI) * radian = 39.8 degrees`

These calculations look fine at first, but there are a few flaws. One, I use volts to do the calculation. The y-axis readings is returned as a ADC value of 10-bits(0-1024) to my Arduino board. This means we first have to convert that back to volt. Secondly, and more important, The results are not that good. Whenever the device tilts over 80 degrees it returns just 0.00. for example. Also the results vary abit, but i guess that should be possible fix with adding something to reduce the noise on the +5v input and output. What I'm looking for is a better way to do the calculations/ or some tips & tricks on this kind of device.

Btw, my Arduino C code looks something like this:

` float volt = (y/1023.0) * 5; // y is the ADC value from analogRead(). *5 is 5volt`

float ydiff = volt - zeroG; // zeroG is constant of 2.41

float yg = ydiff/0.312;

float radian = asin(yg);

float degree = (180 / PI) * radian;

o/

## There's probably something

There's probably something of a non-linearity and eventual dead-band as you approach 80° and over which is giving you those useless 0V readings. If the accelerometer unit is rotating about the Z-axis only, and not the X-axis, you could use the X-axis accelerometer as well and combine the data. Depending on whether the X-axis voltage increases or decreases you'd know whether you were tilting in the positive or negative Z angle direction. Also, if you run the X-axis voltage through a similar trig. calculation you can average the two angles you get from the X and Y-axis sensors, which would give you a more accurate result (unless one of the sensors was way out). Additionally when one of the sensors was close to being perpendicular with g, you could selectively ignore the other sensor, since you know the reading around that point are unreliable.

Most of the above depends on the rotation being restricted to only occur around the Z-axis (ignoring the Y-axis that is, not like it matters with the g vector aligned along it). If the rotation of the sensor is happening in both X and Z-axis directions you can still get useful info out of the combined sensors, since if the Y-axis sensor detects a larger anglular displacement you know that it is due to X-axis rotation. Once again you can combine the data through a trig. relationship to determine the Z-axis rotation from X and Y-axis data, even though you don't have a Z-axis sensor explicitly.

At some point it's probably worth comverting your equations to run in pure digital form to save on rounding errors. All you need to do is establish the digital 'no-rotation' values and the value of your LSB. Then instead of 'volt - zeroG' you can just take the unchanged sensor input and subtract the raw zeroG value, then divide by the LSB to get your 'yg' value.

2