wollewald / MPU9250_WE

An Arduino library for the 9-axis accelerometer, gyroscope and magnetometer MPU9250 and MPU6500. It contains many example sketches make it easy to use.
https://wolles-elektronikkiste.de/en/mpu9250-9-axis-sensor-module-part-1
MIT License
56 stars 26 forks source link

Possible bug inside the check part #10

Closed idea--list closed 2 years ago

idea--list commented 2 years ago

Hi Wolfgang Ewald,

Noticed an unexpected behaviour inside the

if(!myMPU9250.init()){
    Serial.println("MPU9250 does not respond");
}
  else{
    Serial.println("MPU9250 is connected");
}

part of the examples.

For some reason the WHO_AM_I register of the MPU6500 unit on my MPU92/65 board returns 0x73 instead of 0x70 and thus the sketches always returned "MPU9250 does not respond" message when my board boots up, but this left unnoticed as regardless of this all subsequent register reads/writes were successful. After changing static float constexpr WHO_AM_I_CODE = 0x70; to static float constexpr WHO_AM_I_CODE = 0x73; insideMPU6500_WE.h the check is working almost as expected. By almost i mean it works great until i am initializing an MPU6500 object. In that case MPU6500_WE::whoAmI() member function will return 0x73 that gets compared to expectedValue inside MPU6500_WE::init(uint8_t const expectedValue). However if one initializes an MPU9250 object (like the MPU9250_acceleration_data example does), then it will compare the value stored in register No.117 (WHO_AM_I register) of the MPU6500 unit to the WHO_AM_I_CODE defined inside MPU9250_WE.h, which is 0x71. Thus the check function will always evaluate as false.

Took a look inside the documentation of the registers of the MPU9250 found here. It turns out, the magnetometer (AK8963) does not even have a WHO_AM_I register. So there is no register value against which we could compare 0x71 defined as WHO_AM_I_CODE for the magnetometer inside MPU9250_WE.h.

All this is not a big issue as any subsequent register reads/writes do what they are expected to do, just renders the current check part meaningless in its current form.

wollewald commented 2 years ago

Hi @idea--list ,

there is no bug. If your device return 0x73, then it is not an original MPU6500. It might be a fake or another MPU like the MPU6515. Have look on the 24-pin square sized IC on your module. What is the label? It is very small and hard to read, so you might need a magnifying glass.

There might be also other variants out there. I can't support them all. If it works on your side, apart from the "cosmetic" issue, that the skteches return "MPU6500 does not respond", then be just happy. The only thing I might change is the response in the example sketch to "MPU6500 does not respond or it is not a MPU6500" or something else. I will also add comments to the readme sction. But I will not implement additional models.

The "who I am register" of the AK8963 is register 0x00 of the AK8963. You will not find it in the MPU9250 documentation, but in the datasheet of the AK8963, page 28: https://download.mikroe.com/documents/datasheets/ak8963c-datasheet.pdf

Hope this answers all questions.

idea--list commented 2 years ago

Hi Wolfgang,

Thank you for the fast reply and for sharing your implementation! I am really happy as your library is the best among all the different implementations one can find for mpu9250 and it spares a ton of time for me, not needing to implement it from scratch. There are no visible labels on my chip, so it is a fortune that it works. Luckily it is really just a cosmetic thing, that is why it remained unnoticed despite i am using your work for several days now. Will just skip that check if i ever initiate an MPU9250 object as 0x71 against to 0x70 (or in case my deviant IC 0x73) will never satisfy the comparison.