## How to convert accelerometer data into G with the ADXL345 digital accelerometer

71 posts / 0 new
Author
Message

Am totally new to electronics and the datasheet is very confusing to me, so can anyone please guide me through the specification of the accelerometer? So that i can have a better understanding on the accelerometer and to be able to convert the accelerometer data into G.

X-axis Y-axis Z-axis -28 -26 218 These are the readings i get from the accelerometer with a +-2g range

```import smbus
import time

# Get I2C bus
bus = smbus.SMBus(1)

# Select bandwidth rate register, 0x2C(44)
#       0x0A(10)    Normal mode, Output data rate = 100 Hz
bus.write_byte_data(0x53, 0x2C, 0x0A)
# Select power control register, 0x2D(45)
#       0x08(08)    Auto Sleep disable
bus.write_byte_data(0x53, 0x2D, 0x08)
# Select data format register, 0x31(49)
#       0x08(08)    Self test disabled, 4-wire interface
#                   Full resolution, Range = +/-2g
bus.write_byte_data(0x53, 0x31, 0x08)

time.sleep(0.5)

# Read data back from 0x32(50), 2 bytes
# X-Axis LSB, X-Axis MSB

# Convert the data to 10-bits
xAccl = ((data1 & 0x03) * 256) + data0
if xAccl > 511 :
xAccl -= 1024

# Read data back from 0x34(52), 2 bytes
# Y-Axis LSB, Y-Axis MSB

# Convert the data to 10-bits
yAccl = ((data1 & 0x03) * 256) + data0
if yAccl > 511 :
yAccl -= 1024

# Read data back from 0x36(54), 2 bytes
# Z-Axis LSB, Z-Axis MSB

# Convert the data to 10-bits
zAccl = ((data1 & 0x03) * 256) + data0
if zAccl > 511 :
zAccl -= 1024

# Output data to screen
print ("Acceleration in X-Axis : %d" %xAccl)
print ("Acceleration in Y-Axis : %d" %yAccl)
print ("Acceleration in Z-Axis : %d" %zAccl)```

Above are the code used.

This topic has a solution.
Last Edited: Sun. Apr 28, 2019 - 05:51 AM

Multiply result by 4milli g. Assuming 2g scale, 1g ie:gravity will measure around 256 as a raw value. Times 4 milli g gives around 1g. By moving the sensor around you will get a maximum reading of 1g.

Hi Kartman,

First of all, thanks for replying. The above x,y,z axis data was acquired when the accelerometer is stationary and according to the method you provided, 218 * 0.004g = 0.872g. But it isn't close to 1g, am i doing something wrong? Also if i adjust the measurement range to +-4g,+-8g and +-16g do i just simply multiply the data acquire from +-4g,+-8g and +-16g by 0.004 in order to convert them into g?

how manysamples did you try to get the reading of 218? How do you know the sensor was at the right Angle?

I did acquire the data several times and its ranging from 218-221 almost all the time. Also the data was acquired when the accelerometer is stationary.

Based on a limited experience of acelerometer sensors, they don't tend to be particularly well calibrated 'straight out of the box'.

It looks like the sensor gives a signed 10 bit output, so -512 to +511, call it +/- 512.

If it's configured for 2G full scale, then 1g as Kartman said would be a reading of 256.

So a reading of 220 is 220 / 256 = 0.86g.

If it was perfectly level (it proably isn't) and if it was perfectly calibrated (it probably isn't) then you would expect a reading of X = 0, Y=0, Z=1G=256.

Getting around -30 for X and Y (insted of 0) and around 220 (instead of 256) doesn't seem that crazy.

As a simple calibration procedure, you could take the average offset values you are geting with it 'level', then subtract those values from each raw reading to give a 'calibrated' result.

Hi, MrKendo,

First of all, thank you for replying.

Shouldn't 10 bit output (0-1023) how come -512 and +512 why do we have to divide it by 2, can you briefly explain on this? Also, "the average offset values you are getting with it 'level'" which means the above data i acquired?

Because the sensor is specified as having a range of plus 2g to minus 2g.

Ross McKenzie ValuSoft Melbourne Australia

Hi, valusoft,

First of all, thank you.

Ah now i get it. Also if i set the measurement range to +-4g then i need to divide the 1024 by 4 only right?

