Skip to main content
Visitor II
January 24, 2018
Question

Queru on LIS3DH sensor

  • January 24, 2018
  • 2 replies
  • 2270 views
Posted on January 24, 2018 at 09:54

Hi,

I am working on LIS3DH accelerometer sensor, I have interfaced this sensor with STM32F103 series micro controller using SPI interface. When I read X, Y and Z acceleration values, I get some random readings and it too fluctuate lot. The sensor is placed horizontal on PCB, parallel to X , Y axis and perpendicular to Z axis. The reading for all three axes is fluctuate around 0.01 to -0.15. In initialization, all three axes has been enabled.

As I am very new to accelerometer sensor, is my understanding that in the position mentioned above should I get g value for X and Y axis around 0g and for Z axis around 1g correct?

OR it just shows fluctuations in X,Y and Z axis value when there is some movement of sensor and again it get stable value when the sensor is stationary?

    This topic has been closed for replies.

    2 replies

    ST Employee
    January 24, 2018
    Posted on January 24, 2018 at 10:41

    Yes, you first assumption is correct. For the the mentioned position X and Y axis should be close to 0g and Z axis around 1g.

    Can you please share your sensor configuration and the procedure how do you convert raw value to acceleration in g unit?

    Visitor II
    January 24, 2018
    Posted on January 24, 2018 at 11:00

    Thank you so much for your response. Please refer below details.

    /* accelerometer register address define */

    #define Status_Reg1 ((u8)0x07)

    #define Who_Am_I ((u8)0x0F)

    #define Ctrl_Reg1 ((u8)0x20)

    #define Ctrl_Reg2 ((u8)0x21)

    #define Ctrl_Reg3 ((u8)0x22)

    #define Ctrl_Reg4 ((u8)0x23)

    #define Ctrl_Reg5 ((u8)0x24)

    #define Ctrl_Reg6 ((u8)0x25)

    #define Status_Reg2 ((u8)0x27)

    #define Out_X_L ((u8)0x28)

    #define Out_X_H ((u8)0x29)

    #define Out_Y_L ((u8)0x2A)

    #define Out_Y_H ((u8)0x2B)

    #define Out_Z_L ((u8)0x2C)

    #define Out_Z_H ((u8)0x2D)

    #define INT1_CFG ((u8)0x30)

    #define INT1_SRC ((u8)0x31)

    #define INT1_THS ((u8)0x32)

    #define INT1_DURATION ((u8)0x33)

    #define CLICK_CFG ((u8)0x38)

    #define CLICK_SRC ((u8)0x39)

    #define CLICK_THS ((u8)0x3A)

    #define TIME_LIMIT ((u8)0x3B)

    #define TIME_LATENCY ((u8)0x3C)

    #define TIME_WINDOW ((u8)0x3D)

    Below is the sensor configuration at power up. 

    /* Ask who am I to comfirm the hardware status */

    retCode =ACCELEROMETER_Read(Who_Am_I,&tmp);

    if((tmp == 0x33) && (retCode == 0))

    {

    MEMS_DEVICE.HardWareSta = DEF_MEMS_NONE_ERR;

    retCode =0;

    #if(DEF_ADDINFO_OUTPUTEN > 0)

    printf('[ACC]:OK!\r\n');

    #endif

    }

    else

    {

    MEMS_DEVICE.HardWareSta = DEF_MEMS_DEVICE_ERR;

    retCode =-1;

    #if(DEF_ADDINFO_OUTPUTEN > 0)

    printf('[ACC]:Error!\r\n');

    #endif

    }

    if(MEMS_DEVICE.HardWareSta != DEF_MEMS_DEVICE_ERR)

    {

    ACCELEROMETER_Write(Ctrl_Reg1,0x57);//0101:normal/low power mode (100Hz),0:normal mode,111:XYZ enable.

    //ACCELEROMETER_Read(Ctrl_Reg1,&tmp);

    ACCELEROMETER_Write(Ctrl_Reg2,0x89);//high pass filter enable

    //ACCELEROMETER_Read(Ctrl_Reg2,&tmp);

    ACCELEROMETER_Write(Ctrl_Reg3,0x00);//disable INT

    //ACCELEROMETER_Read(Ctrl_Reg3,&tmp);

    ACCELEROMETER_Write(Ctrl_Reg4,0x08);//2: Full scale selection +/- 2G High resolution enable

    //ACCELEROMETER_Read(Ctrl_Reg4,&tmp);

    ACCELEROMETER_Write(Ctrl_Reg5,0x00);//INT1 IO not latched

    //ACCELEROMETER_Read(Ctrl_Reg5,&tmp);

    ACCELEROMETER_Write(Ctrl_Reg6,0x02);//INT1 IO active low(??)

    //ACCELEROMETER_Read(Ctrl_Reg6,&tmp);

    ACCELEROMETER_Write(INT1_DURATION,0x00);//set INT1 mode OR, high event

    //ACCELEROMETER_Read(INT1_DURATION,&tmp);

    ACCELEROMETER_Write(INT1_CFG,0x2A);//set INT1 mode OR, high and low event 0X3F

    //ACCELEROMETER_Read(INT1_CFG,&tmp);

    }

    Below is are INT1 threshold value as per user configuration stored in non volatile memory.

    BSP_ACCELEROMETER_SetInt1Threshold(s_Cfg.accMThreshold, 2000); 

    BSP_ACCELEROMETER_SetInt1Duration(s_Cfg.accMDuration, 2000);

    g value calculation function.

    s8 BSP_ACCELEROMETER_ReadXYZ(MEMS_data_Typedef *MEMS_data,u16 timeout)

    {

    s8 retCode=0;

    u8 X_data_h=0,X_data_l=0,Y_data_h=0,Y_data_l=0,Z_data_h=0,Z_data_l=0,tmp=0;

    s16 tmpdata=0;

    double x_acc = 0, y_acc = 0,z_acc = 0;

    ACCELEROMETER_Read(Out_X_L,&X_data_l);

    ACCELEROMETER_Read(Out_X_H,&X_data_h);

    // read Y data

    ACCELEROMETER_Read(Out_Y_L,&Y_data_l);

    ACCELEROMETER_Read(Out_Y_H,&Y_data_h);

    // read Z data

    ACCELEROMETER_Read(Out_Z_L,&Z_data_l);

    ACCELEROMETER_Read(Out_Z_H,&Z_data_h);

    /* calculate the data */

    tmpdata = X_data_l;

    tmpdata |= (X_data_h << 8);

    MEMS_data->X_data = tmpdata;

    tmpdata = Y_data_l;

    tmpdata |= (Y_data_h << 8);

    MEMS_data->Y_data = tmpdata;

    tmpdata = Z_data_l;

    tmpdata |= (Z_data_h << 8);

    MEMS_data->Z_data = tmpdata;

    x_acc = ((double)MEMS_data->X_data)/16380;

    y_acc = ((double)MEMS_data->Y_data)/16380;

    z_acc = ((double)MEMS_data->Z_data)/16380;

    printf('\r\n[ACC]:X=%lf, Y=%lf, Z=%lf', x_acc,y_acc,z_acc);

    return retCode;

    }
    ST Employee
    January 24, 2018
    Posted on January 24, 2018 at 11:07

    OK,

    you enabled the High pass filter ACCELEROMETER_Write(Ctrl_Reg2,0x89);//high pass filter enable

    In this case you will see only changes in the acceleration, in other words, it will remove any DC value like 1g gravity.

    Visitor II
    January 24, 2018
    Posted on January 24, 2018 at 12:29

    After disabling high pass filter, I am able to get g value as expected.

    Thank you so much for your solution.