jrowberg / i2cdevlib

I2C device library collection for AVR/Arduino or other C++-based MCUs
http://www.i2cdevlib.com
3.91k stars 7.52k forks source link

class MPU9250' has no member named 'dmpInitialize' (BUG?) #617

Open fanlessfan opened 2 years ago

fanlessfan commented 2 years ago

Hello,

I am trying to use MPU9250 Arduino Library. I see the uint8_t dmpInitialize(); in line 902 of MPU9250.h, but I can't find it in MPU9250.cpp and have a compile error of class MPU9250' has no member named 'dmpInitialize'.

Is this a bug?

thx

ZHomeSlice commented 2 years ago

@fanlessfan Note the MPU6050 library has the latest DMP 6.12 and handles all the MPU families including your MPU9250 {Tested}.

Note: The AK8963 magnetometer can be read separately at 1 reading per second. The AK8963 Magnetometer is on a separate i2c address and all you need to do is activate the passthrough feature of the MPU9250 to gain access to it. Documentation for the AK8963 magnetometer is at the bottom of the MPU9250 register map.

AK8963 Datasheet

Z

jrowberg commented 2 years ago

Strictly speaking, this is a bug; somebody mirrored the MPU6050 class header into a separate specific class for the MPU9250, but not all of the implementations form the class source file made it in. As @ZHomeSlice said, it may be easier to use the MPU6050 implementation directly.

fanlessfan commented 2 years ago

Thank you @jrowberg . Thanks you @ZHomeSlice

@ZHomeSlice I tried to use MPU6050 class for MPU9250. the output seems wrong. I put MPU6050 and MPU9250 side by side and set the I2C address to 0x68 and 0x69 using the same example code MPU6050_DMP6_ESPWiFi.ino (https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050/examples/MPU6050_DMP6_ESPWiFi). for the Yaw, Pitch, Roll output the MPU6050 is good with drifted Yaw. When I put it flat in a desk it's roughly (0,0,0) and when I point Y axis to the ground roll become -90 (0,0-90) which is perfect. But when I use MPU9250, the initial is roughly (0,180,180) and when I point Y axis to the group the roll is 150 instead of the correct 90 degree. And Pitch is the same changing 30 degree for 90 degree change. the yaw seems ok and no drift. Do you have any idea of it?

thx

ZHomeSlice commented 2 years ago

I am experimenting with the ESP8266 at this time. I haven't had a chance to test the MPU6050_DMP6_ESPWiFi). but that won't take long :) Z

jaggzh commented 1 year ago

@fanlessfan Did you ever get the mpu9250 working? I had too many issues with the mpu6050, when needing it on its side at least -- my x and/or y would drift (they'd keep returning to a single value -- that is, you move it, it'd pulse, then drift back quickly). I did calibrations, etc.

Thankfully I had one 9250 around, BUT, I want to get Yaw Pitch Roll or Euler rotations out of it, and am struggling with how to include the MotionApps{anything} for it. The header has #ifdef MPU9250_INCLUDE_DMP_MOTIONAPPS20 (and one for "9250...41"), but there's only a MPU9150_INCLUDE_DMP_MOTIONAPPS20 (note the 9150), which is in the MPU9150 i2cdevlib directory.

While I'm not sure how to use it still, according to Invensense (according to this post https://sureshjoshi.com/embedded/invensense-imus-what-to-know):

The MPU-6050 is higher power, lower noise, and larger package versus the MPU-6500. Most of your code should port over, but some low power features are different and will need to be recoded in. Basic data acquisitions shouldn’t have changed. The MPU-9150 contains the MPU-6050 and an AK8975 magnetometer from AKM. The MPU-9250 contains a MPU-6500 and AK8963. The same differences between gyro/accel are the same you see with 6050 v. 6500. The magnetometer on the MPU-9250 is a little better across the board.

Sigh.

ZHomeSlice commented 1 year ago

MPU9250 is an MPU6500 with an internal Magnetometer attached to the secondary I2c bus MPU9150 is an MPU6050 with an internal Magnetometer attached to the secondary I2c bus The only programming difference is the location of the calibration registers These lines of code determine where to store this data:

MPU6050.cpp line 2913, for discovering the save address for the getXAccelOffset Routine uint8_t SaveAddress = ((getDeviceID() < 0x38 )? MPU6050_RA_XA_OFFS_H:0x77); // MPU6050,MPU9150 Vs MPU6500,MPU9250 also found on 2918, 2925, 2930, 2937, and 2942

MPU6050.cpp line 3311 for discovering the save address for the PID calibration routine uint8_t SaveAddress = (ReadAddress == 0x3B)?((getDeviceID() < 0x38 )? 0x06:0x77):0x13;

MPU6050.cpp line 3374 for reading the offset registers

int16_t * MPU6050_Base::GetActiveOffsets() {
    uint8_t AOffsetRegister = (getDeviceID() < 0x38 )? MPU6050_RA_XA_OFFS_H:0x77;
    if(AOffsetRegister == 0x06) I2Cdev::readWords(devAddr, AOffsetRegister, 3, (uint16_t *)offsets, I2Cdev::readTimeout, wireObj);
    else {
        I2Cdev::readWords(devAddr, AOffsetRegister, 1, (uint16_t *)offsets, I2Cdev::readTimeout, wireObj);
        I2Cdev::readWords(devAddr, AOffsetRegister+3, 1, (uint16_t *)(offsets+1), I2Cdev::readTimeout, wireObj);
        I2Cdev::readWords(devAddr, AOffsetRegister+6, 1, (uint16_t *)(offsets+2), I2Cdev::readTimeout, wireObj);
    }
    I2Cdev::readWords(devAddr, 0x13, 3, (uint16_t *)(offsets+3), I2Cdev::readTimeout, wireObj);
    return offsets;
}

I have helped jeff adapt the MPU6050.cpp portion of the library to work with all the MPU6500 and MPU6050 families. There is no need for a separate library for the MPU9150 and the MPU9250 or MPU9255

If you wish to access the Magnetometer you can activate the i2c passthrough and directly manipulate the Magnetometer. Note: The eDMP firmware does not interact with the magnetometer internally! This limits the current code to 6 Degrees of freedom. Invensense has a pre-compiled library that must be run on the Arduino that integrates the magnetometer values but I have not succeeded in compiling this in a way that allows for the Arduino to use it.

Z