I have some experience in this area. I sell acceleration loggers ( http://www.ORElectronics.net ) The ones I use are from STMicro but the technology is very similar to that used by Analog Devices, Bosch, and others.

For all of these, the full scale sensitivity is not very precise. Its not only NOT very precise, but there can also be a lot of difference between axes and a lot of variation with temperature. Also, there tends to be a lot of zero offset. About the best that you can do is orient the sensor so that one of the axes is parallel to the gravity vector, take a reading or readings, then turn it over and take a bunch more readings. Average each set to make one "reading" for each. Then you can say that the difference between the two readings is 2.0g and the average of the two is 0g.

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

ckkkkk wrote:
Shouldn't 10 bit output (0-1023) how come -512 and +512

a 10 bit unsigned number covers the range 0 to 1023, but based on the code you posted

```# Convert the data to 10-bits
xAccl = ((data1 & 0x03) * 256) + data0
if xAccl > 511 :
xAccl -= 1024```

it looks like it is easier to think of as a signed number, so it covers the range -512 to +511.

For simplicity I'm just calling it +/- 512.

A difference of 1 doesn't make much difference.

ckkkkk wrote:
Ah now i get it. Also if i set the measurement range to +-4g then i need to divide the 1024 by 4 only right?

I would think of it as, if full scale range was 4G then

-4G would give -512

+4G would give +512 (actually +511)

So  4G = 512

So 1G = 512 / 4 = 128.

ckkkkk wrote:
Also, "the average offset values you are getting with it 'level'" which means the above data i acquired

Yes.

Almost certainly the sensor will not read exactly 0 when in a field of 0G, there will be some offset, which will be different for each sensor due to manufacturing tolerances etc.

(Plus the other sources of error ka7ehk mentioned above).

So if you require more accurate readings, the sensor needs to be calibrated in some way.

Unlike ka7ehk I am not familar with the best ways to perform a calibration.

I was thinking of the most basic method which is to place it on a (reasonably) level surface and take X,Y Z readings to get the offsets.

Not optimal but it might be good enough.

Hi Jim,

Thank for replying and i will try to follow the method you provided to average out the values.

MrKendo wrote:

I would think of it as, if full scale range was 4G then

-4G would give -512

+4G would give +512 (actually +511)

So  4G = 512

So 1G = 512 / 4 = 128.

Oh i just realized that with +-4g measurement range it will be in 11bit resolution but still 2048/4 = 512 and 512/4 = 128 which is still 128 per g.

MrKendo wrote:
Yes.

Almost certainly the sensor will not read exactly 0 when in a field of 0G, there will be some offset, which will be different for each sensor due to manufacturing tolerances etc.

(Plus the other sources of error ka7ehk mentioned above).

So if you require more accurate readings, the sensor needs to be calibrated in some way.

Unlike ka7ehk I am not familar with the best ways to perform a calibration.

I was thinking of the most basic method which is to place it on a (reasonably) level surface and take X,Y Z readings to get the offsets.

Not optimal but it might be good enough.

But all the data was acquired when the accelerometer is stationary and placed on the table, with the method you mentioned wouldn't this makes the data acquired to become the offset? Or the data i acquired is actually offset instead of acceleration data?

Hello ckkkkk -

Please be aware that each axis will have a different full-scale calibration constant and a different zero offset. One axis is usually pretty easy - the axis that is normal to the mounting plane (e.g. circuit board). With some care, you can lay the board on a flat surface for one reading and turn it over for the opposite one. The other two are much harder unless you mount the board in some fixture that will hold it vertical on the four edges.

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

ckkkkk wrote:

Oh i just realized that with +-4g measurement range it will be in 11bit resolution but still 2048/4 = 512 and 512/4 = 128 which is still 128 per g.

You got me hooked now so I had to go and take a look at the datasheet :)

It depends on the FULL_RES Bit.

If that bit is set then +/-4g range wil use 11 bit, in which case you have 1G = 256 still. If that bit is clear then it uses 10bit mode and 1G = 128.

ckkkkk wrote:
But all the data was acquired when the accelerometer is stationary and placed on the table, with the method you mentioned wouldn't this makes the data acquired to become the offset? Or the data i acquired is actually offset instead of acceleration data?

There is a good explanation in the datsheet under OFFSET CALIBRATION.

Basically with this simple method, you assume that X and Y should be in 0g field, so the reading you get is the offset.

You assume that Z should be 1G. You then have to assume that the correct value for 1G is 256 (or whatever). This may not be correct, and is what ka7ehk's method would improve on (I think). But anyway, if you assume that 1G should be 256, but you read 220, then you can say your Zoffset is (220 - 256) = -36.

ka7ehk wrote:

Hello ckkkkk -

Please be aware that each axis will have a different full-scale calibration constant and a different zero offset. One axis is usually pretty easy - the axis that is normal to the mounting plane (e.g. circuit board). With some care, you can lay the board on a flat surface for one reading and turn it over for the opposite one. The other two are much harder unless you mount the board in some fixture that will hold it vertical on the four edges.

Jim

I'll try my best to get all the reading in orientation, but first i think i need to find a nice shaped wooden block and once again thank you for the advice.

MrKendo wrote:

You got me hooked now so I had to go and take a look at the datasheet :)

It depends on the FULL_RES Bit.

If that bit is set then +/-4g range wil use 11 bit, in which case you have 1G = 256 still. If that bit is clear then it uses 10bit mode and 1G = 128.

Once again thank you for all the effort you spent, really appreciate it.

MrKendo wrote:

There is a good explanation in the datsheet under OFFSET CALIBRATION.

Basically with this simple method, you assume that X and Y should be in 0g field, so the reading you get is the offset.

You assume that Z should be 1G. You then have to assume that the correct value for 1G is 256 (or whatever). This may not be correct, and is what ka7ehk's method would improve on (I think). But anyway, if you assume that 1G should be 256, but you read 220, then you can say your Zoffset is (220 - 256) = -36.

