cancel
Showing results for 
Search instead for 
Did you mean: 

LSM6DS33 => Fifo continous mode bad time values

Maciek Zawistowski
Associate II
Posted on November 18, 2017 at 16:03

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

0x08h

Time

 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 test

CTRL6_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 filter

CTRL9_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 Interrupt

WAKE_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.

1 REPLY 1
Petr S
ST Employee
Posted on November 21, 2017 at 12:30

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 = 2g

2. Write 00h into WAKE_UP_DUR // Timestamp resolution = 6.4 ms

3. Write 80h into TAP_CFG // Enable timestamp count

4. Write 01h into MD1_CFG // End counter interrupt driven to INT1 pin

So 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 the

TIMER_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 to

choose 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 of

the FIFO_CTRL5 register. If the ‘step detected’ trigger is used, no need to set the

ODR_FIFO_[3:0] bits;

7. Configure the FIFO operating mode through the FIFO_MODE_[2:0] field of the

FIFO_CTRL5 register.

So again I suggest to adapt the order of your register settings.