Arduino Pro Micro and multiple MPU6050s

Hi @BanditSalandit

If you require more than two MP6050's on the Pro Micro then you'll need to use an I2C multiplexer, like this one: https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout?view=all.

You just need to double up on everything, two MPU6050 addresses, as well as variables to store the results.

Using I2C, I often find it helpful to include these wrapper functions:

void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
{
  Wire.beginTransmission(address);  // Initialize the Tx buffer
  Wire.write(subAddress);           // Put slave register address in Tx buffer
  Wire.write(data);                 // Put data in Tx buffer
  Wire.endTransmission();           // Send the Tx buffer
}

uint8_t readByte(uint8_t address, uint8_t subAddress)
{
  uint8_t data; // `data` will store the register data   
  Wire.beginTransmission(address);         // Initialize the Tx buffer
  Wire.write(subAddress);                  // Put slave register address in Tx buffer
  Wire.endTransmission(false);             // Send the Tx buffer, but send a restart to keep connection alive
  Wire.requestFrom(address, (uint8_t) 1);  // Read one byte from slave register address 
  data = Wire.read();                      // Fill Rx buffer with result
  return data;                             // Return data read from slave register
}

void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t* dest)
{  
  Wire.beginTransmission(address);   // Initialize the Tx buffer
  Wire.write(subAddress);            // Put slave register address in Tx buffer
  Wire.endTransmission(false);       // Send the Tx buffer, but send a restart to keep connection alive
  uint8_t i = 0;
        Wire.requestFrom(address, count);  // Read bytes from slave register address 
  while (Wire.available()) {
        dest[i++] = Wire.read(); }         // Put read results in the Rx buffer
}

This simplfies the code, for example to access the MPU6050 gyroscope data:

void readGyroData(uint8_t address, int16_t &gx, int16_t &gy, int16_t &gz)
{
  uint8_t rawData[6];  // x/y/z gyro register data stored here
  readBytes(address, GYRO_XOUT_H, 6, &rawData[0]);  // Read the six raw data registers sequentially into data array
  gx = (int16_t)((rawData[0] << 8) | rawData[1]) ;  // Turn the MSB and LSB into a signed 16-bit value
  gy = (int16_t)((rawData[2] << 8) | rawData[3]) ;  
  gz = (int16_t)((rawData[4] << 8) | rawData[5]) ; 
}

and the accelerometer:

void readAccelData(uint8_t address, int16_t &ax, int16_t &ay, int16_t &az)
{
  uint8_t rawData[6];  // x/y/z accel register data stored here
  readBytes(address, ACCEL_XOUT_H, 6, &rawData[0]); // Read the six raw data registers into data array
  ax = (int16_t)((rawData[0] << 8) | rawData[1]) ;  // Turn the MSB and LSB into a signed 16-bit value
  ay = (int16_t)((rawData[2] << 8) | rawData[3]) ;  
  az = (int16_t)((rawData[4] << 8) | rawData[5]) ; 
}

You can then call on these functions, specifying which MPU6050s you're accessing in the loop():

#define MPU_ADDRESS_1 0x68              // MPU6050 addresses
#define MPU_ADDRESS_2 0x69

int16_t gx1, gy1, gz1, ax1, ay1, az1;   // Define MPU6050 result variables
int16_t gx2, gy2, gz2, ax2, ay2, az2;

void setup() 
{
  // Initialisation code goes here..,  
}

void loop()
{
  // ... 
  readGyroData(MPU_ADDRESS_1, gx1, gy1, gz1);   // Read gyro data from MPU6050 1
  readGyroData(MPU_ADDRESS_2, gx2, gy2, gz2);   // Read gyro data from MPU6050 2
  readAccelData(MPU_ADDRESS_1, ax1, ay1, az1);  // Read accelerometer data from MPU6050 1
  readAccelData(MPU_ADDRESS_2, ax2, ay2, az2);  // Read accelerometer data from MPU6050 2
  //
  // Process the gyro and accelerometer data... gx1, gy1, etc...
  //
}