Oh so that every of the reading i get next time on all these 3 axis needed to +28,+26 and +36 on x,y and z-axis.

ckkkkk wrote:

Oh so that every of the reading i get next time on all these 3 axis needed to +28,+26 and +36 on x,y and z-axis.

Correct.

You can either think of it as

Xcalibrated = Xraw + Xoffset

or

Xcalibrated = Xraw - Xoffset

depending on which way round you choose to calculate offset (ie. you could think of Xoffset as either +28 or -28).

You just need to get the signs the right way round.

Question
Can i know what is the differences between the Sensitivity at XOUT, YOUT, ZOUT and Scale Factor at XOUT, YOUT, ZOUT under the SENSITIVITY section on page 4 of the datasheet? After i did some searching, this is one of things that i get

`"Sensitivity of the accelerometer, sometimes referred to as the scale factor of the accelerometer, is the ratio of the sensor’s electrical output to mechanical input"`

I also noticed that the value of the Sensitivity at XOUT, YOUT, ZOUT are same as the calculations that we did above. For example, 256 lsb/g for +-2g range, 128 lsb/g for +-4g range. Also, why do we need to include the sensitivity values to the calculation we need to perform above and can we use the scale factor value instead to replace the sensitivity value to perform the conversion?

ckkkkk wrote:
Can i know what is the differences between the Sensitivity at XOUT, YOUT, ZOUT and Scale Factor at XOUT, YOUT, ZOUT under the SENSITIVITY section on page 4 of the datasheet?

It's simply 2 different ways of saying the same thing. One is the inverse of the other (but with a factor of 1000 because of conversion fro g to mg)

sensitivity = 256 LSB/g

scale_factor = 1 / 256 g/LSB = 1000 / 256 mg/LSB

MrKendo wrote:

It's simply 2 different ways of saying the same thing. One is the inverse of the other (but with a factor of 1000 because of conversion fro g to mg)

sensitivity = 256 LSB/g

scale_factor = 1 / 256 g/LSB = 1000 / 256 mg/LSB

Noted, so 2 are with the same meaning with different implementation.

Agree.

If you do the "calibration" that I suggested, then you do not need to know anything about the spec'd full scale value or the spec'd offset.

Please understand that the specifications provide a "typical" value and "limits" for each axis. That typical value is the ideal one. In the best of all worlds, that is how every device would behave. The limits are a recognition that individual devices are not ideal. The limits specify how far from the ideal any individual device can be. These numbers are basically irrelevant when you are doing your own calibration. YOU are determining what the ACTUAL full scale values and the ACTUAL offsets are so that, in the future, you can use those values to convert from the raw reading into something that is close to the true physical value.

Hope this helps

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

I now have gain access back to the accelerometer and i have took 10 measurement readings from it while it's laying flat on the table. It seems that the z - axis readings are from 216,217 and 220 so which 1 do i use to determine the offset value?

Well, you need to do a second step: turn it over and take 3 more measurements. Then, average the first set together, Then average the second set together. One set should have a positive value and the other should have a negative value.

The number of counts for 1g is then the sum of the absolute values of two averages, divided by 2. Call this ZF  (Z full scale)

The number of counts for the zero offset is the sum of the values of the two averages, divided by 2. Call this Z0

Then, for a future measurement, Z, the g value is simply g = (Z - Z0)/ZF. Even better, take several readings, average them, and use that for Z.

Direct parallel on any other axes.

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

You need to flip the accelerometer over the other way and get the negative readings. Say you get +100 and -100. The offset is 0. If you get +110 and -90 then the offset is -10.

Kartman wrote:
You need to flip the accelerometer over the other way and get the negative readings. Say you get +100 and -100. The offset is 0. If you get +110 and -90 then the offset is -10.

Hi Kartman,

I get the accelerometer data by looping it 10 times. Do i need to average the z-axis value then only find the offset? Also +110 and -90 shouldn't the offset = -20 why is it -10 only?

Why -10? 110-10 = 100. -90-10 = -100. We haven't hit trigonometry yet, so you best be revisiting your high school math books.

ka7ehk wrote:

Well, you need to do a second step: turn it over and take 3 more measurements. Then, average the first set together, Then average the second set together. One set should have a positive value and the other should have a negative value.

I am not sure if i fully understand this but below is what i get from the accelerometer laying flat on a wooden block and the data was acquired using a 10 times loop.

```Acceleration in X-Axis : -6
Acceleration in Y-Axis : 6
Acceleration in Z-Axis : 222
Acceleration in X-Axis : -6
Acceleration in Y-Axis : 6
Acceleration in Z-Axis : 222
Acceleration in X-Axis : -7
Acceleration in Y-Axis : 6
Acceleration in Z-Axis : 219
Acceleration in X-Axis : -7
Acceleration in Y-Axis : 6
Acceleration in Z-Axis : 219
Acceleration in X-Axis : -7
Acceleration in Y-Axis : 5
Acceleration in Z-Axis : 218
Acceleration in X-Axis : -7
Acceleration in Y-Axis : 5
Acceleration in Z-Axis : 218
Acceleration in X-Axis : -9
Acceleration in Y-Axis : 6
Acceleration in Z-Axis : 218
Acceleration in X-Axis : -9
Acceleration in Y-Axis : 6
Acceleration in Z-Axis : 218
Acceleration in X-Axis : -12
Acceleration in Y-Axis : 4
Acceleration in Z-Axis : 218
Acceleration in X-Axis : -12
Acceleration in Y-Axis : 4
Acceleration in Z-Axis : 218```

