2017-06-05 02:40 AM
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.
#lis3dh-spi #lis3dh #mems-accelerometer2017-06-05 06:42 AM
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?2017-06-05 07:27 PM
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.
2017-06-06 02:10 AM
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.
2017-06-06 04:38 AM
,
,
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. ,
2017-07-03 01:33 AM
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).