Skip to content

I2C Issues with MPU9250 Breakout Boards. #937

Closed
@mjs513

Description

@mjs513

Hardware:

Board: ?Onehorse ESP32 Dev Board?
Core Installation/update date: ?12/18/14?
IDE name: ?Arduino IDE 1.8.5?
Flash Frequency: ?80Mhz?
Upload Speed: ?921600?

Description:

I2C reads of MPU9250 are failing. Issue was identified when running a full up sketch for the 9250 and was failing on reading the whoiam register. Even if this is removed it is failing to successfully read any data. It was however identifying the correct addresses when doing a i2scan. This was tested on two different MPU9250 breakout boards. A test sketch was then implemented to do a i2c bus scan and read the who am I register for the correct value.

For the MS5637 pressure sensor, BME280 pressure sensor and the BNO055 it worked no issue. However it failed for the MPU9250.

I installed a early version of the ESP32 Core from about 02/20/17 and it successfully ran the test sketch, i.e., it read the MPU9250 fine - no issues. The 9250 should not be a special case for the ESP32 as it is not for any other boards that I have tested it on - uno, mega, due, teensy 3.2 and 3.5. Especially since it was working before. The new implementation of I2C seems to have broken something.

Sketch:

#include "Wire.h"   

#define MPU9250_ADDRESS 0x68  // Device address when ADO = 0
#define WHO_AM_I_MPU9250 0x75 // Should return 0x71

#define BNO055_ADDRESS 0x28   //  Device address of BNO055 when ADO = 0
#define BNO055_CHIP_ID          0x00    // should be 0xA0              
#define BNO055_ACC_ID           0x01    // should be 0xFB              
#define BNO055_MAG_ID           0x02    // should be 0x32              
#define BNO055_GYRO_ID          0x03    // should be 0x0F

void setup() 
{
  Serial.begin(115200);
  delay(4000);

  Wire.begin(21,22,400000); //(SDA, SCL) (21,22) are default on ESP32, 400 kHz I2C clock
  delay(1000);

  // Set up the interrupt pin, its set as active high, push-pull
  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);

  I2Cscan();// look for I2C devices on the bus
  delay(1000);

  // Read the WHO_AM_I register, this is a good test of communication
  Serial.println("MPU9250 9-axis motion sensor...");
  uint8_t c = readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);  // Read WHO_AM_I register for MPU-9250
  Serial.print("MPU9250 "); Serial.print("I AM "); Serial.print(c, HEX); Serial.print(" I should be "); Serial.println(0x71, HEX);
  // Read the WHO_AM_I register of the magnetometer, this is a good test of communication
/*
  // Read the WHO_AM_I register, this is a good test of communication
  Serial.println("BNO055 9-axis motion sensor...");
  byte c = readByte(BNO055_ADDRESS, BNO055_CHIP_ID);  // Read WHO_AM_I register for BNO055
  Serial.print("BNO055 Address = 0x"); Serial.println(BNO055_ADDRESS, HEX);
  Serial.print("BNO055 WHO_AM_I = 0x"); Serial.println(BNO055_CHIP_ID, HEX);
  Serial.print("BNO055 "); Serial.print("I AM "); Serial.print(c, HEX); Serial.println(" I should be 0xA0");
  delay(1000);
  // Read the WHO_AM_I register of the accelerometer, this is a good test of communication
  byte d = readByte(BNO055_ADDRESS, BNO055_ACC_ID);  // Read WHO_AM_I register for accelerometer
  Serial.print("BNO055 ACC "); Serial.print("I AM "); Serial.print(d, HEX); Serial.println(" I should be 0xFB"); 
  delay(1000);
  // Read the WHO_AM_I register of the magnetometer, this is a good test of communication
  byte e = readByte(BNO055_ADDRESS, BNO055_MAG_ID);  // Read WHO_AM_I register for magnetometer
  Serial.print("BNO055 MAG "); Serial.print("I AM "); Serial.print(e, HEX); Serial.println(" I should be 0x32");
  delay(1000);
  // Read the WHO_AM_I register of the gyroscope, this is a good test of communication
  byte f = readByte(BNO055_ADDRESS, BNO055_GYRO_ID);  // Read WHO_AM_I register for LIS3MDL
  Serial.print("BNO055 GYRO "); Serial.print("I AM "); Serial.print(f, HEX); Serial.println(" I should be 0x0F");
*/
}

void loop() {
  // put your main code here, to run repeatedly:

}

// simple function to scan for I2C devices on the bus
void I2Cscan() 
{
    // scan for i2c devices
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknown error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
}

  uint8_t readByte(uint8_t address, uint8_t subAddress)
{
  uint8_t data = 0;                        // `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, 1);  // Read two bytes from slave register address on MPU9250 
  data = Wire.read();                      // Fill Rx buffer with result
  return data;                             // Return data read from slave register
}

Debug Messages:

MPU9250 9-axis motion sensor...
[W][esp32-hal-i2c.c:235] i2cWrite(): Ack Error! Addr: 68
[W][esp32-hal-i2c.c:334] i2cRead(): Ack Error! Addr: 68, index 0
MPU9250 I AM FF I should be 71

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions