0
\$\begingroup\$

I configure a L3G4200D gyroscope with an Output Data Rate of 100 Hz and a program reads the raw values from the registers (X, Y, Z axis) every 5 ms.

But if the program runs at 200 Hz (i.e. loops every 5 ms) and the gyroscope outputs new values at 100 Hz, then does it that mean that the program (always) reads the very same values every 2 program loops?

\$\endgroup\$
  • \$\begingroup\$ This is really easy to check, just compare the value of the first with the preceding value on all data points. If your answer is zero than yes. \$\endgroup\$ – laptop2d Aug 23 '16 at 20:06
  • \$\begingroup\$ That is actually intriguing, because I sent each X axis value (for example) to a Serial Monitor window and I never get the repeated values, as expected. \$\endgroup\$ – tozheneznayu Aug 23 '16 at 20:11
  • 1
    \$\begingroup\$ If you're sending to a serial terminal - from the same process - that itself may take longer than 5 ms... try confirming the program's rate while doing so, e.g. with an oscilloscope \$\endgroup\$ – Brian Drummond Aug 23 '16 at 20:14
  • \$\begingroup\$ Yes, the 'Serial.print' messes up with the loop. I am struggling how to capture these values to be even able to compare them. \$\endgroup\$ – tozheneznayu Aug 23 '16 at 20:23
  • \$\begingroup\$ Use the interrupt and FIFO wisely. Only after configuring the Interrupt,you will get correct data at anticipated sampling rate. \$\endgroup\$ – ammar.cma Aug 23 '16 at 22:42
0
\$\begingroup\$

I left FIFO disabled by default. I avoided the interference of 'Serial.print' with every single cycle by first concatenating 8 values in a string over 8 cycles and then print the string once after 8 cycles (sacrificing one cycle time).

k = 1;

void loop()
{

 //get values from L3G4200D, e.g. RawX

 output += k;
 output += ": ";
 output += RawX;
 output += ", ";
 k++;

 if (k == 9)
   {
    Serial.println(output);
    output = "";
    k = 1;
   }

 //trim cycle time to 5 ms
}

The result (a visual proof I was looking for) can be seen as follows:

1: -14.10, 2: -14.10, 3: -7.10, 4: -7.10, 5: -7.10, 6: -11.10, 7: -11.10, 8: 14.90, 1: 14.90, 2: -15.10, 3: -15.10, 4: -22.10, 5: -22.10, 6: -11.10, 7: -8.10, 8: -8.10, 1: -4.10, 2: -4.10, 3: 7.90, 4: 7.90, 5: -8.10, 6: -8.10, 7: -33.10, 8: -33.10, …

Increasing the loop frequency to 400 Hz (i.e. 2.5 ms) gives most of the time 4 identical values in a row. Sometimes you also see groups of 2 or 3 identical in-between. This "out-of-synch" can perhaps be corrected by working with FIFO registers, as pointed out by ammar.cma.

Hope it helps others using this specific gyroscope.

\$\endgroup\$
  • \$\begingroup\$ Please check the output with the approach and let me know if it works. \$\endgroup\$ – ammar.cma Aug 26 '16 at 16:56
0
\$\begingroup\$

One look at the datasheet suggests it has enough ammunition to serve the purpose.

The approach to sync the data from the sensor and the controller loop is : Whenever the data is ready in the sensor's register it generates a event/interrupt on a pin. This notifies the controller to pick up data.

To solve your problem :

Try this first approach - I'm not sure if this will work. Datasheet doesn't mention anywhere about this DRDY bit in detail. But give it a shot.

Enable/Set the I2_DRDY Bit in CTRL_REG3 and connect the physical DRDY pin to pin 2 or 3 on arudino uno.

void setup{
attachInterrupt(0,data_pickup,RISING); /* Assuming the DRDY Pin generates a rising edge when data is ready, if it generates falling edge, put falling*/
}


void loop(){
do nothing
/*For example */
if(flag==1){SPI.begin();
SPI.write(yyy);
SPI.end();

}


void data_pickup(){ 
/*initiate a SPI/I2C transcation here and pickup data into your program now.
I prefer to put a flag variable here and set it to true and do other things in loop*/ For example
flag=1;
}

Now coming to second approach that will save some time for arduino to do other things while the data is being put into internal FIFO is like this

Configure FIFO registers to enable. Set a FIFO Threshold and use the interrupt again to start reading. But this time, you have to read 31 samples in a burst read. You still need to connect DRDY pin to arduino and use the interrupt code as above.

Enable I2_WTM bit in CTRL_REG3 for watermark FIFO level

Enable FIFO_EN in CTRL_REG5 for FIFO to enable.

Set the FIFO_CTRL_REG to 01011111 This will put FIFO in stream mode and it has FIFO threshold set to 31 samples. You can tinker with the number of samples you want by setting lower 5 bits.

The above code approach will remain same, except now you need to do a burst read for 31 samples.

I would suggest you try the first approach initially, as it will ensure, whenever the ADC samples, it will generate the interrupt and you pick up the data.

the latter approach is when you want conserve power and optimize the system.

To know more about interrupts : Look for Arduino documentation and learn about it. Google it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.