Skip to main content
Visitor II
October 22, 2017
Question

LIS3D :the calculation---Puzzling problem in AN3308.

  • October 22, 2017
  • 2 replies
  • 3066 views
Posted on October 22, 2017 at 05:12

       I have found a puzzling problem while I reading the document AN3308,On page 17,table 9.In my opinion, 1g come from the formula : a = (0x4000 -> 0x400 = 1024)*2000mg/2048.So get the correct value : 1g , In the same way, 350mg should come from: a = (Ox15e0 -> 0x15e = 350)*2000mg/2048 , but the calculation is 341.8,not equal to 350.

       Another problem is that I have received 12bit data(so as: OxFFF0...) from LIS3DH while I config it working in normal mode (10 bit)

      Anyone can help me explain it ?  thanks !
    This topic has been closed for replies.

    2 replies

    ST Employee
    October 23, 2017
    Posted on October 23, 2017 at 10:13

    The conversion is done in following way:

    acceleration_mg = raw_data_LSB * sensitivity, the value read from output registers must be shifted right according to selected mode (8, 10, 12 bit)

    The sensitivity for all combination of mode and full scale can be found in datasheet in table 4.

    The FIFO stores 10-bit values.

    dehai woAuthor
    Visitor II
    October 24, 2017
    Posted on October 24, 2017 at 14:07

    Thank you very much!

    dehai woAuthor
    Visitor II
    November 20, 2017
    Posted on November 20, 2017 at 08:38

    Thank you very much!  But now I met another tough problem: when I enable X,Y,Z axis, and enable all interrupts ( X_H,X_L,Y_H,Y_L,Z_H,Z_L ) , LIS3DH can not generate interrupt completely . While if I 

    only enable  one  of  the six  interrupts (such us X_H, or Z_L...) , or two or three of  of the six interrupts (such as X_H,Y_H,Z_L) ,then it work fine. How to resolve this problem? thanks .

    ST Employee
    November 20, 2017
    Posted on November 20, 2017 at 10:18

    If you enable X_H interrupt, the interrupt is triggered if the absolute value of acceleration in X axis will be higher then threshold.

    If you enable X_L interrupt, the interrupt is triggered if the absolute value of acceleration in X axis will be lower then threshold.

    So enabling both X_H and X_L conditions doesn't make sense because the interrupt will be triggered all the time.

    dehai woAuthor
    Visitor II
    November 23, 2017
    Posted on November 23, 2017 at 04:12

    Now I see.

    About self test , I  have tested my  sensor , 10 times self testing , only 2~3 times successful, my self test code listed below , is there some thing wrong in the code?

     Self-test0 �?self-test 1  is be mentioned on  page 37 of the datasheet , what is the difference of 

    self-test0  and self-test 1 ? thanks�?

    uint8_t ACC_selftest(void)

    {

    uint8_t i;

    int16_t Gx_no_st,Gy_no_st,Gz_no_st,Gx_st,Gy_st,Gz_st,ST_x,ST_y,ST_z;

    AxesRaw_t acc_data[32];

    //---InitializeSensor,turn on sensor,enableX/Y/Zaxes.?SetBDU=1,FS=2G, NormalMode,ODR=50Hz

    if (!(LIS3DH_WriteReg(0x21, 0x00)))

    return MEMS_ERROR;

    if (!(LIS3DH_WriteReg(0x22, 0x00)))

    return MEMS_ERROR;

    if (!(LIS3DH_WriteReg(0x23, 0x80))) //A0

    return MEMS_ERROR;

    if (!(LIS3DH_WriteReg(0x20, 0x47))) //6F

    return MEMS_ERROR;

    // GYRO is in power down mode after power up

    //set the control register (24h) to Cut-Off Frequency = 50Hz

    // Write(0x24, 0x02);

    // set the control register (23h) to ±2000dps FS, self-test0 mode with BDU bit enabled

    //Write(0x23, 0xA0);

    // set the control register (20h) to 200Hz ODR with X/Y/Z axis enabled.

    //Write(0x20, 0x6F);

    //Wait for 800mS for the gyroscope to be stabilized [2]

    Delay(0x2000);

    // read the gyroscope data 5 times in self-test0 mode

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

    {

    LIS3DH_GetAccAxesRaw(&acc_data[i]);

    }

    // average the raw data

    Gx_no_st = (acc_data[0].AXIS_X + acc_data[1].AXIS_X + acc_data[2].AXIS_X + acc_data[3].AXIS_X + acc_data[4].AXIS_X) / 5;

    Gy_no_st = (acc_data[0].AXIS_Y + acc_data[1].AXIS_Y + acc_data[2].AXIS_Y + acc_data[3].AXIS_Y + acc_data[4].AXIS_Y) / 5;

    Gz_no_st = (acc_data[0].AXIS_Z + acc_data[1].AXIS_Z + acc_data[2].AXIS_Z + acc_data[3].AXIS_Z + acc_data[4].AXIS_Z) / 5;

    // enable self-test 0 at +/-2000dps FS with BDU enabled, Wait for 60mS for the gyroscope to be stabilized

    //Write(0x23, 0xA2);

    //REG4:---selftest'

    LIS3DH_SetSelfTest(LIS3DH_SELF_TEST_0);

    // read the gyroscope data 5 times in self-test0 mode

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

    {

    LIS3DH_GetAccAxesRaw(&acc_data[i]);

    }

    // average the raw data

    Gx_st = (acc_data[0].AXIS_X + acc_data[1].AXIS_X + acc_data[2].AXIS_X + acc_data[3].AXIS_X + acc_data[4].AXIS_X) / 5;

    Gy_st = (acc_data[0].AXIS_Y + acc_data[1].AXIS_Y + acc_data[2].AXIS_Y + acc_data[3].AXIS_Y + acc_data[4].AXIS_Y) / 5;

    Gz_st = (acc_data[0].AXIS_Z + acc_data[1].AXIS_Z + acc_data[2].AXIS_Z + acc_data[3].AXIS_Z + acc_data[4].AXIS_Z) / 5;

    // calculate the absolute self-test values of with self-test minus without self-test

    ST_x = abs(Gx_st - Gx_no_st);

    ST_y = abs(Gy_st - Gy_no_st);

    ST_z = abs(Gz_st - Gz_no_st);

    //

    if ((ST_x <= 360) && (ST_y <= 360) && (ST_z <= 360) && (ST_x >= 17) && (ST_y >= 17) && (ST_z >= 17)){ // 60mg,17,360 need be chaeck !!!!!

    //The gyroscope passes;

    return MEMS_SUCCESS;

    }

    else{

    //The gyroscope fails;

    return MEMS_ERROR;

    }

    }