In this post I will show how to convert the raw values read from an accelerometer to ‘Gs’.
Git repository here
The code can be pulled down to your Raspberry Pi with;
pi@raspberrypi ~ $ git clone https://github.com/ozzmaker/BerryIMU.git
The code for this guide can be found under the python-BerryIMU-measure-G directory.
An accelerometer measures proper acceleration, which is the acceleration it experiences relative to freefall. This is most commonly called “G-Force” (G)
For example, an accelerometer at resting on a table would measure 1G ( 9.81 m/s2) straight upwards. By contrast, accelerometers in free fall and accelerating due to the gravity of Earth will measure zero.
The accelerometer used by the BerryIMU is a MEMS sensors(LSM9DS0), which outputs the raw readings as mg/LSB.
Most MEMS accelerometers use this output format.
mg = milli-G’s (just like milliliters)
1mG = 0.001 G’s of acceleration, so 1000mG = 1G.
LSB = Least Significant bit, which is the last bit on the right.

The LSM9DS0 outputs a 16 bit value for the accelerometer readings.
If you look at the characteristics of the LSM9DS0 in the datasheet, you can see the sensitivity levels for the accelerometer highlighted in red below and the corresponding values for the LSB, which are highlighted in blue. You can download the datasheet here;
The raw values from the accelerometer are multiplied by the sensitive level to get the value in G.

Let’s use FS ±2 g as an example sensitivity level. As the range is -2 to +2, this would be a total of 4g. Or 4,000 Milli-Gs.
The output is 16 bits. 16 bits equals 65,535. This means we can get 65,535 different readings for the range between -2 and +2. (or -2,000 MilliGs and +2,000 MilliGs)
4,000 MilliGs / 65,535 = 0.061
Each time the LSB changes by one, the value changes by 0.061, which is the value highlighted in blue in the table above.
For FS ±8 g, the range would be -8 to +8, which is a total of 16,000 MilliGs.
16,000 MilliGs / 65,535 = 0.244
Example when using ±2g sensitivity
In the table below, every time the raw values increments by one, the final calculated value(which is MilliG) increments by 0.061
RAW BINARY LSB value for +/-2G Calc MilliG
16 10000 0.061 0.976
17 10001 0.061 1.037
18 10010 0.061 1.098
The above values of 16,17 and 18 above a very low and only used for illustration.
If your accelerometer is horizontal and resting and at rest when using a sensitive level of ±2g, the raw value for Z should hover around 16,500.
16,500 X 0.061 = 1006 MilliGs or 1G
Example when using ±8g sensitivity
In the table below, every time the raw values increments by one, the final calculated value(which is MilliG) increments by 0.244
RAW BINARY LSB value for +/-2G Calc MilliG
16 10000 0.244 3.904
17 10001 0.244 4.148
18 10010 0.244 4.392
If you accelerometer is horizontal and at rest, when using a sensitive level of ±8g, the raw value for Z should hover around 4,475.
4,175 X 0.244 = 1018.7 MilliGs or 1G
The Code
The two above examples are easy to implement in python;
±8g Sensitivity
writeACC(CTRL_REG2_XM, 0b00010000) #+/- 8G full scale
print("G Value for Z axis %f G" % ((ACCz * 0.244)/1000))
The first line above is used to initialise the accelerometer with a sensitivity level of ±2g.
The second line prints the calculated value as G using the raw values from the accelerometer.
±2g Sensitivity
writeACC(CTRL_REG2_XM, 0b00000000) #+/- 2G full scale
print("G Value for Z axis %f G" % ((ACCz * 0.061)/1000))
The first line above is used to initialise the accelerometer with a sensitivity level of ±2g.
The second line prints the calculated value as G uses using raw values from the accelerometer.
Below is a snippet from the main program;
import smbus
import time
import math
from LSM9DS0 import *
import datetime
bus = smbus.SMBus(1)
def writeACC(register,value):
bus.write_byte_data(ACC_ADDRESS , register, value)
return -1
def readACCx():
acc_l = bus.read_byte_data(ACC_ADDRESS, OUT_X_L_A)
acc_h = bus.read_byte_data(ACC_ADDRESS, OUT_X_H_A)
acc_combined = (acc_l | acc_h <<8)
return acc_combined if acc_combined < 32768 else acc_combined - 65536
def readACCy():
acc_l = bus.read_byte_data(ACC_ADDRESS, OUT_Y_L_A)
acc_h = bus.read_byte_data(ACC_ADDRESS, OUT_Y_H_A)
acc_combined = (acc_l | acc_h <<8)
return acc_combined if acc_combined < 32768 else acc_combined - 65536
def readACCz():
acc_l = bus.read_byte_data(ACC_ADDRESS, OUT_Z_L_A)
acc_h = bus.read_byte_data(ACC_ADDRESS, OUT_Z_H_A)
acc_combined = (acc_l | acc_h <<8)
return acc_combined if acc_combined < 32768 else acc_combined - 65536
#initialise the accelerometer
writeACC(CTRL_REG1_XM, 0b01100111) #z,y,x axis enabled, continuos update, 100Hz data rate
writeACC(CTRL_REG2_XM, 0b00011000) #+/- 8G full scale
while True:
#Read the accelerometer,gyroscope and magnetometer values
ACCx = readACCx()
ACCy = readACCy()
ACCz = readACCz()
print("##### X = %f G #####" % ((ACCx * 0.244)/1000)),
print(" Y = %fG #####" % ((ACCy * 0.244)/1000)),
print(" Z = %fG #####" % ((ACCz * 0.244)/1000))
#slow program down a bit, makes the output more readable
time.sleep(0.03)
Guides and Tutorials