2019-11-28 05:28 AM
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:
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
Solved! Go to Solution.
2020-01-10 06:48 AM
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
2019-11-28 07:46 AM
Hi @wpaul , one question before going deep in the request... are you really working at about 170 degrees Celsius? Regards
2019-12-02 12:58 AM
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
2020-01-10 06:48 AM
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
2020-01-13 02:21 AM
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
2020-01-13 04:45 AM
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;