2017-11-18 07:03 AM
Hello everyone,
I've problem with using Continous Fifo mode. During data processing I get periodically strange values in timestamp. In table below is shown configuration whitch I use.I use interrupt on fifo treshold on int 1 pin to start read fifo (procedure below). Can someone guide me how to improve the reliability of both gyroscope and accelerometer (mainly gyroscope). I need to calculate rotation of sensor attached to mechanical arm.(I know my configuration isn't perfect for reliability, but for now I tried to use fifo correctly).NameRejestr No.ValueDescription
FUNC_CFG_ACCESS0x01h0x00hNo embedded functions
FIFO_CTRL10x06h0x7FhFIFO threshold level = 127
FIFO_CTRL20x07h0x80hEnable timestamp as 3rd FIFO data set
FIFO_CTRL30x08H0x09hGyro/Accelerometer FIFO no decimation
FIFO_CTRL4
0x09h
0x08hTime
FIFO
n
o decimation
FIFO_CTRL50x0Ah0x0EhFIFO ODR =12.5Hz, Continuous mode.
ORIENT_CFG_G0x0Bh0x00h
INT1_CTRL0x0Dh0x08hFIFO threshold interrupt on INT1 pad
INT2_CTRL0x0Eh0x00h
CTRL3_C0x12h0x44hBlock Data Update Enable,
Interrupt output pads active high, push-pull mode, Register address automatically incremented,data LSB @ lower address;CTRL4_C0x13h0x08hbandwidth determined by ODR selection,
Data-ready mask enable.CTRL5_C0x14h0x00hNo rounding,
No self testCTRL6_C0x15h
0x00h
High-performance operating mode enable for accelerometer
CTRL7_G 0x16h
0x00h
High-performance operating mode
en
able for gyro
CTRL8_XL0x17h0xE4hAccelerometer low-pass filter LPF2 disable,
Accelerometer slope filterCTRL9_XL0x18h0x38hAccelerometr OX,OY,OZ axis enebled
CTRL10_C0x19h
0x38h
Gyroscope OX,OY,OZ axis enabled
TAP_CFG0x58h0x91hTimestamp count enable,
Enable accelerometer HP and LPF2 filters,Latched InterruptWAKE_UP_DUR0x5Ch0x00hTimestamp register resolution setting 1LSB = 6.4 ms;
CTRL1_XL0x10h0x17h
Accelerometer ODR =12.5 Hz, Accelerometer full-scale selection=16g,
Anti-aliasing filter bandwidth selection f=50Hz,CTRL2_G 0x11h0x1Ch
Gyroscope ODR =
12.5 Hz,
Gyroscope
full-scale selection= 2000deg/s,
Anti-aliasing filter bandwidth selection f=50Hz,
When interrupt occurs I read registers 0x3Ah and 0x3Bh, and combine them into number of unread words.
Then I use while loop to read Fifo data as below.
while((NoData>9)||(!FifoEmpty)){
//Discard
unread words if doesn't start from Fifopattern=0
while(FifoPattern!=0){ C=i2c_Read(I2Cx, I2C_LSM6DS33_Address, 0x3C); D=i2c_Read(I2Cx, I2C_LSM6DS33_Address, 0x3D); FifoPattern=(D<<8) | C;if(FifoPattern!=0){
FiFoL=(i2c_Read(I2Cx, I2C_LSM6DS33_Address, 0x3E)); FiFoH=(i2c_Read(I2Cx, I2C_LSM6DS33_Address, 0x3F)); }}//Read whole fifopattern (form 0 to 8)for(j=0;j<9;j++){ C=i2c_Read(I2Cx, I2C_LSM6DS33_Address, 0x3C); D=i2c_Read(I2Cx, I2C_LSM6DS33_Address, 0x3D); FifoPattern=(D<<8)+C;FiFoL=(i2c_Read(I2Cx, I2C_LSM6DS33_Address, 0x3E));
FiFoH=(i2c_Read(I2Cx, I2C_LSM6DS33_Address, 0x3F)); FiFo=(FiFoH<<8)+FiFoL;switch(FifoPattern){
case 0: { XGyro=FiFo; break;} case 1: { YGyro=FiFo; break;} case 2: { ZGyro=FiFo; break;} case 3: { XAkcel=FiFo; break;} case 4: { YAkcel=FiFo; break;} case 5: { ZAkcel=FiFo; break;} case 6: { Time_0=FiFo; break;} case 7: { Time_1=FiFo; break;} case 8: { Time_2=FiFo; break;}}}//Processing Data
Time = ((((Time_0 & 0xFFFFFF) << 8)) + ((Time_1 & 0xFF00)>>8));dt=(Time-Time2)*WspTime;
Time2=Time;
//If is nessesary to reset Timestamp
if((Time==0xFFFFFF)&&(WspTime==0.000025)){ i2c_Write(I2Cx, I2C_LSM6DS33_Write, 0x42,0xAA); Time2=0;}//Sensitivity G=70 mdps/LSB
dalfa=((XGyro-XOG)*dt*SensitivityG/1000); //[deg]dbeta=((YGyro-YOG)*dt*SensitivityG/1000);dgamma=((ZGyro-ZOG)*dt*SensitivityG/1000);alfa=alfa+(dalfa);beta=beta+(dbeta);gamma=gamma+(dgamma);//Sensitivity A=0.488
mg
/LSB
dSX=(0.5*(XAkcel-XOA)*SensitivityA*dt*dt*9.81/1000);
dSY=(0.5*(YAkcel-YOA)*SensitivityA*dt*dt*9.81/1000);dSz=(0.5*(ZAkcel-ZOA)*SensitivityA*dt*dt*9.81/1000);SX=SX+dSX; //[mm]
SY=SY+dSY;SZ=SZ+dSZ;A=i2c_Read(I2Cx, I2C_LSM6DS33_Address, 0x3A);
B=i2c_Read(I2Cx, I2C_LSM6DS33_Address, 0x3B);NoData
=((B&0x0F)<<8)+A;FifoFull=((B&0x20)>>5);FifoTresh=((B&0x80)>>7);FifoOverRun=((B&0x40)>>6);FifoEmpty=((B&0x10)>>4);}
Thanks for any help or guidance.
2017-11-21 03:30 AM
A few points you can take a look at:
1. Is your 'NoData' and 'FifoPattern' var. data type size at least 16 bits? If not you'd read incorrect number of samples or get unexpected data from the FIFO.
2. Is your 'C' var. data type unsigned? If not you'd actually subtract the C value from shifted D value instead of adding it (in your 'for' cycle AND in case of C > 0x7F). Same case for any 'lower' bytes readings like 'FiFoL' and so on.
3. In the 6.4 Timestamp chapter of the
http://www.st.com/resource/en/application_note/dm00175930.pdf
is stated:The timestamp resolution has to be set before enabling the timestamp functionality; a basic SW routine is as follows:
1. Write 50h into CTRL1_XL // Turn on the accelerometer, ODR_XL = 208 Hz, FS_XL = 2g2. Write 00h into WAKE_UP_DUR // Timestamp resolution = 6.4 ms3. Write 80h into TAP_CFG // Enable timestamp count4. Write 01h into MD1_CFG // End counter interrupt driven to INT1 pinSo I suggest to adapt the order of your register settings.
4. In the 6 Android embedded functions chapter
of the
http://www.st.com/resource/en/application_note/dm00175930.pdf
is stated:All these functions (list includes Timestamp) work at 26 Hz, so the accelerometer ODR must be set at 26 Hz or higher values.
So maybe try also increasing ODR_XL.
5. In the 7.8 Step counter and timestamp data in FIFO chapter
of the
http://www.st.com/resource/en/application_note/dm00175930.pdf
is stated:Follow these steps to store timestamp and pedometer data in the FIFO using either the
internal trigger (accelerometer/gyroscope data ready) or the ‘step detected’ method:1. Turn on the accelerometer;2. Enable the timestamp and pedometer (see Section 6.1 and Section 6.4);3. Choose the decimation factor for the 3rd FIFO data set through theTIMER_PEDO_DEC_FIFO[2:0] bits of the FIFO_CTRL4 register;4. Set to 1 the TIMER_PEDO_FIFO_EN bit in the FIFO_CTRL2 register;5. Configure the bit TIMER_PEDO_FIFO_DRDY in the FIFO_CTRL2 register, in order tochoose the method of storing data in the FIFO (internal trigger or every step detected);6. If an internal trigger is used, choose the FIFO ODR through the ODR_FIFO_[3:0] bits ofthe FIFO_CTRL5 register. If the ‘step detected’ trigger is used, no need to set theODR_FIFO_[3:0] bits;7. Configure the FIFO operating mode through the FIFO_MODE_[2:0] field of theFIFO_CTRL5 register.So again I suggest to adapt the order of your register settings.