cancel
Showing results for 
Search instead for 
Did you mean: 

LIS3DH Z output noisy

Anusuya Nallathambi
Associate II
Posted on June 05, 2017 at 11:40

I am trying to measure a machine's vibration using LIS3DH sensor. 

I set the LIS3DH in low power mode and 5.376 kHz sampling frequency which outputs 8 bit output. I use spi to get the data from the sensor. I changed this raw output into �g' using the sensitivity value given in the datasheet.

My problem is: The sensor shows a fluctuation in its output of Z axis even when there is no vibration applied and the sensor is fitted on a horizontal surface. The range of this fluctuation is approximately from 0.6g to 1.2g. I have attached a image that shows such output. (X axis is time and Y axis is vibration in terms of g)

Can someone please help me to interpret why this is happening ? Is there a method to somehow remove this noise from the output ?

Please help.0690X00000607ETQAY.png

#lis3dh-spi #lis3dh #mems-accelerometer
5 REPLIES 5
Miroslav BATEK
ST Employee
Posted on June 05, 2017 at 15:42

The fluctuation is really big, it is not correct.

Can you please share your sensor configuration and the code how do you convert the raw data into acceleration in g?
Posted on June 06, 2017 at 02:27

Thank you for your reply. I do not understand what you mean by sensor configuration. I am using LIS3DH sensor in low power mode. The sampling frequency is 5.376 kHz and the output is 8 bit long.The range of output is +/- 4g. I use FIFO stream mode and watermark interrupt to accumulate the data. After reading the data from the FIFO I multiply it by 0.032 to convert it into g. I use Raspberry PI to process the data via SPI communication. I am unable to show you the code right now due to some technical difficulties.

Posted on June 06, 2017 at 09:10

There is one more thing I would like to clarify. The 8 bit output is in the High register of the OUT_X,OUT_Y,OUT_Z registers. I read this data as it is and multiply it with 0.032 and display the acceleration in g. Is this method right ? I know the output of LIS3DH is left justified. I assumed that since the output is 8 bit I can use it as it is. Am I right in my assumption ?

Please help.

Posted on June 06, 2017 at 11:38

 ,

 ,

The below is the code I am using:

♯ define LIS3DH_WHOAMI_REG (0x0F)

 ,

♯ define LIS3DH_CTRL_REG1 (0x20)

♯ define LIS3DH_CTRL_REG4 (0x23)

 ,

♯ define LIS3DH_CTRL_REG5 (0x24)

♯ define LIS3DH_OUT_X_REG (0x28)

 ,

♯ define LIS3DH_OUT_Y_REG (0x2A)

 ,

♯ define LIS3DH_OUT_Z_REG (0x2C)

 ,

♯ define LIS3DH_FIFO_CTRL_REG (0x2E)

 ,

♯ define LIS3DH_FIFO_SRC_REG (0x2F)

 ,

♯ define SPI_MODE_READ (0x80)

 ,

♯ define SPI_INCREMENTAL_READ (0x40)

♯ define  ,LIS3DH_LPEN  ,  ,  ,  ,  ,  ,  ,(0x08)  ,// Low-power mode enable

♯ define  ,LIS3DH_XYZ_EN  ,  ,  ,  ,  ,  ,(0x07)  ,// X,Y,Z-axis enable

♯ define  ,LIS3DH_5KHZ  ,  ,  ,  ,  ,  ,  ,(0x90)  ,// Low-power mode 5.376kHz, HR/Normal 1.344kHz

♯ define  ,LIS3DH_FIFO_EN  ,  ,  ,  ,  , (0x40)  ,// FIFO enable

♯ define  ,LIS3DH_SCALE_4G  ,  ,  ,  ,  ,(0x10)  ,// +/-4G

♯ define LIS3DH_STATUS_REG_VAL (LIS3DH_STATUS_REG | SPI_MODE_READ)

 ,

static unsigned char s_reg_status[2] = {LIS3DH_STATUS_REG_VAL, 0x00},

// FIFO_SRC_REG

 ,

♯ define LIS3DH_FIFOSRC_REG_VAL (LIS3DH_FIFO_SRC_REG | SPI_MODE_READ)

 ,

static unsigned char fifo_src_reg[2] = {LIS3DH_FIFOSRC_REG_VAL, 0x00},

