cancel
Showing results for 
Search instead for 
Did you mean: 

Problem reading LIS3DH FIFO Buffer data

Lalit Kumar Baghel
Associate II

I am using nRF52 DK and LIS3DH accelerometer. 

LIS3DH configuration is follows:

1. LIS3DH ODR set at 10Hz, 

2. Low Power Mode (Low resolution), 

3. Acceleration: 2g. 

4. FIFO Enable, and operating in FIFO mode.

I am reading all 32 samples stored in FIFO buffer using I2C read when OVRN is set.

This cycle is repeated 20 times (total of 32x20=640 samples) with a multishot timer running at 3s intervals. All these samples are stored a array of size 640. I am not getting the data properly on serial i.e., sometimes it is saying logs dropped and sometimes data is not coming. Is there any problem in FIFO configuration or FIFO data read.

Below attached is the code:

// structre definition
 
typedef struct
{
uint8_t x_msb;
uint8_t x_lsb;	
uint8_t y_msb;
uint8_t y_lsb;	
uint8_t z_msb;
uint8_t z_lsb;	
}motion_data;
motion_data Motion_data[640];                // structure to hold Lis3dh data 
uint8_t*acc_ptr;
 
//A. Main Function:
 
static void motion_sensor_timer_handler(void *p_context)
{
float LIS3DH_Acc[96]; // Array to store (32samples containing x, y and z data i.e., total 96 elements )
nrf_gpio_pin_set(ACC_VDD);
nrf_gpio_pin_set(ACC_SDO);
twi_init();
LIS3DH_Init(); //LIS3DH Sensor Init
LIS3DH_GetAccData(LIS3DH_Acc);
int16_t lis_data[96] = {0};
 
 
for(int i=0; i<96; i+=3){
lis_data[i] =(int16_t)( LIS3DH_Acc[i]);
lis_data[i+1] =(int16_t)( LIS3DH_Acc[i+1]);
lis_data[i+2] =(int16_t)( LIS3DH_Acc[i+2]);
 
 
NRF_LOG_INFO(" value of acc x %d ",lis_data[i]);
NRF_LOG_INFO(" value of acc y %d ", lis_data[i+1]);
NRF_LOG_INFO(" value of acc z %d ",lis_data[i+2]);
 
Motion_data[flag].x_msb= (uint8_t)((lis_data[i] & 0xFF00)>>8); // Motion_data[640]: an array to store 20 sets of 32 samples.
Motion_data[flag].x_lsb= (int8_t)(lis_data[i] & 0xFF);
Motion_data[flag].y_msb= (int8_t)((lis_data[i+1] & 0xFF00)>>8);
Motion_data[flag].y_lsb= (int8_t)(lis_data[i+1] & 0xFF);
Motion_data[flag].z_msb= (int8_t)((lis_data[i+2] & 0xFF00)>>8);
Motion_data[flag].z_lsb= (int8_t)(lis_data[i+2] & 0xFF);
 
NRF_LOG_INFO(" value of flag %d ",flag);
++flag;
}
 
nrf_drv_twi_disable(&m_twi); // disable twi
nrf_drv_twi_uninit(&m_twi);
 
if(flag == 640) //collect 640 readings
{
flag=0;
app_timer_stop(motion_sensor_timer_id); //stop the repeated timer T1
ret_code_t error_code;
 
error_code = app_timer_start(m_battery_timer_id, //begin collecting battery data T2
BATTERY_DATA_UPDATE,
NULL);
APP_ERROR_CHECK(error_code);
nrf_gpio_pin_clear(ACC_VDD);
nrf_gpio_pin_clear(ACC_SDO);
 
}
}
 
 
 
 
//LIS3DH
 
//Configuration setup
 
