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

MPU9250 Magnetometer does not respond #1

Closed Andyinater closed 2 years ago

Andyinater commented 3 years ago

Sorry if this is inappropriate, but your sketches work perfectly for me besides the magnetometer. I could not see anything on your blog for troubleshooting this. Do you perhaps know what can cause this? I am using this breakout board with my ESP32: https://www.amazon.ca/CANADUINO-InvenSense-Accelerometer-Magnetometer-Compatible/dp/B07M76H9CM

Any help is appreciated, danke.

wollewald commented 3 years ago

Hi @Andyinater, can you tell me more about the issue? Does is not compile, do you get wrong result or no results? That will help me to resolve it.

wollewald commented 3 years ago

@Andyinater , I have just tried it with an ESP32 and it worked. My MPU9250 looks like yours apart from the label which is MPU9250/6500 on mine and MPU92/65 on yours. But that shouldn't make any difference.

I tried the unchanged MPU_9250_all_data.ino and MPU9250_magnetometer_data.ino sketches. Which one did you try? And did you change anything?

Do you get the message "Magnetometer does not respond"?

Andyinater commented 3 years ago

Hi @wollewald, it compiles fine. When running the magnetometer example sketch "MPU9250_magnetometer_data.ino"

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

Results in the serial print "Magnetometer does not respond". Could it be because I am using custom pins for I2C? Is there a global variable I can define I2C pins? Sorry, I am very new to all of this.

wollewald commented 3 years ago

If the accelerometer and the gyroscope are working then in theory there shouldn't be an issue with your I2C settings.

If you take another sketch which also uses the accelerometer, e.g. MPU9250_all_data, do you only get the "Magnetometer does not response" message or also "MPU9250 does not respond"?

Andyinater commented 3 years ago

Only the 'Magnetometer does not respond' message, and then it proceeds to output reasonable data for accel and gyroscope, but magneto returns all 0s

wollewald commented 3 years ago

Then this might be related with the way I implemented the magnetometer. Maybe this does not work with every module. I have ordered a module which look exactly like yours. But this will take some time until they arrive. Maybe I will rewrite the library and implement an alternative way of implementing the magnetometer. But I can't promise a timeline.

wollewald commented 3 years ago

@Andyinater , I have fundamentally changed the way to retrieve magnetometer data. I have released a new version. I hope you are still motivated to try. That would help me a lot since I can't reproduce the issue with my module. Occasionally, but only after upload of sketches, you might need to disconnect from power and repower again.

Andyinater commented 3 years ago

@wollewald Wow, I did not expect such a response and I greatly appreciate it.

Unfortunately, I am still getting the same response. MPU9250 is connected, Magnetometer does not respond.

wollewald commented 3 years ago

OK - that's of course disappointing. Maybe I can reproduce and then solve the issue when I get the MPU9250 modules that I have ordered and which look more like yours. But they come from the US and that will take few weeks.

Have you tried another library and did it work? This one worked for me: https://github.com/bolderflight/mpu9250-arduino

Andyinater commented 3 years ago

For that one, I am uncertain on how to manually declare my I2C SCL and SDA pins. I attempted modifying his "mpu9250.cpp" under the method Mpu9250::Begin() by changing

i2c_->begin();

to

i2c_->begin(33,32);

Although this results in "IMU initialization unsuccessful"

Andyinater commented 3 years ago

Honestly, at this point I'm wondering if I somehow got a knock-off unit without the magnetometer in it. If every library gives me a problem, I am the problem... lol

wollewald commented 3 years ago

To be honest I was also not sure how to do that. There is no way to pass the SDA / SCL pins. I just took the Basic I2C example and it worked with the pins 18/19 like this:

#include "MPU9250.h"
TwoWire myWire = TwoWire(0);

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68
MPU9250 IMU(myWire,0x68);
int status;

