Speed with ITG3200 and ADXL345 (I2C)

Hello people,

While I’m solving a problem with my HMC5843, I would like to ask about a concern I have regarding the rate I can read my gyroscope (ITG3200) and accelerometer (ADXL345).

I use an Arduino Uno, and in my testing, I found that it takes about 1ms to read each sensor via I2C and cast the two bytes into an integer (casting is very fast, it’s still approxmately 1ms without casting). I’ve left the I2C settings at default as with the Wire library and I use the polling method (not the interrupt method).

Since reading each sensor in turn will take 2ms, it seems the maximum frequency I can run my loop at is 500Hz which is too slow for the AHRS I’m building. (2ms is not even considering the other sensor and the calculations the processor has to do!)

Considering how the ITG3200 can have an internal sampling rate of 8kHz and the ADXL345 3.2kHz, I seriously doubt 1ms is the shortest time it takes for each read!

Is there a software change I should make to read the sensors more quickly?

Here’s the I2C read code I wrote:

void readFrom(int device_address, byte register_address, int byte_number, byte buffer[]) {
      Wire.beginTransmission(device_address); //Start transmission to device
      Wire.send(register_address); //Sends register address
      
      int x = Wire.endTransmission();
      if (x != 0) { //Check for errors
            ready_status = 0;
            Serial.println(x);
      }
      Wire.beginTransmission(device_address); //Start transmission to device again
      Wire.requestFrom(device_address, byte_number); //Request number of bytes from device
      int i = 0;
      while (Wire.available()) { //When device is still attempting to send bytes
            buffer[i] = Wire.receive(); //Receive 1 byte
            i++;
      }
      x = Wire.endTransmission();
      if (x != 0) { //Check for errors
            ready_status = 0;
            Serial.println(x);
      }
}

And here’s the function I wrote to read and cast the ITG3200 data:

void readGyroscope() {
      readFrom(GYRO_ADDRESS, GYRO_DATA_REG, GYRO_BYTES, gyro_buffer);
      
      angular_velocity[0] = (((int)gyro_buffer[0]) << 8) | gyro_buffer[1];
      angular_velocity[1] = (((int)gyro_buffer[2]) << 8) | gyro_buffer[3];
      angular_velocity[2] = (((int)gyro_buffer[4]) << 8) | gyro_buffer[5];
}

Thank you!

Bo Xuan

Hi Bo, sorry to hear you still have issues with the HMC5843.. I gave you all the suggestions I could.. I'm out of ideas on that one.

Regarding your question here.. you might want to have a look here: http://harleyhacking.blogspot.com/2009/10/adxl345-at-full-speed-32khz-on-arduino.html

The guy above claim to have achieved 3.2kHz with Arduino and the ADXL345.

Never tested it, I'm currently sampling my 9DOM MARG IMU at 25Hz which looks ok for what I need to do (HCI).

The I2C drivers on the arduino run at the standard speed of 100KHz. Now more modern I2C devices can run faster, typical is 400KHz. In the I2C library there is a line which defines the speed so you could try changing that.

Wow thanks Grumpy_Mike! That worked really well! I previously tried including a line to redefine the TWBR but that didn't work so I thought changing that the library wouldn't work too! The time for each read has now dropped to 380 microseconds!

Oddly, this still isn't fast enough to achieve 3.2kHz (for the ADXL345 alone) though. Is there anything else I have to change to achieve that kind of speed? There'll be three sensors on the bus and some pretty intensive math so I really need all the speed I can get. I'm aiming to have each loop completed within 2ms.

Bo Xuan

Fabio,

Do you do any integration (mathematical) with your 9DOF IMU? If you integrate at 25Hz (i.e. using 0.04s steps), would the drift be larger/faster?

If I'm not wrong, using smaller time steps will be more akin to true integration and therefore give a more accurate result for an ideal sensor. But I'm not very sure how this will affect drift considering the noise from the sensors.

Bo is talking about this: http://www.varesano.net/blog/fabio/initial-implementation-9-domdof-marg-imu-orientation-filter-adxl345-itg3200-and-hmc5843-a

You can find all the math stuff from: http://diydrones.com/profiles/blogs/dcm-imu-theory-first-draft http://code.google.com/p/imumargalgorithm30042010sohm/downloads/list http://www.x-io.co.uk/res/doc/an_efficient_orientation_filter_for_inertial_and_inertialmagnetic_sensor_arrays.pdf

Note that I did not designed those algorithm so I'm (still) not aware of the math behind them... but above you should have everything you need.