void LIS3DH_Init(void)
{
uint8_t chipid = 0;
uint8_t tmp = 0;
 
uint8_t FIFO_Enable = 0x40;
 
for(int i=0; i<30000; i++){__ASM("nop");}
 
//read chip id
for (int i = 0; i < 10 ; i++ )
{
for(int j = 0 ; j < 1000 ; j++ ) {__asm("NOP");}
i2c_read(LIS3DH_I2C_ADDRESS ,LIS3DH_REGISTER_WHO_AM_I, &chipid, 0x01);
if ( chipid == 0x33 ) {
break;
}
}
 
//reboot sensor
tmp = (LIS3DH_CTRL_REG5_REBOOT);
i2c_write(LIS3DH_I2C_ADDRESS ,LIS3DH_REGISTER_CTRL_REG5, &tmp, 0x01);
 
//delay some time
for(int i=0; i<30000; i++){__ASM("nop");}
for(int i=0; i<30000; i++){__ASM("nop");}
for(int i=0; i<30000; i++){__ASM("nop");}
for(int i=0; i<30000; i++){__ASM("nop");}
for(int i=0; i<30000; i++){__ASM("nop");}
 
//report rate = 10Hz, x/y/z axis enable
tmp = (LIS3DH_CTRL_REG1_DATARATE_10HZ | LIS3DH_CTRL_REG1_XYZEN | LIS3DH_CTRL_REG1_LPEN);
i2c_write(LIS3DH_I2C_ADDRESS ,LIS3DH_REGISTER_CTRL_REG1, &tmp, 0x01);
 
 
 
//delay some time
for(int i=0; i<30000; i++){__ASM("nop");}
for(int i=0; i<30000; i++){__ASM("nop");}
for(int i=0; i<30000; i++){__ASM("nop");}
for(int i=0; i<30000; i++){__ASM("nop");}
 
//enable block data update, full-scale = +-2g
tmp = (LIS3DH_CTRL_REG4_BLOCKDATAUPDATE | LIS3DH_CTRL_REG4_SCALE_2G);
i2c_write(LIS3DH_I2C_ADDRESS ,LIS3DH_REGISTER_CTRL_REG4, &tmp, 0x01);
 
//FIFO Enable
i2c_write(LIS3DH_I2C_ADDRESS ,LIS3DH_REGISTER_CTRL_REG5, &FIFO_Enable, 0x01); // Enable FIFO Buffer
 
}
 
//B.2 LIS3DH data
 
void LIS3DH_GetAccData(float *acc)
{
uint8_t tmp[6] = {0};
int16_t tmp_int16[96] = {0};
 
uint8_t Wait_WTM = 0;
uint8_t enable_bypass = 0x00;
 
uint8_t FIFO_Mode_Enable = 0x5F;
i2c_write(LIS3DH_I2C_ADDRESS ,LIS3DH_REGISTER_FIFO_CTRL_REG, &FIFO_Mode_Enable, 0x01); // Enable FIFO Mode
 
while(!((Wait_WTM == 0xDF)|(Wait_WTM ==0x9F))){
i2c_read(LIS3DH_I2C_ADDRESS ,(LIS3DH_REGISTER_FIFO_SRC_REG), &Wait_WTM, 0x01); // Wait for WTM/OVRN
NRF_LOG_INFO("WTM Status: %x", Wait_WTM);
}
 
 
NRF_LOG_INFO("Getting inside loop");
 
for(int i=0; i<96; i+=3){
i2c_read(LIS3DH_I2C_ADDRESS ,(LIS3DH_REGISTER_OUT_X_L | LIS3DH_READ_MULTI_BYTES), tmp, 0x06);
tmp_int16[i] = (int16_t)((tmp[1]<< 8) | tmp[0]);
tmp_int16[i+1] = (int16_t)((tmp[3]<< 8) | tmp[2]);
tmp_int16[i+2] = (int16_t)((tmp[5]<< 8) | tmp[4]);
acc_working_condition=1;
acc[i] = (float)(tmp_int16[i]) * LIS3DH_ACC_CONVERT_2G;
acc[i+1] = (float)(tmp_int16[i+1]) * LIS3DH_ACC_CONVERT_2G;
acc[i+2] = (float)(tmp_int16[i+2]) * LIS3DH_ACC_CONVERT_2G;}
 
i2c_write(LIS3DH_I2C_ADDRESS ,LIS3DH_REGISTER_FIFO_CTRL_REG, &enable_bypass, 0x01); //Enable Bypass Mode
 
}

1 REPLY 1
Eleon BORLINI
ST Employee

Hi @Lalit Kumar Baghel​ ,

To be sure it is a FIFO issue, did you try to change the FIFO parameters and check if the data appear missing as well?

And did you have the possibility to check also other devices?

-Eleon