And these are the data acquired from the accelerometer when it's upside down.

Kartman wrote:

Why -10? 110-10 = 100. -90-10 = -100. We haven't hit trigonometry yet, so you best be revisiting your high school math books.

Ok i get it now.

Kartman wrote:
You need to flip the accelerometer over the other way and get the negative readings. Say you get +100 and -100. The offset is 0. If you get +110 and -90 then the offset is -10.

I have averaged up all the readings and get 219 and for upside down it is -263.8. But its +256 and -256, so it be 37 and -7.8 offset?

I am not sure if i fully understand this

OK now flip it over in all 3 dimensions and re-read. For example if I look at just the X from your first readings I see:

```Acceleration in X-Axis : -6
Acceleration in X-Axis : -6
Acceleration in X-Axis : -7
Acceleration in X-Axis : -7
Acceleration in X-Axis : -7
Acceleration in X-Axis : -7
Acceleration in X-Axis : -9
Acceleration in X-Axis : -9
Acceleration in X-Axis : -12
Acceleration in X-Axis : -12
```

So the average of those is -8.2 (add them all up, divide by 10). Now flip over. Take 10 readings, perhaps the average of those is +6.7 ? So the "mid point" is half way between -8.2 and +6.7 which would be -1.5

Last Edited: Fri. Apr 26, 2019 - 10:29 AM

```Acceleration in Z-Axis : 222
Acceleration in Z-Axis : 222
Acceleration in Z-Axis : 219
Acceleration in Z-Axis : 219
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218

-262
-262
-263
-263
-265
-265
-265
-265
-264
-264```

The +ve average is then +219 and the -ve is +263.8. So the midpoint is +44.8

clawson wrote:

```Acceleration in Z-Axis : 222
Acceleration in Z-Axis : 222
Acceleration in Z-Axis : 219
Acceleration in Z-Axis : 219
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218

-262
-262
-263
-263
-265
-265
-265
-265
-264
-264```

The +ve average is then +219 and the -ve is +263.8. So the midpoint is +44.8

According to all these then y reading would be

```6
6
6
6
5
5
6
6
4
4```

```1
1
0
0
-3
-3
1
1
2
2```

+ve = 54 / 10 = 5.4 and -ve = 2 / 10 = 0.2 and the "midpoint" or offset would be 53.8?

Last Edited: Fri. Apr 26, 2019 - 10:50 AM

How do you get 53.8 from that? Halfway between 5.4 and 0.2 is 2.8

ckkkkk wrote:
I have averaged up all the readings and get 219 and for upside down it is -263.8. But its +256 and -256, so it be 37 and -7.8 offset?

The difference is +44.8. Divide this by two. 22.4. Thus: 219 + 22.4 = 241.4 , -263.8 + 22.4 = -241.4. Both side balance. The scale would be 250/241.4 = 1.0356. Uncalibrated the scale is off by around 3%. Does this line up with the datasheet?

clawson wrote:
Uncalibrated the scale is off by around 3%

Hi clawson,

Kartman wrote:

ckkkkk wrote:
I have averaged up all the readings and get 219 and for upside down it is -263.8. But its +256 and -256, so it be 37 and -7.8 offset?

The difference is +44.8. Divide this by two. 22.4. Thus: 219 + 22.4 = 241.4 , -263.8 + 22.4 = -241.4. Both side balance. The scale would be 250/241.4 = 1.0356. Uncalibrated the scale is off by around 3%. Does this line up with the datasheet?

Shouldn't it be 256/241.4 = 0.9415 as 256 represents 1G? But what i am going to do is strap the accelerometer on wrist and the accelerometer will likely be on the same direction for most of the time and based on the method you guys provided, it takes both +- z-axis data in order to calculate the offset and to convert the value in G. Is there any other way that i can get the offset that would be usable for both the +ve and -ve of z-axis?

Last Edited: Fri. Apr 26, 2019 - 12:05 PM

ckkkkk wrote:
Shouldn't it be 256/241.4 = 0.9415 as 256 represents 1G?

Is your calculator dyslexic? I had a read of the datasheet and , yes, the full scale value is noted to be 256 or 3.9mG/lsb. Thus the scale factor would be 256/241.4 = 1.06

Kartman wrote:

ckkkkk wrote:
Shouldn't it be 256/241.4 = 0.9415 as 256 represents 1G?

Is your calculator dyslexic? I had a read of the datasheet and , yes, the full scale value is noted to be 256 or 3.9mG/lsb. Thus the scale factor would be 256/241.4 = 1.06

