cancel
Showing results for 
Search instead for 
Did you mean: 

LIS3DH wrong out value +-16g

baks637202
Associate
Posted on September 28, 2016 at 12:35

Hi,

LIS3DH, I don't move it. Sampling rate 400 Hz, CTRL_REG2=0.

+-2g full scale : (0g;0g;1g) out value

+-4g full scale : (0g;0g;1g) out value

+-8g full scale : (0g;0g;1g) out value

+-16g full scale : (0g;0g;0,67g) out value

 

What is going wrong?
11 REPLIES 11
Miroslav BATEK
ST Employee
Posted on October 04, 2016 at 11:16

Can you please share you code how do you convert the raw data from sensor to g values?

Best regards

Miroslav

Posted on January 18, 2017 at 10:20

Hi Miroslav,

I also experienced the same problem

.

Are there any mistakes in this code?

 // power-on

 :

 // 2G-100Hz

 delay_100ms();        // delay 100ms

 i2c_write(CTRL_REG1, 0x57);

 i2c_write(CTRL_REG4, 0x00);    // 2g

 delay_100ms();        // delay 100ms

 x = i2c_read(OUT_X_H)<<8 | i2c_read(OUT_X_L);

 y = i2c_read(OUT_Y_H)<<8 | i2c_read(OUT_Y_L);

 z = i2c_read(OUT_Z_H)<<8 | i2c_read(OUT_Z_L);

 printf('x:%d y:%d: z:%d\r\n', x, y, z);            --> 'x:0 y:0 z:16448' ==> 1.004g

 // 4G-100Hz

 delay_100ms();        // delay 100ms

 i2c_write(CTRL_REG1, 0x57);

 i2c_write(CTRL_REG4, 0x10);

 delay_100ms();        // delay 100ms

 x = i2c_read(OUT_X_H)<<8 | i2c_read(OUT_X_L);

 y = i2c_read(OUT_Y_H)<<8 | i2c_read(OUT_Y_L);

 z = i2c_read(OUT_Z_H)<<8 | i2c_read(OUT_Z_L);

 printf('x:%d y:%d: z:%d\r\n', x, y, z);            --> 'x:0 y:0 z:8064' ==> 0.984g

 // 8G-100Hz

 delay_100ms();        // delay 100ms

 i2c_write(CTRL_REG1, 0x57);

 i2c_write(CTRL_REG4, 0x20);

 delay_100ms();        // delay 100ms

 x = i2c_read(OUT_X_H)<<8 | i2c_read(OUT_X_L);

 y = i2c_read(OUT_Y_H)<<8 | i2c_read(OUT_Y_L);

 z = i2c_read(OUT_Z_H)<<8 | i2c_read(OUT_Z_L);

 printf('x:%d y:%d: z:%d\r\n', x, y, z);            --> 'x:0 y:0 z:3968' ==> 0.969g

 // 16G-100Hz

 delay_100ms();        // delay 100ms

 i2c_write(CTRL_REG1, 0x57);

 i2c_write(CTRL_REG4, 0x30);

 delay_100ms();        // delay 100ms

 x = i2c_read(OUT_X_H)<<8 | i2c_read(OUT_X_L);

 y = i2c_read(OUT_Y_H)<<8 | i2c_read(OUT_Y_L);

 z = i2c_read(OUT_Z_H)<<8 | i2c_read(OUT_Z_L);

 printf('x:%d y:%d: z:%d\r\n', x, y, z);            --> x:0 y:0 z:1216 ==> 0.593g
Posted on January 18, 2017 at 11:27

Hello,

unfortunately in your code is not seen how do you convert the raw value to acceleration in g unit. I will try to explain it.

It seems you are using High Resolution mode. In this mode the output is 12-bit left-justified (in 2 x 8bit = 16 bit output register). So you have to divide the value by 16 (or shift right by 4 digits) and them multiplied by proper sensor sensitivity. The sensitivity is in datasheet in Table 4.

Examples for you cases:

FS=2g: raw value 16448 ... 16448 / 16 = 1028, 1028 * 1mg/digit = 1028mg = 1.028g

FS=4g

raw value 8064 ... 8064 / 16 = 504, 504 * 2

mg/digit

= 1008mg = 1.008g

FS=8g: raw value 3968 ... 3968 / 16 = 248, 248 * 4mg/digit = 992mg = 0.992g

FS=16g: raw value 1216 ... 1216 / 16 = 76, 76 * 12mg/digit = 912mg = 0.912g

Posted on January 19, 2017 at 01:37

Hi Miroslav,

Thank you

,

I understand.

I thought that FS (Full Scale) would be represented by 16 bits.

FS:16g

raw 32767(0x7fff) --> 16g * 32767/32768 = 16g

raw 1216 --> 16g * 1216/32768 = 0.593g
Posted on June 06, 2017 at 10:55

Thank you for your answer. If I set the output as 8 bit resolution do I have to divide it by 16 then ? When the resolution is 8 bit, only the high registers in the axis output registers have value, the low registers are always zero. How do I calculate the g in this case ?

Please help.

Posted on June 06, 2017 at 13:03

If you use the low-power mode (8-bit output) you can simply multiply the high byte by the sensitivity.

FS=2g: 16mg/digit

FS=4g:

32

mg/digit

FS=8g: 64mg/digit

FS=16g: 192mg/digit

Ahmed  Ben Amara
Associate II
Posted on May 03, 2018 at 17:02

Hello, 

I face the same issue and i just use this methode:

for(i=0; i<3; i++)

{

    valueinfloat = ((buffer[(i<<1) + 1] << 8) + buffer[i<<1]) * sensitivity;

    pData[i] = (int16_t)valueinfloat;

}

where the sensitivity is given by the datasheet 

/* 0.06 mg/digit*/ for the 2G FS

 /* 0.12 mg/digit*/ for the 4G FS

 /* 0.18 mg/digit*/ for the 6G FS

 /* 0.24 mg/digit*/ for the 8G FS

/* 0.73 mg/digit*/ for the 16G FS

the data with 16G FS can exceed the 20G with is wrong as i expect and i do not think i did a shock of 20G.
Posted on May 06, 2018 at 14:28

ahmed.benamara

‌ please specify the issue it is not clear.

I explained how to convert raw values into g unit value in my previous posts.

Posted on May 06, 2018 at 16:06

Sorry , the ic was LIS3DSH, in the lis3dsh i used the function below to convert raw values however when i was testing i give some shocks to the lis3dsh and read the values i saw the values exceed 16g and reach 20g i do not think my shock exceed 8g because when i tested with 8g full scale the values do not exceed 8g. could you please check if i had done a fault in converting raw data?