ADXL 345 - How to get output in Gs?

I have a question regarding scaling the output to get it in units of Gs. For the +/- 2G range, the min and max output values are -512 and 511 respectively. If you want to map -512 to a value of -2G and 511 to a value of 2G, you must use the following equation G_Value = 4/1023*output_Value + 2/1023. You can check this and verify that it works. This equation will map the max and min values to 2G and -2G exactly, but has several problems. First, in addition to multiplying the output by a value, you must add an offset value. I don't know anything about this converting process really but I don't think this is right. Second, it cannot represent 0.

The data sheet lists a value of 3.9 mg/LSB as the multiplicative factor to use. This maps as follows -512- -> -1.9968; 511 -> 1.9929. So the values aren't exact, but pretty close. This has the added benefit of being able to represent the value zero. It is impossible in binary to exactly represent the end values of a range that is symmetric about 0 and exactly represent 0, at least I think so. I think this is the right way to do this. I found an ADXL library that someone had written and they had gain values written in, but I cannot tell where they came from. (here: Additionally, they are different for each axis. Why would this be? They are all close to 3.9mg. The data sheet also says that the factor can range from 3.5-4.3 mg. 3.9 is only the typical value. If there is some variability here, how can you find how to adjust this for your own sensor?

I also read on another site that someone calibrated their ADXL345. They mentioned that they removed bias values. Do I need to calibrate it? If so, how? Is it a matter of just finding the appropriate factor to multiply by in the data sheet's specified range, or do I also have to remove a bias?

You cannot expect better than about 1% accuracy from a consumer-grade sensor, so even after calibration and scaling "1 g" can result in a measurement between 0.99 and 1.01 g, roughly speaking. Furthermore, the gains and offsets along the three axes are usually a bit different, which you can easily verify by simply orienting the sensor along each axis, up or down, to get six different readings. Note also that the axes perpendicular to the "down" direction usually do not read 0, indicative of an offset to be corrected.

For best performance, each sensor has to be individually recalibrated with an individual gain and offset for each axis, so that each axis reads the same number (+/-) when pointed directly up or down. There is lots of info on the web about how to do this, but my favorite procedure is this: Sailboat Instruments: Improved magnetometer calibration (Part 1) (designed for magnetometers, but it works just as well for accelerometers if the sensor is held still for each measurement).

There are several aspects to calibration. The peak value should be the same in each direction. The zero value should be zero. The three directions should have the same scale. I use a spherical harmonic model to correct the measured value in each axis.