Oh ya something wrong with that calculator. But still

ckkkkk wrote:
But what i am going to do is strap the accelerometer on wrist and the accelerometer will likely be on the same direction for most of the time and based on the method you guys provided, it takes both +- z-axis data in order to calculate the offset and to convert the value in G. Is there any other way that i can get the offset that would be usable for both the +ve and -ve of z-axis?

It's called ‘calibration’ - you do it once and store the offset and scale values usually in eeprom. For a one off, you might hard code these values into your code. Whilst the calibration drifts with temperature, it is only small. The datasheet says around 0.01% per degreeC.

Besides, why are you concerned with scale and offset? If you want to measure movement and basic orientation, the errors are probably insignificant.

Kartman wrote:
Besides, why are you concerned with scale and offset? If you want to measure movement and basic orientation, the errors are probably insignificant.

I am doing a fall detection system with raspberry pi and the prototype will eventually place on the wrist. Thus, the acceleration is important for me to determine whether or not the fall event happened.

Last Edited: Fri. Apr 26, 2019 - 01:51 PM

Wrong answer. For fall detection you are more interested in the change rather than the absolute values. So again, why do you need to scale and offset? The errors are probably insignificant. I would understand if you were making an inclinometer.

Kartman wrote:
Wrong answer. For fall detection you are more interested in the change rather than the absolute values. So again, why do you need to scale and offset? The errors are probably insignificant. I would understand if you were making an inclinometer.

I did quite a lot of research before this and many suggest that it is best to get 1G on the z-axis and 0G on both the x,y-axis.

```Acceleration in Z-Axis : 222
Acceleration in Z-Axis : 222
Acceleration in Z-Axis : 219
Acceleration in Z-Axis : 219
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218
Acceleration in Z-Axis : 218```

So again if i just take 1 of the value above, lets say 222 for example then i need to multiply 222 with 3.9mg to convert it into G which makes 222*0.0039 = 0.8658 G. Which is not even close to 1G. Thus, i need to know the offset so that i can make the z-axis reading closer to 1G. Or is it just using 1G - 0.8658G = 0.1342G / 256 - 222 = 34 to find the offset for the z-axis?

Last Edited: Fri. Apr 26, 2019 - 03:35 PM

We seem to be going around in circles. We’ve shown you how to calculate the offset and scale. For a given sensor you do this once and make note of the values. You then use these values in subsequent readings. The calculation becomes:
Real value = (raw value - offset) * scale

Getting 0 on the other axes results in chasing your tail. You cannot know what zero on any axis is until you calibrate that axis. Calibrating any axis requires zero on the other two.

And round, and round again. OR, you can iterate through this set of measurements several times to get arbitrarily close.

Because it is a cosine function, the error on the gravity axis due to the other axes NOT being zero is small, as long as those other axes are CLOSE to zero. So, get close and accept it.

In the end, you really don't have a precision sensor to start with, so why all the agony over precision calibration? Even if you do the calibration precisely, you only have 1 part in +/-256 resolution!

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

Last Edited: Fri. Apr 26, 2019 - 10:50 PM

Wait i am quite lost now, where exactly are these again?

Kartman wrote:
We’ve shown you how to calculate the offset and scale. For a given sensor you do this once and make note of the values. You then use these values in subsequent readings. The calculation becomes: Real value = (raw value - offset) * scale

ka7ehk wrote:

Because it is a cosine function, the error on the gravity axis due to the other axes NOT being zero is small, as long as those other axes are CLOSE to zero. So, get close and accept it.

Jim

Alright.

ka7ehk wrote:
In the end, you really don't have a precision sensor to start with, so why all the agony over precision calibration? Even if you do the calibration precisely, you only have 1 part in +/-256 resolution!

Jim

Ok i think i got it now, what i am doing right now is just going to perfect the 3 axis readings from 1 side to be perfect but there are other sides...So is there a universal value that can used by all the other sides to calibrate?

No you haven’t! There’s no magic values - you must perform the calibration procedure to obtain the values. If you don’t want to do the calibration then tolerate the +/-10% error.
Realise that this is not a perfect sensor - it has noise, offsets, scaling and temperature sensitivity.the datasheet outlines these. You need to understand these parameters and determine if they are suitable for your application. Personally, for a fall detector, precision isn’t paramount as there’s a big difference between someone standing up and when they’ve fallen down. You don’t need degree resolution to measure this.

Kartman wrote:
No you haven’t! There’s no magic values - you must perform the calibration procedure to obtain the values. If you don’t want to do the calibration then tolerate the +/-10% error.

Which means all the above calculations discussed are all for only 1 direction like this?

Kartman wrote:
Realise that this is not a perfect sensor - it has noise, offsets, scaling and temperature sensitivity.the datasheet outlines these. You need to understand these parameters and determine if they are suitable for your application. Personally, for a fall detector, precision isn’t paramount as there’s a big difference between someone standing up and when they’ve fallen down. You don’t need degree resolution to measure this.

So, it is better to just bear with the 10% errors and move on with the data i get?

For each axis you need to measure gravity in the positive and negative direction. From these values we obtain the offset and scale values.

