# Choosing an accelerometer

I would like some help in choosing the right accelerometer for my application. I have been looking at a lot of accelerometers from various major manufacturers and have done some testing on one of the accelerometers to get the required result. Basically, I am looking for an accelerometer that would give me an accuracy of a maximum of about 0.5 degrees over the whole 360 degree cycle. The sensitivity of various accelerometers is usually given in 100's mV/g etc, but could anyone tell me as to how do I get the accuracy out of this? I have all the datasheets of the various accelerometers but I am unable to understand as to how do I relate the accuracy to the sensitivity or do I look for something else in the datasheet.

Main idea: Yeah, I need to use an accelerometer. Basically, I have rotation sensors to measure an angle via these accelerometers and have a system using four of these sensors together requiring an overall system accuracy of 1%. Taking that into account, I am looking for achieving an accuracy of 0.5 degrees on each sensor/accelerometer so that the overall accuracy remains below 1%.

The accelerometer that I have used earlier is: MMA8451Q and the accuracy that I got with it went up to about 2.5 degrees at 90 and 270 degree angles. It had a sensitivity of 4096 counts/g. Since this was not good enough, I have started looking at other options that would provide me with the required accuracy. Any suggestions?

• Those are pretty hard requirements. What do you want to achieve? Do you really need to use an accelerometer?
– suha
Jun 6, 2012 at 14:18
• Yeah, I need to use an accelerometer. Basically, we have rotation sensors to measure an angle via these accelerometers and we have a system using four of these sensors together requiring an overall system accuracy of 1%. Taking that into account, we are looking for achieving an accuracy of 0.5 degrees on each sensor/accelerometer so that the overall accuracy remains below 1%. Jun 6, 2012 at 14:44
• @The Newbie Of what are you measuring rotation? Are you 100% sure that you can't use something else which can be more precise? Maybe some sort of optical recognition? Jun 6, 2012 at 14:51
• Oh I am just using the accelerometer for inclination sensing. Jun 6, 2012 at 15:04
• You might want to read starlino.com/imu_guide.html Jun 6, 2012 at 19:52

Ignore what stevenvh says in his first paragraph. It's the wrong way to solve the problem. He is measuring cos(angle), which he rightly says is basically useless.

stevenvh has now fixed his first paragraph.

To measure inclination with an accelerometer, you must measure the horizontal acceleration, so that a positive inclination gives a positive acceleration reading, and a negative inclination gives a negative acceleration reading. Now your reading is proportional to sin(angle). Taking this ADXL device as an example. When it's lying flat on the table, the Z axis reads 1g, while X and Y both read 0g. If you rotate it 0.5º about the Y axis, then the Z axis reading will hardly change, but the X axis reading will change noticeably.

Assume we have an accelerometer with sensitivity of ±1g, with a 12-bit output, giving a range of -2048..2047.

At 0º then, we measure 0g, and get an ADC output of 0. At 0.5º we measure sin(0.5)g = 0.0087g. Which will give us an ADC output of 0.0087*2047 = 17.

Therefore, you should be able to measure the first 0.5º from level with a ±1g accelerometer and a 12-bit ADC, as long as you calibrate it properly.

The problem is that your accuracy drops as you rotate away from level. This is where a second accelerometer comes in. To deal with a full 360º rotation, you must use two orthogonal accelerometers. (E.G. a 2-axis device).

Use the signal from each one to calculate the angle, then take the weighted average of those angles, each weighted by the amplitude of the signal of the other one.

float Angle_radians(float x, float y) const
{
float angle;

if (fabs(x)>fabs(y))
{
angle = atan(y/x);
if (x<0.0f) angle += PI;
}
else
{
angle = PI*0.5f - (float)atan(x/y);
if (y<0.0f) angle += PI;
}
if (angle < 0.0f) angle += PI*2;
if (angle > PI*2) angle -= PI*2;

return angle;
}

x_acc *= 1.0 / 2047;         // scale to range -1 .. +1
y_acc *= 1.0 / 2047;



Added: As markrages mentioned, there's usually also a function called atan2(), which does exactly this:

angle = atan2(x_acc, y_acc);


