cancel
Showing results for 
Search instead for 
Did you mean: 

Queru on LIS3DH sensor

Vishal Dongare
Associate II
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?

9 REPLIES 9
Miroslav BATEK
ST Employee
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?

Vishal Dongare
Associate II
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;

}
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.

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.

Posted on January 25, 2018 at 04:13

Hi Vishal, Can you share how you convert raw data into g value? And what is the configuration of registers settings? Thanks for your time.

Posted on January 25, 2018 at 05:10

Cast the signed integer to a float and scale based on the full-scale-deflection mode selected.

Pick a range based on what you expect to be measuring so you get the finest granularity measurements.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on January 25, 2018 at 07:20

Hi Clive, my controller is not having FPU(Floating point unit) so only integer support. Could you provide the equation for raw data into g value for +-2g scale? Thanks.

Posted on January 25, 2018 at 16:44

You don't need an FPU to do floating point math, and you say you want units in G, not mG

float x = (float)X * 0.001f; // in G where 12-bit signed sample, and +/-2G range

http://www.st.com/content/ccc/resource/technical/document/datasheet/3c/ae/50/85/d6/b1/46/fe/CD00274221.pdf/files/CD00274221.pdf/jcr:content/translations/en.CD00274221.pdf

 
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on January 29, 2018 at 06:05

Thank you Clive. So, as per your response. I have to put raw value into the equation to get the data into G unit. Am I right? or If I want to use 8-bit or 10-bit output sample than according to Mechanical characteristic table value from datasheet I have to replace 0.001 value to its respective value. Am I right?