void setup() {
  // serial to display data
  Serial.begin(115200);
  while(!Serial) {}
  myWire.begin(18,19);
  // start communication with IMU 
  status = IMU.begin();
.......

Good luck!

Andyinater commented 3 years ago

So, I used the library by Kris Weiner and some new info came out by probing what is called the "Who am I" register.

https://github.com/kriswiner/MPU9250/issues/458

It appears that I DO NOT have a genuine 9250, or I at least have a mislabeled (probably on purpose) 9255 or something. When I followed his advice in that issue, his library did end up producing magnetometer values, but I do not think I will be able to make use of them anyways. (for my absolute orientation desires I am now looking towards the BNO055 from Bosche)

For now, I will be continuing with your library as I find it very intuitive to use. I do have a new question though: Is there a way to retrieve the offset values generated by autoOffsets()? Mainly so I can store them in flash memory so if my device accidentally power cycles I can return to logging on the previously established offsets.

wollewald commented 3 years ago

Using the magentometer values is a bit tricky. Every cable on a breadboard influcences the measured values. In theory you could calibrate it. Just turn around in all directs and record the min/max values. Quite some effort. And you always have to calibrate whenever you change the location. I was a bit disappointed after the first experience.

Ihave not (yet) written a function like "getAutoOffsets". But you can determine them easily yourself. It's nothing sohisticated:

    accOffsetVal.x = 0.0;
    accOffsetVal.y = 0.0;
    accOffsetVal.z = 0.0;

    enableGyrDLPF();
    setGyrDLPF(MPU9250_DLPF_6);  // lowest noise
    setGyrRange(MPU9250_GYRO_RANGE_250); // highest resolution
    setAccRange(MPU9250_ACC_RANGE_2G);
    enableAccDLPF(true);
    setAccDLPF(MPU9250_DLPF_6);
    delay(100);

    for(int i=0; i<50; i++){
        getAccRawValues();
        accOffsetVal.x += accRawVal.x;
        accOffsetVal.y += accRawVal.y;
        accOffsetVal.z += accRawVal.z;
        delay(1);
    }

    accOffsetVal.x /= 50;
    accOffsetVal.y /= 50;
    accOffsetVal.z /= 50;
    accOffsetVal.z -= 16384.0;

    for(int i=0; i<50; i++){
        getGyrRawValues();
        gyrOffsetVal.x += gyrRawVal.x;
        gyrOffsetVal.y += gyrRawVal.y;
        gyrOffsetVal.z += gyrRawVal.z;
        delay(1);
    }

    gyrOffsetVal.x /= 50;
    gyrOffsetVal.y /= 50;
    gyrOffsetVal.z /= 50;

For long term storage I would recommend the other procedure I have implemented with the min / max values for the axes. It's bit more effort but a one off.

Andyinater commented 3 years ago

Thank you so much for your help, I think I will finally be able to complete my prototype.

ivicajan commented 2 years ago

HI Wolle, thanks for putting all that into nice library.

I have similar problem with different pre-defined SDA/SCL that I want to pass during the setup() phase. Is it possible to add function .setWire similar like: https://github.com/asukiaaa/MPU9250_asukiaaa/blob/master/src/MPU9250_asukiaaa.h lines 39-41

That way I could easily do something like this in dhe setup:

define SDA_PIN 21

define SCL_PIN 22

Wire.begin(SDA_PIN, SCL_PIN); myMPU9250.setWire(&Wire);

Otherwise I can do complete init inside setup: void setup() { Serial.begin(115200);

ifdef _ESP32_HAL_I2CH // For ESP32

Wire.begin(SDA_PIN, SCL_PIN); // SDA, SCL

else

Wire.begin();

endif

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

But then inside loop() it is not defined myMPU9250 and can't compile.

Thanks!

wollewald commented 2 years ago

@ivicajan , you can predefine the SDA and SCL pins and pass it to your MPU9250 object. I have tried this on an ESP32.

Like this, e.g.:

#define I2C_FREQ 400000
#define SDA_PIN 21
#define SCL_PIN 22
#define MPU9250_ADDR
TwoWire wire1 = TwoWire(1);

MPU9250_WE myMPU9250 = MPU9250_WE(&wire1, MPU9250_ADDR);

void setup() {
  wire1.begin(SDA_PIN, SCL_PIN, I2C_FREQ);
.......
ivicajan commented 2 years ago

Thanks! it's working.

Cheers, Ivica

On Sun, 26 Sept 2021 at 16:57, Wolfgang (Wolle) Ewald < @.***> wrote:

@ivicajan https://github.com/ivicajan , you can predefine the SDA and SCL pins and pass it to your MPU9250 object. I have tried this on an ESP32.

Like this, e.g.:

define I2C_FREQ 400000

define SDA_PIN 21

define SCL_PIN 22

define MPU9250_ADDR

TwoWire wire1 = TwoWire(1);

MPU9250_WE myMPU9250 = MPU9250_WE(&wire1, MPU9250_ADDR);

void setup() { wire1.begin(SDA_PIN, SCL_PIN, I2C_FREQ); .......

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/wollewald/MPU9250_WE/issues/1#issuecomment-927263418, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEN4TMAKPQTIKUQSPLZLPILUD3N67ANCNFSM45JQZZEQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

sparkplug23 commented 2 years ago

So has everyone got the magnetometer values okay now? I have tried 3 different MPU9250 boards (from 2 different sources) and both will not show me anything for the magnetometer, while the acc/gyro work okay.

wollewald commented 2 years ago

@sparkplug23, have you tried other libraries and do you get magnetometer results with these?

sparkplug23 commented 2 years ago

@sparkplug23, have you tried other libraries and do you get magnetometer results with these?

I have tried others, but the values I am getting out are completely random. It doesn't even appear to be noise, it can go from +2000 to -2000 etc on each new sample.

I dug into your library, and the function that reads the register is getting 0 for the value. _wire->available () is correctly showing as one byte, but that result (_wire->read()) is always 0.

For now, after wasting the last 2 days I've switched to another IMU I have (gy89) and am getting sensible values with it. I'll need to spend more time trying to debug the issue with the mpu9250. I briefly looked at its datasheet (though I suspect it was an abrievated version) and didn't really see the register/i2c handshake I needed to do to get the values out of the magnetometer.

Edit: to be clear. I know I need to switch registers so I can read the magnetometer etc, I just was looking thr datasheet specs so I could compare/debug against your code and my hardware.

wollewald commented 2 years ago

@sparkplug23, I know how frustrating it is to spend so much time without success. Everything works for me with modules from various souces. That makes it hard to solve the issue. If anyone sends me a module that is not working (to Germany) I am happy to dig deeper.

If you always get 0, I guess the the example sketches tell you "Magnetometer does not respond", right? If this is the case could you comment out lines 630 - 632 in MPU9250_WE.cpp and try again. It's just an idea. The code checks the devide ID of the magnetometer and if it's wrong or the register can't be read then the init function does not continue.

Regarding the data sheet, there are three documents to consider: 1) the data sheet for the MPU9250: https://3cfeqx1hf82y3xcoull08ihx-wpengine.netdna-ssl.com/wp-content/uploads/2015/02/PS-MPU-9250A-01-v1.1.pdf 2) the register map of the MPU9250: https://3cfeqx1hf82y3xcoull08ihx-wpengine.netdna-ssl.com/wp-content/uploads/2017/11/RM-MPU-9250A-00-v1.6.pdf 3) the data sheet for the magnetometer (AK8963): https://download.mikroe.com/documents/datasheets/ak8963c-datasheet.pdf

sparkplug23 commented 2 years ago

@wollewald

Apologies I forgot to respond, swamped with work right now.

I managed to get another IMU sensor I have working for now (LSM303D and L3G), but I did buy additional MPU9250 last week and they have the same issue. I will dig deeper into the code and try figure out what is happening in the near future when I get more time. Appreciate the links. I will come back and let you know when I figure the issue out.

As a slightly related question, have you ever used IMU readings and brought them into MATLAB? I got my raw register values, then in matlab converted these to the correct units (rads/s, m/s/s and uT). I am wondering about if I need to apply calibration and at what point I should be doing that, just curious if you have any tips on that.

wollewald commented 2 years ago

@sparkplug23 It's really strange. Can you send me a link for the source where you bought the MPU9250? If they deliver to Germany I might be able to also buy one.

I have tried at least three different ones as you can see on the foto below. They are all working fine, e.g. with MPU9250_all_data.ino as is. Which board / MCU do you use?

MPU9250_modules

To the other question: I have very limited experience with MATLAB and never tried to work with IMU data.

wollewald commented 2 years ago

Since I have not heard anything I close this issue now.

vladkozlov69 commented 1 year ago

Just wanted to put my 5 cents. Today I received from Ali some modules advertised as MPU9250. The magnetometer data is just 0. Acc/Gyr data seems okay. So I believe Ali sellers just got batches of MPU9250 with broken magnetometer and resells them.

wollewald commented 1 year ago

Hi @vladkozlov69 , thanks for this info. Can you run the example sketch who_am_i.ino ? Maybe you have one of the modules which have the MPU6500 (or other) instead of the MPU9250.

vladkozlov69 commented 1 year ago

Hi @wollewald here it is

WhoAmI Register: 0x75 Your device is probably an MPU6515 Not sure if it works with this library, just try

Going to give one star to the seller :)) Chip itself is clearly states it's 9250 so I believe it's fake. Fortunately I need only Acc and Gyr for my project...

wollewald commented 1 year ago

Unfortunately, it's not possible to give 0 stars to such suppliers! Thanks again for the Info!