RTIMUlib: I2C communication with MPU-9250 flawed

Hello forums,

I observed strange behavoir of the Serial Monitor output with an MPU9250, connected to an Uno via I2C @ 115200 baud.

I use the the IMU Library of richard tech (RTIMUlib): RTIMULib-Arduino, there is also a I2C lib included

For proper usage of the MPU9250 it requires a calibration of the magnetometer, also described here.

The first time I tried the calibration, the Serial Monitor continuously streamed data from the magnetometer sensor. But unfortunately only x and y values, although according to the code also the z-vaules should be printed out. I also got these set of warnings:

"warning Arduino IDE v1.0.1+ with I2CDEV BUILTIN FASTWIRE implementation is recommended." "warning Using current Arduino IDE with Wire library is functionally limiting."

Therefore I replaced the I2C library by another one:

i2cdev

, and the error message was gone.

Now, with the new library there are no magnetometer measurement data displayed at all. Just this:

ArduinoMagCal starting
Enter s to save current data to EEPROM
ArduinoIMU calibrating device MPU-9250

Thats it. With the first i2c-library I also got something like "successfully initialized". The strange thing is, after I reinstalled the first i2c-lib again, that also doenst work anymore. I get the same serial monitor output plus the warning messages.

I also tried lowering the baud rate to 9600/4800, that doesnt work.

What the heck is going on. Should I try it with a Nano?

EDIT:

Sometimes I get double messages like this:

"ArduinoMagCal starting Enter s to save currenArduinoMagCal starting Enter s to save current data to EEPROM ArduinoIMU calibrating device MPU-9250 "

I don't know anything about your devices or the I2C libraries but I doubt if the problem has anything to do with the Serial Monitor and having that in your title may confuse people who might otherwise be able to help. You can change the title by editing your Original Post. Maybe a better title would be "Problem with MPU 9250, RTIMUlib" - but think about it carefully.

...R

It is this part of the code, which decides, whether a measurement is going to be taken or not:

bool RTIMUMPU9250::IMURead()
{
    unsigned char fifoCount[2];
    unsigned int count;
    unsigned char fifoData[12];
    unsigned char compassData[8];

    if (!I2Cdev::readBytes(m_slaveAddr, MPU9250_FIFO_COUNT_H, 2, fifoCount))
         return false;

    count = ((unsigned int)fifoCount[0] << 8) + fifoCount[1];

    if (count == 1024) {
        resetFifo();
        m_timestamp += m_sampleInterval * (1024 / MPU9250_FIFO_CHUNK_SIZE + 1); // try to fix timestamp
        return false;
    }

    if (count > MPU9250_FIFO_CHUNK_SIZE * 40) {
        // more than 40 samples behind - going too slowly so discard some samples but maintain timestamp correctly
        while (count >= MPU9250_FIFO_CHUNK_SIZE * 10) {
            if (!I2Cdev::readBytes(m_slaveAddr, MPU9250_FIFO_R_W, MPU9250_FIFO_CHUNK_SIZE, fifoData))
                return false;
            count -= MPU9250_FIFO_CHUNK_SIZE;
            m_timestamp += m_sampleInterval;
        }
    }

    if (count < MPU9250_FIFO_CHUNK_SIZE)
        return false;

    if (!I2Cdev::readBytes(m_slaveAddr, MPU9250_FIFO_R_W, MPU9250_FIFO_CHUNK_SIZE, fifoData))
        return false;

    if (!I2Cdev::readBytes(m_slaveAddr, MPU9250_EXT_SENS_DATA_00, 8, compassData))
        return false;

    RTMath::convertToVector(fifoData, m_accel, m_accelScale, true);
    RTMath::convertToVector(fifoData + 6, m_gyro, m_gyroScale, true);
    RTMath::convertToVector(compassData + 1, m_compass, 0.6f, false);

    //  sort out gyro axes

    m_gyro.setY(-m_gyro.y());
    m_gyro.setZ(-m_gyro.z());

    //  sort out accel data;

    m_accel.setX(-m_accel.x());

    //  use the fuse data adjustments for compass

    m_compass.setX(m_compass.x() * m_compassAdjust[0]);
    m_compass.setY(m_compass.y() * m_compassAdjust[1]);
    m_compass.setZ(m_compass.z() * m_compassAdjust[2]);

    //  sort out compass axes

    float temp;

    temp = m_compass.x();
    m_compass.setX(m_compass.y());
    m_compass.setY(-temp);

    //  now do standard processing

    handleGyroBias();
    calibrateAverageCompass();

    if (m_firstTime)
        m_timestamp = millis();
    else
        m_timestamp += m_sampleInterval;

    m_firstTime = false;

    return true;
}