So, basically by using a dual/triple axis accelerometer there are better chances of getting the correct accuracy with averaging and filtering?

No, I'm saying that to get an accurate reading across the whole 360º range, you have to use two axes. One axis will go from maximum accuracy at 0º to zero accuracy at 90º. The other axis will do the opposite.

Could you please show me one example of an accuracy calculation for the datasheet attached?

Your part is the MMA8451Q, which contains a 14-bit ADC, is available in a 2g version, giving 4096 counts/g. This is twice the resolution of my example above. However, accuracy is not all about resolution. You also need to take into account the Zero-g offset. When your device is flat on the table, one axis should read exactly zero, but it won't. There will be a slight offset. According to the datasheet, this can be as much as ±30mg. This is equivalent to an angle error of 1.7º! You will need to account for this offset error. You do this by calibration.

Take a thickish plate of glass or polished granite, and place a large ball bearing on it. Adjust the angle of the glass until the bearing doesn't roll any more. This is pretty level now.

Place your device flat on the glass, and take note of the reading from the horizontal sensors. They will give readings close to zero. You can now load these readings into the device, and it will subtract them from its own readings. One last question is noise. The sensor readings won't be perfectly stable. With the device stationary, the readings will probably fluctuate very slightly. You can reduce the noise by taking multiple sensor readings (16 maybe), and averaging them. Of course, this reduces the your real sensor update rate.

See Guy NXT door for a good article about accelerometer calibration and sensor noise.

• Why not use atan2()? Jun 6, 2012 at 17:27
• @markrages - You could use atan2(). Jun 6, 2012 at 17:32
• @markrages - managed to dig out some old vector to angle code. Hopefully it works. Jun 6, 2012 at 17:39
• You posted your own version of atan2() but it relies on atan(). In most systems where atan() is available atan2() is also available. Jun 6, 2012 at 18:18
• @markrages - Oh, I didn't know it was available in C. Oops. Well, I'll leave it as it is, because it shows the internal workings. Jun 6, 2012 at 19:38

Most accelerometers have at least 2 axes. Below 45° the cosine varies less than the sine, above 45° it's the other way around. At 0° inclination the horizontal sensor will give a 0 G reading, that's the sine. The vertical one will give you the cosine of the inclination angle. A 0.5° rotation can best be read on the horizontal sensor. The worst case resolution-wise is at 45°. Sin(45°)=0.707, sin(45.5°)=0.713. That's a difference of 0.006. 8 bits resolution give you an LSB of 0.004, so that should be enough. Most digital sensors have a much higher resolution. (thanks, Rocketmagnet).

That's for accelerometers with digital output. Devices with analog output have an in principle infinite resolution, however. (Note that I count PWM output accelerometers also as analog.) While digital has the advantage of a unambiguous reading (15 is 15 and nothing else), analog isn't that clear. The actual precision you can obtain depends on numerous factors, like noise and non-linearity. Noise can be taken care of by averaging over a couple hundred samples (if you have the time for that), non-linearity by calibrating at several angles.

edit
Rocketmagnet has a point, and you can exploit it further. You don't need a second sensor for when your angle becomes larger than 45°. Like I said, most acceleration sensors are at least 2-axis, and a single device will typically have an alignment error of 0.01°. You can't position two separate parts that accurately on a PCB. Since you have two sensors in one package, use them both and average them.

"Oh I am just using the accelerometer for inclination sensing."

Just thinking of alternatives. How about an absolute rotary encoder? Append a weight on it and mount it so that it can rotate with as little friction as possible. A 10 bit encoder gives you a 0.35° resolution. • Instead of the full 360 degree cycle, is there an option for a 0 to +-90 degree option with a 0.5 degree accuracy? Jun 6, 2012 at 14:51
• @TheNewbie - For non-linearity errors that would mean less calibration points. But for noise for instance, if you try to get that decimal right at 38.x° it doesn't matter if it's a 90° or 360° device. Jun 6, 2012 at 15:02
• -1 because of the first paragraph. See my answer. Jun 6, 2012 at 17:14
• Downvote me for what? I fully explained how the OP should use measurements from two axes. Also, you have not corrected the first paragraph. Jun 6, 2012 at 17:24