bolderflight / invensense-imu

Arduino and CMake library for communicating with the InvenSense MPU-6500, MPU-9250 and MPU-9255 nine-axis IMUs.
MIT License
498 stars 209 forks source link

I am unable to begin communicating with my mpu9250 #101

Closed frozenmafia closed 2 years ago

frozenmafia commented 2 years ago

_s_e_sen-03-005-1 My MPU9250 looks exactly like this.

First I check i2c connections using the following code (I copied it from somewhere else):

uint8_t addrs[7] = {0};
uint8_t device_count = 0;

template <typename WireType = TwoWire>
void scan_mpu(WireType& wire = Wire) {
    Serial.println("Searching for i2c devices...");
    device_count = 0;
    for (uint8_t i = 0x68; i < 0x70; ++i) {
        wire.beginTransmission(i);
        if (wire.endTransmission() == 0) {
            addrs[device_count++] = i;
            delay(10);
        }
    }
    Serial.print("Found ");
    Serial.print(device_count, DEC);
    Serial.println(" I2C devices");

    Serial.print("I2C addresses are: ");
    for (uint8_t i = 0; i < device_count; ++i) {
        Serial.print("0x");
        Serial.print(addrs[i], HEX);
        Serial.print(" ");
    }
    Serial.println();
}

template <typename WireType = TwoWire>
uint8_t readByte(uint8_t address, uint8_t subAddress, WireType& wire = Wire) {
    uint8_t data = 0;
    wire.beginTransmission(address);
    wire.write(subAddress);
    wire.endTransmission(false);
    wire.requestFrom(address, (size_t)1);
    if (wire.available()) data = wire.read();
    return data;
}

void setup() {
    Serial.begin(115200);
    Serial.flush();
    Wire.begin();
    delay(2000);

    scan_mpu();

    if (device_count == 0) {
        Serial.println("No device found on I2C bus. Please check your hardware connection");
        while (1)
            ;
    }

    // check WHO_AM_I address of MPU
    for (uint8_t i = 0; i < device_count; ++i) {
        Serial.print("I2C address 0x");
        Serial.print(addrs[i], HEX);
        byte ca = readByte(addrs[i], WHO_AM_I_MPU9250);
        if (ca == MPU9250_WHOAMI_DEFAULT_VALUE) {
            Serial.println(" is MPU9250 and ready to use");
        } else if (ca == MPU9255_WHOAMI_DEFAULT_VALUE) {
            Serial.println(" is MPU9255 and ready to use");
        } else if (ca == MPU6500_WHOAMI_DEFAULT_VALUE) {
            Serial.println(" is MPU6500 and ready to use");
        } else {
            Serial.println(" is not MPU series");
            Serial.print("WHO_AM_I is ");
            Serial.println(ca, HEX);
            Serial.println("Please use correct device");
        }
        static constexpr uint8_t AK8963_ADDRESS {0x0C};  //  Address of magnetometer
        static constexpr uint8_t AK8963_WHOAMI_DEFAULT_VALUE {0x48};
        byte cb = readByte(AK8963_ADDRESS, AK8963_WHO_AM_I);
        if (cb == AK8963_WHOAMI_DEFAULT_VALUE) {
            Serial.print("AK8963 (Magnetometer) is ready to use");
        } else {
            Serial.print("AK8963 (Magnetometer) was not found");
        }
    }
}

void loop() {
}

I get the following output image

Now here I am only able to detect 0x68 . But magnetormeter is not detected.

Then I uploaded i2c example from your library.

Error initializing communication with IMU

If there is any information missing please tell me so that I can properly frame the question.

Thanking you.

flybrianfly commented 2 years ago

What microcontroller are you using?

frozenmafia commented 2 years ago

I am using esp32 vroom. I even failed at SPI communication. I have made connection like the following image. ESP32-30PIN-DEVBOARD

If there is any mistake please do tell me. Thanking you

flybrianfly commented 2 years ago

I'm not familiar enough with ESP32 to check the pinout without taking more time to figure out the labels. For I2C, ESP32 doesn't correctly support repeated starts, despite some attempts at reporting this bug to them. You would want to search my code for endTransmission(false) and replace it with endTransmission(). That should fix I2C communication, assuming that the wiring and everything else is good.

frozenmafia commented 2 years ago

I have edited the code

bool Mpu9250::ReadRegisters(uint8_t reg, uint8_t count, uint8_t *data) {
  if (iface_ == I2C) {
    i2c_->beginTransmission(dev_);
    i2c_->write(reg);
    // i2c_->endTransmission(false);
        i2c_->endTransmission();
    bytes_rx_ = i2c_->requestFrom(static_cast<uint8_t>(dev_), count);
    if (bytes_rx_ == count) {
      for (std::size_t i = 0; i < count; i++) {
        data[i] = i2c_->read();
      }
      return true;
    } else {
      return false;
    }
  } else {
    spi_->beginTransaction(SPISettings(spi_clock_, MSBFIRST, SPI_MODE3));
    #if defined(TEENSYDUINO)
    digitalWriteFast(dev_, LOW);
    #else
    digitalWrite(dev_, LOW);
    #endif
    #if defined(__IMXRT1062__)
      delayNanoseconds(50);
    #endif
    spi_->transfer(reg | SPI_READ_);
    spi_->transfer(data, count);
    #if defined(TEENSYDUINO)
    digitalWriteFast(dev_, HIGH);
    #else
    digitalWrite(dev_, HIGH);
    #endif
    #if defined(__IMXRT1062__)
      delayNanoseconds(50);
    #endif
    spi_->endTransaction();
    return true;
  }
}

Still same error , I think something is wrong with my sensor.

izsoandras commented 2 years ago

Hi, I have a similar problem, also with ESP32, different devboard though (Node32S), and GY-91 sensor board. The setup previously worked with another breakout board, with different library (). After I switched sensor board, the other library didn't work (https://github.com/hideakitai/MPU9250).

I found another, which reads the gyro and acc data, but not the magnetometer, and in this thread this lib was suggested (https://github.com/asukiaaa/MPU9250_asukiaaa/issues/22), but with this library it can't estabilish the communication. I tried replacing the endTransmission as you suggested, but it didn't work either.

Do you have maybe any suggestion what should I try? I'm not that familiar with low level communication, so far the libs I found worked just fine.

flybrianfly commented 2 years ago

If you run an I2C scanner does it see the sensor? Are you certain that the board is an MPU-9250 and not an MPU-6500?

izsoandras commented 2 years ago

It sees the sensor (0x68), but I looked more into it and if I'm right, the magnetometer should actually have it's unique address, I tried to bypass the acc and gyro with writing 00000010 to 0x37, but it didn't show up. If I do it with my other sensor, a 0x0C address shows up. On the chip MP92 236LA 1833 is written, so I'm pretty sure it should be MPU-9250

flybrianfly commented 2 years ago

Maybe it's a fake? You could modify my library to print out the WHO_AM_I byte, which is queried on this line: https://github.com/bolderflight/mpu9250/blob/main/src/mpu9250.cpp#L92

Or instead of returning false, modify the Begin method to return an integer based on where it is failing.