mpu6050, reading time of data

Status
Not open for further replies.

jacko91

Active member
Good day,
I am using a teensy 3.5 and a mpu6050.

I am using the standard code to get raw data:

Code:
#include <i2c_t3.h> 
const int MPU_ADDR = 0x68; 
int16_t accelerometer_x, accelerometer_y, accelerometer_z; // variables for accelerometer raw data
int16_t gyro_x, gyro_y, gyro_z; // variables for gyro raw data
int16_t temperature; // variables for temperature data

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
  Wire.write(0x6B); // PWR_MGMT_1 register
  Wire.write(0); // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
}
void loop() {
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
  Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
  Wire.requestFrom(MPU_ADDR, 7*2, true); // request a total of 7*2=14 registers
  
  // "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same variable
  accelerometer_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
  accelerometer_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
  accelerometer_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
  temperature = Wire.read()<<8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
  gyro_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
  gyro_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
  gyro_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)

}

I want to use the data for controlling of a self balancing robot. When checking the time needed to run the routine in the main loop, I got roughly 1.6ms. This seemed a bit too much. I then checked it with an oszi. And the time needed for the i2c data to be transmitted is 0.2ms. Now I am wondering where the rest of the time comes from. Any ideas?
 
The biggest issue I see with your code is that you should use Wire.setClock() to set the I2C speed. Right now, your code is only using 100 kHz and you should be using 400 kHz.
 
for my self balancing robot 20ms was enough (many many years ago). the hardware (motors, gears, the mass..) needed no faster speed. a nano did it. it had a raspberry (very first version) to control the nano (for remote-control etc) today I'd just use a Teensy LC or 3.2 alone.
 
why do you read the temperature?

It's silly, Invensense placed the temperature registers in between the accelerometer and gyro data registers. It's faster to do a burst read of 14 bytes (accel data, temp data, then gyro data) than two 6 byte transactions to get just the accel and gyro data.
 
Hey , thanks for your replies. Sorry the wire.setclock got lost in the copy to the forum, so i am already using 400khz. The wire.requestfrom() function needs 1.4ms to be executed. Where does the difference between this time and the measured time of 0.2 ms on the oszi come from? Is there any time consuming stuff going on in the function?
Thx
 
I dug out my MPU-9250 (essentially the same as your MPU-6050) and ran your code. My hardware setup is using 4.7kOhm resistors for pullup to +3.3V. When I run this, I get a read time (t2 - t1) of 1.6 ms as you report.

Code:
#include <i2c_t3.h> 
const int MPU_ADDR = 0x68; 
int16_t accelerometer_x, accelerometer_y, accelerometer_z; // variables for accelerometer raw data
int16_t gyro_x, gyro_y, gyro_z; // variables for gyro raw data
int16_t temperature; // variables for temperature data

unsigned long t1, t2;

void setup() {
  Serial.begin(115200);
  while(!Serial) {}
  Serial.println("1");
  Wire.begin();
  // Wire.setClock(400000);
  // Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
  // // Wire.write(0x6B); // PWR_MGMT_1 register
  // // Wire.write(0); // set to zero (wakes up the MPU-6050)
  // Wire.endTransmission(true);
}
void loop() {
  
  t1 = micros();
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
  Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
  Wire.requestFrom(MPU_ADDR, 7*2, true); // request a total of 7*2=14 registers
  
  // "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same variable
  accelerometer_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
  accelerometer_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
  accelerometer_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
  temperature = Wire.read()<<8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
  gyro_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
  gyro_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
  gyro_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)
  t2 = micros();
  Serial.println(t2 - t1);
  delay(20);
}

Simply setting the clock to 400 kHz drops my read time to 440 us.

Code:
#include <i2c_t3.h> 
const int MPU_ADDR = 0x68; 
int16_t accelerometer_x, accelerometer_y, accelerometer_z; // variables for accelerometer raw data
int16_t gyro_x, gyro_y, gyro_z; // variables for gyro raw data
int16_t temperature; // variables for temperature data

unsigned long t1, t2;

void setup() {
  Serial.begin(115200);
  while(!Serial) {}
  Serial.println("1");
  Wire.begin();
  Wire.setClock(400000);
  // Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
  // // Wire.write(0x6B); // PWR_MGMT_1 register
  // // Wire.write(0); // set to zero (wakes up the MPU-6050)
  // Wire.endTransmission(true);
}
void loop() {
  
  t1 = micros();
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
  Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
  Wire.requestFrom(MPU_ADDR, 7*2, true); // request a total of 7*2=14 registers
  
  // "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same variable
  accelerometer_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
  accelerometer_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
  accelerometer_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
  temperature = Wire.read()<<8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
  gyro_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
  gyro_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
  gyro_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)
  t2 = micros();
  Serial.println(t2 - t1);
  delay(20);
}

Maybe you weren't setting the I2C clock correctly?

From my experience with the MPU-9250, you won't get faster than the 440 us without switching to SPI, in which case you'll drop to about 20 us to read the sensor.
 
Well, as Frank said, how fast do you need it? Looks like you should be able to get 440 us via I2C. If you need faster reads, then better go with SPI.
 
Status
Not open for further replies.
Back
Top