Only you know what method you are using to determine a fall, so it is up to you to decide what accuracy you require.

Kartman wrote:
For each axis you need to measure gravity in the positive and negative direction. From these values we obtain the offset and scale values. Only you know what method you are using to determine a fall, so it is up to you to decide what accuracy you require.

Based on the data i provided above it is only able to find the offset for the z-axis right? Because only z-axis is experiencing the G force. Am i correct?

ckkkkk wrote:

So, it is better to just bear with the 10% errors and move on with the data i get?

When you start writing the code that uses the senor readings, I would include variables for offset and scale, so you would have for example

x_real = (x_raw - x_offset) * x_scale

and similar for y and z.

To start with, you can just set all the offsets to 0, and set all the scales to the nominal 3.9 (1000/256).

Then you don't need to change the main part of the code if you add a calibration step later where you actually measure values for the offsets (and if using the 'turn it over' method also values for the scales).

MrKendo wrote:

When you start writing the code that uses the senor readings, I would include variables for offset and scale, so you would have for example

x_real = (x_raw - x_offset) * x_scale

and similar for y and z.

To start with, you can just set all the offsets to 0, and set all the scales to the nominal 3.9 (1000/256).

Then you don't need to change the main part of the code if you add a calibration step later where you actually measure values for the offsets (and if using the 'turn it over' method also values for the scales).

Right now, i know scale but i am not completely sure how to calculate the offset.

I don't think you do know the scale exactly. You are just assuming that it is the nominal value from the datasheet, which it probably won't be exactly.

However, that may be good enough. Depends how accurate you need it to be.

So, one last time.

There are a number of different calibration methods, depending on how accurate you need it.

1) simple one position calibration. Gives offsets only. Scale (or sensitivity) is assumed to be the nominal value from datasheet ie. 256 for 1g.

This was described back in post #15.

Place board on level surface so x and y are in 0g, z is in 1g.

x and y readings give you the offset directly.

For the z offset, you have to assume the scale/sensitivity is the nominal value given in datasheet. In practice it probably won't be, so you have some error in the z offset.

2) slightly improved two position calibration. Gives offsets only. Scale (or sensitivity) is assumed to be the nominal value from datasheet ie. 256 for 1g.

Place board on level surface so x and y are in 0g, z is in 1g.

Then reposition board such that z is now in 0g.

Take z reading, this gives you the z offset.

3) full on 'turn it over' method on all 3 axis, gives offsets and scale.

Place board so z is in 1g. Take z reading.

Turn it over so z is in -1g. Take z reading.

The combination of the 2 readings gives you both offset and scale for the z axis.

Place board so x is in 1g. Take x reading.

Turn it over so x is in -1g. Take x reading.

The combination of the 2 readings gives you both offset and scale for the x axis.

Place board so y is in 1g. Take y reading.

Turn it over so y is in -1g. Take y reading.

The combination of the 2 readings gives you both offset and scale for the y axis.

MrKendo wrote:

I don't think you do know the scale exactly. You are just assuming that it is the nominal value from the datasheet, which it probably won't be exactly.

However, that may be good enough. Depends how accurate you need it to be.

So, one last time.

There are a number of different calibration methods, depending on how accurate you need it.

1) simple one position calibration. Gives offsets only. Scale (or sensitivity) is assumed to be the nominal value from datasheet ie. 256 for 1g.

This was described back in post #15.

Place board on level surface so x and y are in 0g, z is in 1g.

x and y readings give you the offset directly.

For the z offset, you have to assume the scale/sensitivity is the nominal value given in datasheet. In practice it probably won't be, so you have some error in the z offset.

2) slightly improved two position calibration. Gives offsets only. Scale (or sensitivity) is assumed to be the nominal value from datasheet ie. 256 for 1g.

Place board on level surface so x and y are in 0g, z is in 1g.

Then reposition board such that z is now in 0g.

Take z reading, this gives you the z offset.

3) full on 'turn it over' method on all 3 axis, gives offsets and scale.

Place board so z is in 1g. Take z reading.

Turn it over so z is in -1g. Take z reading.

The combination of the 2 readings gives you both offset and scale for the z axis.

Place board so x is in 1g. Take x reading.

Turn it over so x is in -1g. Take x reading.

The combination of the 2 readings gives you both offset and scale for the x axis.

Place board so y is in 1g. Take y reading.

Turn it over so y is in -1g. Take y reading.

The combination of the 2 readings gives you both offset and scale for the y axis.

Right now i really did understand there are different methods to do "calibration". But can you explain more on the "Turn it over" method? Also all these "calibration" test is a one off thing right? Means i only need to do one of these "calibration" once right, then next time i just sub those values in without doing the "calibration" again. Am i right on this one?

Kartman wrote:
It's called ‘calibration’ - you do it once and store the offset and scale values usually in eeprom. For a one off, you might hard code these values into your code. Whilst the calibration drifts with temperature, it is only small. The datasheet says around 0.01% per degreeC.

'turn it over' means rotate it on its axis 180 degrees. Basically look for the most positive reading, then look for the most negative reading.

