So I have three MPU9250s connected to a single ESP32 board and I'm trying to print the address of each MPU9250. The problem I keep running into is that only one address is being discovered despite there being three MPU9250s connected to the ESP32. I've connected each MPU9250 one by one to check if their being acknowledged and they were, all sensors are working fine. But when you connect all three devices only one device gets discovered.
#include <Wire.h>
byte errorResult; // error code returned by I2C Wire.endTransmission
byte i2c_addr; // I2C address being pinged
byte lowerAddress = 0x08; //I2C lowest valid address
byte upperAddress = 0x7F; //I2C lowest valid address
byte numDevices;
void setup() {
Wire.begin();
Serial.begin(115200);
}
void loop() {
Serial.println("Scanning I2C 7-bit address range 0x");
if (lowerAddress < 0x10)
Serial.print("0");
Serial.print(lowerAddress, HEX);
Serial.print(" to 0x");
Serial.print(upperAddress, HEX);
Serial.println(".");
numDevices = 0;
for (i2c_addr = lowerAddress; i2c_addr <= upperAddress; i2c_addr++) {
Wire.beginTransmission(i2c_addr); // initiate communication at current address
errorResult = Wire.endTransmission(); // if device is present, it will send an acknowledge "0"
if (errorResult == 0) { // "0" means device has acknowledged the serial
Serial.print("I2Cbdevice found at address 0x");
if (i2c_addr < 0x10)
Serial.print("0"); // pad string with a leading "0"
Serial.print(i2c_addr, HEX);
numDevices++;
}
}
Serial.print("Scan complete, Devices found: ");
Serial.println(numDevices);
Serial.println("");
delay(10000);
}
Serial print:
Scanning I2C 7-bit address range 0x08 to 0x7F.
I2 bdevice found at address 0x68
Scan complete, Devices found: 1
Scanning I2C 7-bit address range 0x08 to 0x7F.
I2C device found at address 0x68
Scan complete, Devices found: 1
The MPU-9250 can have one of only two addresses, 0x68 or 0x69, depending on the logic state of the address select input, AD0. The details are in the data sheet.
To use three sensors, the AD0 pins must be connected to 3.3V I/O pins and set so that only one sensor is addressed at a time (e.g. at address 0x68, with the other two set to 0x69).
An example where the AD0 of each sensor is controlled by a ESP32:
// Select a MPU-6050 by changing its I2C address runtime.
//
// This Wokwi project: https://wokwi.com/projects/394777263927329793
//
// A MPU-6050 can have I2C address 0x68 or 0x69.
// Only the active sensor is set at 0x68, while the others are at 0x69.
//
// Warning: This is only possible with a 3.3V board.
// A output pin with 5V output may not be connected to AD0
//
#include <Wire.h>
#define NUM_MPUS 4
const int AD0pin[NUM_MPUS] = {16, 17, 18, 19};
void setup() {
Serial.begin(115200);
Serial.println("Click on a MPU-6050 module and change the acceleration.");
for(int i=0; i<NUM_MPUS; i++)
{
pinMode(AD0pin[i],OUTPUT);
digitalWrite(AD0pin[i],HIGH); // default high for 0x69
}
Wire.begin(); // default pins, SDA=21, SCL=22.
for(int i=0; i<NUM_MPUS; i++)
{
SelectMPU(i);
Wire.beginTransmission(0x68);
Wire.write(0x6B); // power register
Wire.write(0); // turn sensor on
Wire.endTransmission(true);
}
}
void loop()
{
// Get the acceleration
int ax, ay, az;
for(int i=0; i<NUM_MPUS; i++)
{
SelectMPU(i);
Wire.beginTransmission(0x68);
Wire.write(0x3B); // first register address for acceleration
Wire.endTransmission();
Wire.requestFrom(0x68,6); // x,y,z, two bytes each.
ax = Wire.read()<<8 | Wire.read();
ay = Wire.read()<<8 | Wire.read();
az = Wire.read()<<8 | Wire.read();
Serial.printf("MPU %d = %d,%d,%d\r\n", i, ax, ay, az);
}
Serial.println("---------------------------");
delay(1500);
}
// Choose a MPU, parameter starts at zero.
// AD0 = high, address = 0x69, not selected
// AD0 = low, address = 0x68, selected
void SelectMPU(int selection)
{
for(int i=0; i<NUM_MPUS; i++)
{
if(i == selection)
digitalWrite(AD0pin[i],LOW); // selected, 0x68
else
digitalWrite(AD0pin[i],HIGH); // not selected, 0x69
}
}