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...
//
}