This reply has been marked as the solution.

ckkkkk wrote:
Also all these "calibration" test is a one off thing right? Means i only need to do one of these "calibration" once right, then next time i just sub those values in without doing the "calibration" again. Am i right on this one?

YES!!!

ckkkkk wrote:
But can you explain more on the "Turn it over" method?

This is ka7ehk method from way back in post #10.

For each axis, you need to position it so that axis is vertical. But there are 2 ways it can be vertical, the positive direction of the axis can either be pointing into the ground or up into the air. So you take a reading (or a set of readings and average them) in both positions.

Let's say reading A is 240.

And the other way up, reading B is -260.

The 2 readings will be of opposite sign.

You can then say

A - B = 2g

A + B = 2 * offset

So in this example,

A - B = 240 - (-260) = 2g

500 = 2g

250 = g

And

A + B = 240 + (-260) = 2 *  offset

-20 = 2 * offset

-10 = offset

MrKendo wrote:

This is ka7ehk method from way back in post #10.

For each axis, you need to position it so that axis is vertical. But there are 2 ways it can be vertical, the positive direction of the axis can either be pointing into the ground or up into the air. So you take a reading (or a set of readings and average them) in both positions.

It doesn't need to be in vertical right? Can it be horizontal?

MrKendo wrote:

And

A + B = 240 + (-260) = 2 *  offset

-20 = 2 * offset

-10 = offset

I don't understand why -20 is not the offset for z-axis instead -10 is the offset. Also can i perform the "calibration" now and can you please take a look to check whether if i do it correctly or not?

ckkkkk wrote:
I don't understand why -20 is not the offset for z-axis instead -10 is the offset.

draw a diagram. It will make sense when you think about it.

```                                        offset = 0
-1g (-250)                           0                                  +1g (+250)
|                                   |                                   |
|                                   |                                   |
<---------------250---------------> <---------------250--------------->
|
|
|
offset = -10
|
-10  |
|   |
-1g (-260)                           |   |                              +1g (+240)
|                                   |   |                               |
<---------------250---------------> <---------------250--------------->
```

```Acceleration in X-Axis : -4
Acceleration in Y-Axis : 5
Acceleration in Z-Axis : 223
Acceleration in X-Axis : -4
Acceleration in Y-Axis : 5
Acceleration in Z-Axis : 223
Acceleration in X-Axis : -4
Acceleration in Y-Axis : 5
Acceleration in Z-Axis : 223
Acceleration in X-Axis : -5
Acceleration in Y-Axis : 5
Acceleration in Z-Axis : 223
Acceleration in X-Axis : -7
Acceleration in Y-Axis : 3
Acceleration in Z-Axis : 218
Acceleration in X-Axis : -7
Acceleration in Y-Axis : 3
Acceleration in Z-Axis : 218
Acceleration in X-Axis : -7
Acceleration in Y-Axis : 3
Acceleration in Z-Axis : 218
Acceleration in X-Axis : -9
Acceleration in Y-Axis : 3
Acceleration in Z-Axis : 218
Acceleration in X-Axis : -9
Acceleration in Y-Axis : 3
Acceleration in Z-Axis : 218
Acceleration in X-Axis : -9
Acceleration in Y-Axis : 5
Acceleration in Z-Axis : 218 ```

When data is positive

```Acceleration in X-Axis : -13
Acceleration in Y-Axis : 0
Acceleration in Z-Axis : -264
Acceleration in X-Axis : -13
Acceleration in Y-Axis : 0
Acceleration in Z-Axis : -264
Acceleration in X-Axis : -13
Acceleration in Y-Axis : 0
Acceleration in Z-Axis : -271
Acceleration in X-Axis : -14
Acceleration in Y-Axis : 0
Acceleration in Z-Axis : -271
Acceleration in X-Axis : -14
Acceleration in Y-Axis : 0
Acceleration in Z-Axis : -271
Acceleration in X-Axis : -10
Acceleration in Y-Axis : -1
Acceleration in Z-Axis : -268
Acceleration in X-Axis : -10
Acceleration in Y-Axis : -1
Acceleration in Z-Axis : -268
Acceleration in X-Axis : -10
Acceleration in Y-Axis : -4
Acceleration in Z-Axis : -271
Acceleration in X-Axis : -11
Acceleration in Y-Axis : -4
Acceleration in Z-Axis : -271
Acceleration in X-Axis : -11
Acceleration in Y-Axis : -4
Acceleration in Z-Axis : -271 ```

When data is negative

Average of positive data = 220 and Average of negative data = -269

MrKendo wrote:

And

A + B = 240 + (-260) = 2 *  offset

-20 = 2 * offset

-10 = offset

220 + (-269) = 2 * offset

-49 = 2 * offset

-24.5 = offset?

MrKendo wrote:

ckkkkk wrote:
I don't understand why -20 is not the offset for z-axis instead -10 is the offset.

draw a diagram. It will make sense when you think about it.

