ITG3200, fast i2c and 8kHz sample frequency

robtillaart:
Can you test reading 2 bytes at once? (maybe the 2 bytes should be swapped?)

int readX()

{
  int data = 0;
  Wire.beginTransmission(itgAddress);
  Wire.write( GYRO_XOUT_H);
  Wire.endTransmission();
  Wire.requestFrom(address, 2);

if (Wire.available())
  {
    data = Wire.read() << 8;
    data = data + Wire.read();
  }
  return data;
}

This does not make sense to me. The low byte and high byte are in 2 different registers. How could i get them at once from just reading the GYRO_XOUT_H (high byte) with two calls of wire.read() ?

with

Wire.requestFrom(address, 2);

you are requiring 2 byte, so because one register is 1 byte, you are reading also the next register. Pay attenn as not always register are H and the L.
If i remeber correctly the x, y and z register are all contiguus, so you can read 6 byte from the first and then send this array by serial

Ok, indeed that was the only explanation i thought of.

I'm making a few measurements, and will print out the comparisons. It seems to work. That's really good advise you're all giving. Thank you very much.

[UPDATE] : and yes, they are contiguous. 29, 30, ...

good to hear it works, now the performance figures become interesting...

So, i made some more complete measurements.

Using that the 3 coordinate-registers are contiguous to read them in "one pass" of "wire-related" function,
Using lowbyte and highbyte functions to transmit the values to Matlab through Serial,
here are the fastest sample frequencies i would get if i measure only 1, and then, 3 coordinates at the same time :

1 coordinates ; 3 coordonates

Standard I2c @100 kHz => 1.4 kHz ; 880 Hz (TWBR = 72)
Fast I2C @400 kHz => 3.8 kHz ; 2.3 kHz (TWBR = 12)
Very Fast I2C @800 kHz => 5.1 kHz ; 3.2 kHz (TWBR = 2)

Having said that, that doesn't tell me how stable it's gonna be over several iterations of the main loop.

Now my (last?) question is :

i'm sending the data through serial to a software. Should i put any delay at the end of the main loop, or use flush(), to make sure that the software has time to read things and so the buffer doesn't get filled ? If yes, i guess that would reduce my sampling freq.

Or do you think it will be stable enough to avoid any unnecessary delay(xxx), or flush() and i can just read things as they go out, at the end of each cycle with no pause in the software either ? I hope i'm being clear... if not, let me know :blush:

Thanks

dronadair:
...
Now my (last?) question is :

i'm sending the data through serial to a software. Should i put any delay at the end of the main loop, or use flush(), to make sure that the software has time to read things and so the buffer doesn't get filled ? If yes, i guess that would reduce my sampling freq.

Or do you think it will be stable enough to avoid any unnecessary delay(xxx), or flush() and i can just read things as they go out, at the end of each cycle with no pause in the software either ? I hope i'm being clear... if not, let me know

That are at least 2 questions :wink:

  1. is easy to verify with a small test (much faster than waiting on a forum answer ..)
    Any additional code will reduce the frequency.
  2. see 1

You can gain time by compressing the data before sending. but it depends on the data

  • only send the delta wrt previous value 1 byte can handle +- 127 (50% gain)
  1. on the arduino side you will see stable time give only ONE fact: when the output serial buffer is full, a write (or print, as print call write) will call a flush(), or more exaclty will wait for buffer to be empty enough. So you'll see (on an immaginary debug) firsts reading accumulate in a fast way (loop very fast), and then, once the buffer is full once, it will keep itself always full slowling down the loop at the serial max speed. No need to delay or flush by yourself, if you do so, you'll fall again the the bad "all forst sample, no older sampe"

now let's do some math:

baudare: 256.000 baud per byte: 10
256.000/10 = 25.600byte/s

if you don't compress data the every write need 6 byte, so max speed is 25.600/6=4266write/second = ~4.2KHz

that means you will never notice a slowdown caused by a serial buffer compression, and you DON'T need a compression algoritm.

Actually, i've just realised the baudrate will be a bottleneck, on the contrary. First of all, my vibration analysis will of course come with Fourier analysis. For this i'll obviously need to send the times for each measurement (any better idea than using micros() perhaps ?). That's 2 to 4 bytes more . Moreover, my setup (Matlab + serial objects + arduino pro mini 16Mhz) doesn't seem to accept serial baudrate higher than 115200 bps. Maybe because of the old laptop serial , maybe the desktop will have more luck with that. Or is it a limitation of the Pro Mini ?

I'll try a few measurements and see how far i can push my sample rate when setting a long acquisition (relatively speaking, few seconds actually).

Thank you again, you've been really helpful and helped me learn a lot in a few days.

That's a sw limitation of matlab or wathever. it also is into sw serial. But using directly the serial, with java, c or another REAL language :slight_smile:

BTW as the mesurement use only 10bit, you need 10+10+10+4*8 byte for every read, just buffer the exceeding bit :slight_smile: that way you are working on the BIT stream and not byte, i don't know if it will be enought

lesto:
That's a sw limitation of matlab or wathever. it also is into sw serial. But using directly the serial, with java, c or another REAL language :slight_smile:

BTW as the mesurement use only 10bit, you need 10+10+10+4*8 byte for every read, just buffer the exceeding bit :slight_smile: that way you are working on the BIT stream and not byte, i don't know if it will be enought

Since you mention the buffer, maybe you guys can enlighten me.
Buffering has always two sides per device. I read that the arduino boards have a hard-coded buffer size than cannot be changed within a sketch.
To me, there must be an output and input buffer, and i couldn't find a satisfying documentation specific to the arduino, just Forum threads that increase the confusion. So, what buffer am i meant to change here ?
on the PC-side, i naively assumed that whatever is sent from the arduino goes into the inputbuffer of the serial object that is opened/created by the software (Processing, Matlab, or whatever)
If i'm sending data from the arduino to the pc, what exactly is the buffer that you suggest me
to change ?
So far i extended the InputBuffer on the PC side, and things worked, no data loss, i collected the same number of bytes that were sent by the arduino. But i was not sure of what i was doing with these buffers. Just try and error till i had no data loss anymore.

well because you cannot access the underlyng (pc side and arduino side) buffer, my advise is to create a byte array to use as your own buffer, then when your buffer is ready, print it (effectively will be copied in the undeling buffer, and then camputetd by serial, a bit strange, but it works :slight_smile: )

But i was not sure of what i was doing with these buffers

simply your program does not process data from serial fast enought, and was lost because the buffer overflooded. on the PC side normally i use a thread that just read serial and put data in a syncronized list, then another thread poll this list, and if new data is available work on it. That way i don't loose data, in case the consumer thread is too slow, the list will slowly fill the ram (but filling 8GB of ram require a loooooooot of time at statndard serial speed (19200baud = 1920 byte/s), so you can debug and find bottleneck)

lesto:
well because you cannot access the underlyng (pc side and arduino side) buffer

Ok, i understand.
Well, obviously, on the PC-software side i have access to the Serial inputBuffer that does this trick since i got rid of data loss by increasing this inputBuffer size within Matlab (the latter can manipulate the Serial input and outputbuffer). So far, as long as i kept my input buffer size roughly equal to the baudrate , i never get losses, and this still preserved my sampling rates mentioned earlier.