// OUT_X, OUT_Y, OUT_Z

 ,

♯ define LIS3DH_OUT_X_REG_VAL (LIS3DH_OUT_X_REG | SPI_MODE_READ | SPI_INCREMENTAL_READ)

 ,

♯ define LIS3DH_OUT_Y_REG_VAL (LIS3DH_OUT_Y_REG | SPI_MODE_READ | SPI_INCREMENTAL_READ)

 ,

♯ define LIS3DH_OUT_Z_REG_VAL (LIS3DH_OUT_Z_REG | SPI_MODE_READ | SPI_INCREMENTAL_READ)

static unsigned char s_reg_out_x[3] = {LIS3DH_OUT_X_REG_VAL, 0x00, 0x00},

 ,

static unsigned char s_reg_out_y[3] = {LIS3DH_OUT_Y_REG_VAL, 0x00, 0x00},

 ,

static unsigned char s_reg_out_z[3] = {LIS3DH_OUT_Z_REG_VAL, 0x00, 0x00},

♯ define  ,LIS3DH_FIFO_BYPASS  ,  ,  ,  , (0x00)

♯ define  ,LIS3DH_FIFO_STREAM_FIFO  ,  ,(0xC0)

♯ define LIS3DH_FIFO_STREAM_WTM_12 LIS3DH_FIFO_STREAM|0x0C

//Output data store in array

 ,

♯ define ACCEL_SAMPLE_SIZE (10000000)

 ,

static float s_accel_x[ACCEL_SAMPLE_SIZE],

 ,

static float s_accel_y[ACCEL_SAMPLE_SIZE],

 ,

static float s_accel_z[ACCEL_SAMPLE_SIZE],

 ,

static int s_num_data = 0,

//LIS3DH set up function

bool setup_LIS3DH(int fd)

 ,

{

 ,

// LIS3DH�確�

 ,

unsigned char reg_whoami[2] = {LIS3DH_WHOAMI_REG|SPI_MODE_READ, 0x00},

 ,

wiringPiSPIDataRW(LIS3DH_SPI_PORT, reg_whoami, 2),

 ,

if (reg_whoami[1] == 0x33)

 ,

{

 ,

printf('found LIS3DH\n'),

 ,

}

 ,

else

 ,

{

 ,

printf('LIS3DH not found\n'),

 ,

return false,

 ,

}

// CTRL_REG1(0x20)setting

 ,

// Low-power

 ,

unsigned char reg_ctrl1[2] = {LIS3DH_CTRL_REG1, LIS3DH_5KHZ | LIS3DH_LPEN | LIS3DH_XYZ_EN}, // 5.376kHz ,

 ,

wiringPiSPIDataRW(LIS3DH_SPI_PORT, reg_ctrl1, 2),

// CTRL_REG4(0x23)setting

 ,

unsigned char reg_ctrl4[2] = {LIS3DH_CTRL_REG4, LIS3DH_SCALE_4G}, //+/-4G high-resolution off

 ,

wiringPiSPIDataRW(LIS3DH_SPI_PORT, reg_ctrl4, 2),

// CTRL_REG5(0x24)

 ,

unsigned char reg_ctrl5[2] = {LIS3DH_CTRL_REG5, LIS3DH_FIFO_EN}, // FIFOオン

 ,

wiringPiSPIDataRW(LIS3DH_SPI_PORT, reg_ctrl5, 2),

}

float scalefactor = 0.032,// +/-4g scale low power mode sensitivity = 32mg/digit

//read data from fifo and save in array

bool fifo_read(char nbytes)

 ,