```                                        offset = 0
-1g (-250)                           0                                  +1g (+250)
|                                   |                                   |
|                                   |                                   |
<---------------250---------------> <---------------250--------------->
|
|
|
offset = -10
|
-10  |
|   |
-1g (-260)                           |   |                              +1g (+240)
|                                   |   |                               |
<---------------250---------------> <---------------250--------------->
```

Oh, so in order to solve the offset is to +10

ckkkkk wrote:

220 + (-269) = 2 * offset

-49 = 2 * offset

-24.5 = offset?

Yes, offset = -24.5

And your value for the sensitivity is 1g = 489 / 2 = 244.5

So you can see it is a bit different to the nominal value of 256.

And if you want to convert 1g= 244.5 to scale in mg then scale = 1000 / 244.5 = 4.09mg

ckkkkk wrote:

Oh, so in order to solve the offset is to +10

Yes, or you can think of it as subtracting -10,

as in z_real = (z_raw - z_offset) * z_scale.

I'm done now!

MrKendo wrote:

ckkkkk wrote:

220 + (-269) = 2 * offset

-49 = 2 * offset

-24.5 = offset?

Yes, offset = -24.5

And your value for the sensitivity is 1g = 489 / 2 = 244.5

So you can see it is a bit different to the nominal value of 256.

And if you want to convert 1g= 244.5 to scale in mg then scale = 1000 / 244.5 = 4.09mg

So for the scale value, which 1 do i follow? Should i take the one from the datasheet?

MrKendo wrote:

ckkkkk wrote:

Oh, so in order to solve the offset is to +10

Yes, or you can think of it as subtracting -10,

as in z_real = (z_raw - z_offset) * z_scale.

I'm done now!

But for my case z_real = (220 - (-24.5) * 0.0039 = 0.95355G ? Also i have to do it for X and Y-axis right in order to acquire the offset from the x and y-axis.

Last Edited: Sat. Apr 27, 2019 - 02:42 PM

These are data from x-axis

MrKendo wrote:

And

A + B = 240 + (-260) = 2 *  offset

-20 = 2 * offset

-10 = offset

Average of positive data = 250.5  and Average of negative data = -266.3

250.5 + (-266.3) = 2 * offset

-15.8 = 2 * offset

-7.9 = offset

value for the sensitivity is 1g = 516.8 / 2 = 258.4

1000 / 258.4 = 3.87 mg

Below are data from y-axis

Average of positive data = 256.5  and Average of negative data = -261.4

256.5 + (-261.4) = 2 * offset

-4.9 = 2 * offset

-2.45 = offset

value for the sensitivity is 1g = 517.9 / 2 = 258.95

1000 / 258.95 = 3.86 mg

Am i doing all these calculations correctly?

Correct. You need to reorient it and repeat the measurements for each axis. There is a unique pair of offset/scale values for each axis.

If it is fall detection you are after, the question is: are you talking about a fall as in "the cellphone is falling" or a fall as in "my grandfather fell down"? In the first case, all axes go very close to zero during the fall time of a few 10s of milliseconds. The usual reason for doing this is to shut down any moving parts (e.g. memory). In the second case, the orientation will be different from that of a standing or sitting person. So, different criteria for detecting what is a fall and what is not. Neither of these cases really needs calibration of the kind you have been asking about.

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

Last Edited: Sat. Apr 27, 2019 - 06:10 PM

ka7ehk wrote:

Correct. You need to reorient it and repeat the measurements for each axis. There is a unique pair of offset/scale values for each axis.

If it is fall detection you are after, the question is: are you talking about a fall as in "the cellphone is falling" or a fall as in "my grandfather fell down"? In the first case, all axes go very close to zero during the fall time of a few 10s of milliseconds. The usual reason for doing this is to shut down any moving parts (e.g. memory). In the second case, the orientation will be different from that of a standing or sitting person. So, different criteria for detecting what is a fall and what is not. Neither of these cases really needs calibration of the kind you have been asking about.

Jim

Oh i am doing the "my grandfather fell down" one. Also could you please help me check whether the above calculations i did are correct and should i follow the scale on the datasheet or just use the scale value i found during the calibration?

You can easily check if your calculations are correct - you should measure +/- 1g. If you don't, then your calcs are wrong. Really, this is simple linear algebra math - nothing magic. The same techniques would apply to finding the centre of a piece of wood.

Kartman wrote:

You can easily check if your calculations are correct - you should measure +/- 1g. If you don't, then your calcs are wrong. Really, this is simple linear algebra math - nothing magic. The same techniques would apply to finding the centre of a piece of wood.

Alright, then everything is fine as all come close to 1g and -1g.

Can i know what is the most suitable measurement range for fall detection? There are the +-2,4,8,16G.

Think about the basic physics of the problem - if someone trips over, what is the acceleration involved? Do you care about this acceleration or are you more interested in the position of the subject in relation to the ground?

My concern is you seem to lack basic maths skills and to do fall detection successfully requires a lot of maths- both from the physics involved, but also filtering and processing of the data. Unfortunately it is not as simple as: read sensor, determine vertical or horizontal, alarm or no alarm. Whilst it might appear simple, this is a stunningly difficult problem.