cancel
Showing results for 
Search instead for 
Did you mean: 

LSM9DS1, FIFO, Duplicated data

wpaul
Associate II

Hi,

I'm acquiring gyros and accelerometers data through i2C bus, pulling the data from the FIFO asynchronously from the component acquisition frequency, but at a frequency close by (to avoid overfilling the FIFO).

Without metrological tools, I can still confirm readings are OK ( "g" on the axe pointing downward, sign of rotation etc ...).

However, when looking closer to the data, some are duplicated from one FIFO emptying to the next:0690X00000AsaAtQAJ.jpg

LSM is acquiring at 59.5Hz. I've tried to collect at several frequencies: 60Hz, 50Hz, 40Hz or 200Hz. Behavior occurrence vary, but is always present. Also, as visible on the table, it is not systematic, but when happening it is always first sample compare to last sample of previous batch.

Before reading the FIFO, I'm checking STATUS_REG for new data, and FIFO_SRC for FIFO size. Which, btw, highlights the Temp, Acc and gyro data are not writing in a single shoot into the FIFO.

I'm struggling on this topic for several days now. I'm about to write a turn around to compare last recorded sample to the first one of a new batch: but it is ugly.

Anyone encounter such behavior, or could provide any tips about what I'm doing wrong?

Below some extract from my code and LSM configuration.

Tanks in advance.

//LSM9DS1 configuration
#define CTRL_REG1_G_IxDflt      0b01000000 /* ACC & Gyro OutputDataRate= 59.5Hz; BW=16Hz; FullScale= 245dps */
#define CTRL_REG8_IxDflt        0b01000100 /* Normal reboot mode, No update until MSB read;  Reg. addr. auto. inc.; LITTLE Endian mode, IT pinS active High, push-pull; 4-wire SPI, no reset requested */
#define CTRL_REG9_IxDflt        0b00000010 /* Enable FIFO, and NO!!! FIFO for TEMP data*/
#define FIFO_CTRL_IxDflt        0b00100000 /* Fill in fifo until full, then stop. No custom threshold for fifo*/
//Other settings remain at default values
 
int ReadSensor(sDevAccGyro *sIMU)
{
	uint8_t szBuf[14] = {0};
	
	struct i2c_rdwr_ioctl_data sI2cDataSet;
	struct i2c_msg sMsgList[4];
	//preparing i2c_rdwr_ioctl_data and i2c_msg structures
	//in order to use ioctl() with I2C_RDWR option
	//Good exemple: http://www.merkles.com/Using_I2C/5_struct_i2c_msg.html 
 
	
	//Reading New data flags and FIFO size
	//Custom fonction to acces LSM (based on LINUX Read() methode)
	ReadI2cRegister( iHandeler, iDeviceAddr, STATUS_REG_Addr, szBuf);
	ReadI2cRegister( iHandeler, iDeviceAddr, FIFO_SRC_Addr, (szBuf+1),false);
	int iStatus = szBuf[0];
	int iSamplesNb = (szBuf[1] & 0b00111111);
	
	//FIFO empting loop
	for (int i = 0; i < iSamplesNb; i++ )
	{
		//Avoid to read FIFO while new data are fiding in
		if( !(0x0 == iSamplesNb) && !(0x7 == iStatus) )
			return -3;
		
		ioctl(iHandeler, I2C_RDWR, &sI2cDataSet);
		//recovering data from sI2cDataSet structure
		//...
		ReadI2cRegister( iHandeler, iDeviceAddr, STATUS_REG_Addr, szBuf);
		iStatus = szBuf[0];
		memset(szBuf, 0x00, sizeof(szBuf));
	}
}

PS: there are some similarities with this post:

https://community.st.com/s/question/0D50X0000AxCwVUSQ0/lis2dh-fifo-documentation-and-usage-questions

1 ACCEPTED SOLUTION

Accepted Solutions
wpaul
Associate II

Hi,

Issue is fixed 🙂

It cames from the use of the "ioctl(iHandeler, I2C_RDWR, &sI2cDataSet);" methode. When returning to a regular posix read() methode, all worked well (obviously it take more time).

At last to answer to @Eleon BORLINI​ question: LSM9DS1 datasheet mention "Temperature sensor output = 0 (typ.) at 25 °C, temperature sensitivity: 16 LSB/°C". So my sensor temperature was some 35°C, which is reasonable, the component being close to my µP.

Cheers

View solution in original post

5 REPLIES 5
Eleon BORLINI
ST Employee

Hi @wpaul​ , one question before going deep in the request... are you really working at about 170 degrees Celsius? Regards

wpaul
Associate II

Hi @Eleon BORLINI​ 

Sorry I was away for a while.

No, temperature is room temperature, some 22°C. The 170 came straight from the LSM9DS1. I believe it is shown in some tens of degree, but there must be some scale factor. I have some records made in a temperature chamber, so it will give me more insight about.

Regards

wpaul
Associate II

Hi,

Issue is fixed 🙂

It cames from the use of the "ioctl(iHandeler, I2C_RDWR, &sI2cDataSet);" methode. When returning to a regular posix read() methode, all worked well (obviously it take more time).

At last to answer to @Eleon BORLINI​ question: LSM9DS1 datasheet mention "Temperature sensor output = 0 (typ.) at 25 °C, temperature sensitivity: 16 LSB/°C". So my sensor temperature was some 35°C, which is reasonable, the component being close to my µP.

Cheers

Hi @wpaul​ , maybe the use of "ioctl(iHandeler, I2C_RDWR, &sI2cDataSet);" method for FIFO asynchronous mode missed a few samples during the reading, or you were too fast in reading the FIFO and the data was not yet updated... did you try to set the BDU bit in CTRL_REG8 (22h) before switching method? Regards

Hi,

Thank you for the return.

Yes, BDU is ON.

I'm missing details about how the "ioctl(...,I2C_RDWR,...)" work in the background.

If by any chance you are familiar with and could share some insight, it would be highly    appreciated.

Kind regards

FYI: Below the structure transmitted to the method, based on info coming from http://www.merkles.com/Using_I2C/5_struct_i2c_msg.html and around.

	struct i2c_rdwr_ioctl_data i2cDataSet;
	struct i2c_msg msgList[4];
 
	//Setting up first @register to read
	msgList[0].addr = sIMU->iDeviceAddr; 	//Slave address
	msgList[0].flags = 0;					//I2C write operation
	msgList[0].len = 1;
	msgList[0].buf = ucDataBank;			//TEMP @ register
 
	//Setting up room for data set to read
	msgList[1].addr = sIMU->iDeviceAddr;
	msgList[1].flags = I2C_M_RD;			//I2C read operation
	msgList[1].len = 14;					//Reading all date registers (TEMP_LSB, MSB, Gyro_X_L, _MSB, G_Y_L, _M, G_Z_L, _M, ACC_X_LSB, _MSB, ACC_Y_L, _MSB, A_Z_L, _M)
	msgList[1].buf = cBuf;
 
	//Wrapping all message into i2c_rdwr_ioctl_data type structure
	i2cDataSet.msgs = msgList;
	i2cDataSet.nmsgs = 2;