{

 ,

int input,turn,

 ,

signed char out,

 ,

float scaledoutx,scaledouty,scaledoutz,

 ,

for (turn=1,turn<,(nbytes+1),turn++)

 ,

{

 ,

// LIS3DH OUT_X ->,read x axis value

 ,

s_reg_out_x[0] = LIS3DH_OUT_X_REG_VAL,

 ,

wiringPiSPIDataRW(LIS3DH_SPI_PORT, s_reg_out_x, 3),

 ,

out=s_reg_out_x[2],

 ,

scaledoutx=out*scalefactor, //scaling

 ,

//printf('OUT_X = %f ',scaledoutx),

 ,

 ,

// LIS3DH OUT_Y ->, read y axis value

 ,

s_reg_out_y[0] = LIS3DH_OUT_Y_REG_VAL,

 ,

wiringPiSPIDataRW(LIS3DH_SPI_PORT, s_reg_out_y, 3),

 ,

out=s_reg_out_y[2],

 ,

scaledouty=out*scalefactor, //scaling

 ,

//printf('OUT_Y = %f ',scaledouty),

 ,

 ,

// LIS3DH OUT_Z -read z axis value

 ,

s_reg_out_z[0] = LIS3DH_OUT_Z_REG_VAL,

 ,

wiringPiSPIDataRW(LIS3DH_SPI_PORT, s_reg_out_z, 3),

 ,

out=s_reg_out_z[2],

 ,

scaledoutz=out*scalefactor, //scaling

 ,

//printf('OUT_Z = %f ',scaledoutz),

 ,

 ,

//read I/O input from pin ♯ 27

 ,

input=digitalRead(GPIO_PORT2),

 ,

//printf('Input = %d\n ',input),

 ,

 ,

if (s_num_data>,ACCEL_SAMPLE_SIZE)

 ,

{

 ,

return false,

 ,

}

 ,

else

 ,

{

 ,

s_accel_x[s_num_data]= scaledoutx,

 ,

s_accel_y[s_num_data]= scaledouty,

 ,

s_accel_z[s_num_data]= scaledoutz,

 ,

s_gpio[s_num_data]=input,

 ,

s_num_data+=1,

 ,

}}} /*saving data in array*/

/*main function*/

int main(int argc, char *argv[])

 ,

{

 ,

int fd,j,

 ,

unsigned char nbytes,

// SPI initiliase

 ,

fd = 0,

 ,

if (!init_spi(&,fd))

 ,

return 1,

// LIS3DHsetting

 ,

if (!setup_LIS3DH(fd))

 ,

return 1,

 ,

//BYPASS MODEactivate

 ,

unsigned char fifo_ctrl_reg[2] = {LIS3DH_FIFO_CTRL_REG, LIS3DH_FIFO_BYPASS},

 ,

wiringPiSPIDataRW(LIS3DH_SPI_PORT, fifo_ctrl_reg, 2),

 ,

 ,

//FIFO Buffer STREAM MODE→12byte watermarksetting

 ,

fifo_ctrl_reg[0] = LIS3DH_FIFO_CTRL_REG,

 ,

fifo_ctrl_reg[1] = LIS3DH_FIFO_STREAM_WTM_12,

 ,

wiringPiSPIDataRW(LIS3DH_SPI_PORT, fifo_ctrl_reg, 2),

 ,

while(1)

 ,

{

 ,

//start polling the FIFO status

 ,

if(fifo_overrun())

 ,

{}

 ,

else

 ,

{

 ,

while(fifo_src_reg[1]<,0x80)//check for WTM bit to become 1

 ,

{

 ,

if(fifo_overrun()) break,

 ,

fifo_src_reg[0] = LIS3DH_FIFOSRC_REG_VAL,

 ,

wiringPiSPIDataRW(LIS3DH_SPI_PORT, fifo_src_reg, 2),

 ,

}}

 ,

//when WTM bit is 1 read the data from FIFO buffer get the number of new data bytes in the FIFO

 ,

nbytes=fifo_src_reg[1] &, 0x1F,

 ,

if(!(fifo_read(nbytes)))

 ,

{

 ,

printf('Memory error: exiting program...\n'),

 ,

break,

 ,

}}

 ,

return(0),

 ,

}

This is the program I am using to read the data. ,

Please help. ,

Alex Spurling
Associate
Posted on July 03, 2017 at 10:33

Please try the following and see if you still get the same noisy output:

Verify that the x and the y axes do not show the same noisy output.

Set the sensitivity to 2g.

Set high precision mode on.

Set the sample rate to something like 10/50/100hz (I've tried these rates and they work well for me)

Turn off FIFO mode and try to sample the acceleration values directly from the 28-2D registers.

Try reading both the low and the high bits as a 16 bit value. You then need to change the scaling factors to get the correct g value.

I found this thread because I was seeing more noise in the z axis on my sensor than on the x or y. However, the maximum deviation from the mean is only about 0.05g (x and y tend to stay within about 0.025g).