kriswiner / MPU9250

Arduino sketches for MPU9250 9DoF with AHRS sensor fusion
1.02k stars 469 forks source link

Magnetometer only returns zeros #82

Open Kryzzalid opened 7 years ago

Kryzzalid commented 7 years ago

Hi!

Your page is a great resource and help for the MPU-9250. I have been trying for a while to get the MPU-9250 to work with a TM4C123 (Tiva C) via an IIC connection. I get the right answer (0x71) from the WHO_AM_I inquiry and also from the magnetometer's WHO_AM_I (0x48). I can read the values of the accelerometer and the gyroscope but the magnetometer only gives 0 on the 3 axis. I haven't calibrated anything yet since the magnetometer does not work.

My initialization is:

I2CSend(MPU9250_ADDRESS, PWR_MGMT_1, 0x01); // Auto-selecting best clock source
SysCtlDelay(80000*10); 
I2CSend(MPU9250_ADDRESS, INT_PIN_CFG, 0x02); // Bypass enable
SysCtlDelay(80000*10);                                                   // about 10ms delay
I2CSend(MAG_ADDRESS, MAG_CNTL_1, 0x16);          // values on 16-bits and Continuous measurement mode 2 (100Hz)
SysCtlDelay(80000*10);

I read the values of the x-axis of the magnetometer the following way:

mx_1 = I2C2Receive(MAG_ADDRESS, MAG_XOUT_H);
mx_2 = I2C2Receive(MAG_ADDRESS, MAG_XOUT_L);
m_x = (float)((mx_1 << 8) | mx_2);

mx_1, mx_2 and m_x are defined as uint16_t The preprocessor macros are:

#define MAG_ADDRESS     0x0C
#define MAG_XOUT_L      0x03
#define MAG_XOUT_H      0x04
#define MAG_YOUT_L      0x05
#define MAG_YOUT_H      0x06
#define MAG_ZOUT_L      0x07
#define MAG_ZOUT_H      0x08
#define MAG_CNTL_1      0x0A
#define MAG_CNTL_2      0x0B

#define MPU9250_ADDRESS 0x68
#define PWR_MGMT_1        0x6B
#define PWR_MGMT_2        0x6C
#define INT_PIN_CFG          0x37

I also tried with different values of delay. I noticed if I use the PWR_MGMT_2 the magnetometer stops functioning and returns -1 on the 3 axis. I'm using CJMCU 10DOF 9 Axis MPU9250 + BMP180 Sensor Module (picture front, picture back). The physical connections are: SDA --> tiva SDA SCL --> tiva SCL AD0 --> GND NCS --> VCC (3.3V) +3V3 --> VCC GND --> GND common to all circuits (Tiva, module) since I use an external 3.3V power supply

Would you have any idea why it doesn't work? I really hope you can help. Thank you very much for your time!

kriswiner commented 7 years ago

Shouldn't this line:

m_x = (float)((Ax_1 << 8) | Ax_2);

read:

m_x = (float)((mx_1 << 8) | mx_2);

???

-----Original Message----- From: Kryzzalid [mailto:notifications@github.com] Sent: October 30, 2016 9:59 AM To: kriswiner/MPU-9250 Subject: [kriswiner/MPU-9250] Magnetometer only returns zeros (#82)

Hi!

Your page is a great resource and help for the MPU-9250. I have been trying for a while to get the MPU-9250 to work with a TM4C123 (Tiva C) via an IIC connection. I get the right answer (0x71) from the WHO_AM_I inquiry and also from the magnetometer's WHO_AM_I (0x48). I can read the values of the accelerometer and the gyroscope but the magnetometer only gives 0 on the 3 axis. I haven't calibrated anything yet since the magnetometer does not work.

My initialization is:

I2CSend(MPU9250_ADDRESS, PWR_MGMT_1, 0x01); // Auto-selecting best clock source SysCtlDelay(80000_10); I2CSend(MPU9250_ADDRESS, INT_PIN_CFG, 0x02); // Bypass enable SysCtlDelay(80000_10); // about 10ms delay I2CSend(MAG_ADDRESS, MAG_CNTL_1, 0x16); // values on 16-bits and Continuous measurement mode 2 (100Hz) SysCtlDelay(80000*10);

I read the values of the x-axis of the magnetometer the following way:

mx_1 = I2C2Receive(MAG_ADDRESS, MAG_XOUT_H); mx_2 = I2C2Receive(MAG_ADDRESS, MAG_XOUT_L); m_x = (float)((Ax_1 << 8) | Ax_2);

mx_1, mx_2 and m_x are defined as uint16_t The preprocessor macros are:

define MAG_ADDRESS 0x0C

define MAG_XOUT_L 0x03

define MAG_XOUT_H 0x04

define MAG_YOUT_L 0x05

define MAG_YOUT_H 0x06

define MAG_ZOUT_L 0x07

define MAG_ZOUT_H 0x08

define MAG_CNTL_1 0x0A

define MAG_CNTL_2 0x0B

define MPU9250_ADDRESS 0x68

define PWR_MGMT_1 0x6B

define PWR_MGMT_2 0x6C

define INT_PIN_CFG 0x37

I also tried with different values of delay. I noticed if I use the PWR_MGMT_2 the magnetometer stops functioning and returns -1 on the 3 axis. I'm using CJMCU 10DOF 9 Axis MPU9250 + BMP180 Sensor Module (picture front http://bsfrance.fr/documentation/images_erp/10702/CJMCU_IMU10DO_BMP280_3.pn g , picture back http://bsfrance.fr/documentation/images_erp/10702/CJMCU_IMU10DO_BMP280_5.pn g ). The physical connections are: SDA --> tiva SDA SCL --> tiva SCL AD0 --> GND NCS --> VCC (3.3V) +3V3 --> VCC GND --> GND common to all circuits (Tiva, module) since I use an external 3.3V power supply

Would you have any idea why it doesn't work? I really hope you can help. Thank you very much for your time!

You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU-9250/issues/82 , or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qkkYeysopYeYfrAC0dNOb FTvyMrYks5q5MzUgaJpZM4KkbbE . https://github.com/notifications/beacon/AGY1qtvE8SDDnZA6PtpurWbq_LkQ-1cMks5 q5MzUgaJpZM4KkbbE.gif

Kryzzalid commented 7 years ago

Oups sorry, my bad. Yes it should. I changed the names of the variables here to make it clearer to explain. I used Ax_1 and Ax_2 in my original program.

kriswiner commented 7 years ago

So, does it work now?

-----Original Message----- From: Kryzzalid [mailto:notifications@github.com] Sent: October 30, 2016 10:19 AM To: kriswiner/MPU-9250 Cc: Kris Winer; Comment Subject: Re: [kriswiner/MPU-9250] Magnetometer only returns zeros (#82)

Oups sorry, my bad. Yes it should. I changed the names of the variables here to make it clearer to explain. I used Ax_1 and Ax_2 in my original program.

You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU-9250/issues/82#issuecomment-257164467 , or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qhAmnbIcnDv2CgQ1NWxWV O2RKFgvks5q5NGFgaJpZM4KkbbE . https://github.com/notifications/beacon/AGY1qiH5cdTDDnFPO9G0EOTpHiFIXfT2ks5 q5NGFgaJpZM4KkbbE.gif

Kryzzalid commented 7 years ago

No, that wasn't the problem. I just made a stupid mistake when changing the name of the variables here. In my program it is Ax_1 and Ax_2. But I thought mx_1 and mx_2 would be more explicit.

kriswiner commented 7 years ago

Your conversions are wrong, mx_1 and mx_2 should be uint8_t since they are just register reads (bytes), then m_x should be int16_t, and m_x = ((int16_t) mx_1 << 8) | mx_2;

Then you can set float Mx = (float) m_x;

Don't know if this is your problem though. If you can read thr WHO_AM_I refister successfully you should be able to read the data/ Are you also reading the Status register each time? You might need to leave a few tens of milliseconds for the I2C transaction to complete. I have no trouble reading mag data with the sketchin my github repository.

kriswiner commented 7 years ago

The other thing is, these CJMCU modules (the purple ones) are crap; I bought two and got crazy values from the mag.

kriswiner commented 7 years ago

You need to read the seven bytes starting with MX_L:

define MAG_XOUT_L 0x03

define MAG_XOUT_H 0x04

define MAG_YOUT_L 0x05

define MAG_YOUT_H 0x06

define MAG_ZOUT_L 0x07

define MAG_ZOUT_H 0x08

define MAG_CNTL_1 0x0A

each time you read data; the last byte must be read or the device won't work properly. Check the AK8963C data sheet.

Kryzzalid commented 7 years ago

Thank you for your fast answer! Thank you for pointing out the conversion problem. I corrected it but like you said it wasn't the problem. I read all the seven bytes like you suggested with >10ms delay after each reading and sending but it didn't help. So, I tried to read in a loop all the magnetometer values:

WHO_AM_I (0x00) which gives 0x48 INFO (0x01) which gives 0x9a the status ST1 (0x02) which gives 0x00 the values of the magnetometer (0x03 to 0x08) which give 0,0,0 Status ST2 (0x09) which gives 0x00 CNTL_1 (0x0A) which gives 0x00 CNTL_2 (0x0C) which gives 0x00

I don't know what the INFO value is but when it is going all wrong, -1 value everywhere, it gives 0xFF. I'm worried about the CNTL_1. If I set it to 0x16 and read it right after a delay it gives some weird values like 0x4f, 0x33,0x7B, etc.. I kind of knew that a cheap CJMCU could be bring more trouble. So, I also bought an other module, GY-9250, which is a MCU-9255, but all the values from gyroscope, accelerometer are -1 and the magnetometer gives 0 with the same code. I can read the WHO_AM_I from the module and the AK8963 (0x73, 0x48). I thought I may just keep trying with the CJMCU.

Kryzzalid commented 7 years ago

I mentioned it earlier but when I try to send any value to PWR_MGMT_2, 0x00, 0x3F, etc... The modules' magnetometers stop working, return 0xFF to all registers from WHO_AM_I to CNTL_2 (-1 for magnetometers values). I can read it and it always returns 0x00. I think there might be a problem in that. Especially because both of them react the same way. The only way to get the magnetometers to "work" again is to remove command that changes the PWR_MGMT_2 register, physically power down the module and turn on again. Software reset (PWR_MGMT_1 to 0x80) doesn't work.

kriswiner commented 7 years ago

Well, you have four options as I see it:

1) keep struggling to get these devices to work with your own code and MCU.

2) use known good code (like the ones I have on github) with your devices and MCU

3) use known good devices like these (https://www.tindie.com/products/onehorse/mpu9250-teensy-3x-add-on-shields/ ) with your MCU

4) get a Teensy and do 2) and 3).

Not sure I can help you with 1), I don't have the time to debug your code and I gave up on CJ (means Chinese Junk) a long time ago to make my own.

Sorry I can't be of more help.

Kris

-----Original Message----- From: Kryzzalid [mailto:notifications@github.com] Sent: October 31, 2016 2:42 AM To: kriswiner/MPU-9250 Cc: Kris Winer; Comment Subject: Re: [kriswiner/MPU-9250] Magnetometer only returns zeros (#82)

I mentioned it earlier but when I try to send any value to PWR_MGMT_2, 0x00, 0x3F, etc... The modules' magnetometers stop working, return 0xFF to all registers from WHO_AM_I to CNTL_2 (-1 for magnetometers values). I can read it and it always returns 0x00. I think there might be a problem in that. Especially because both of them react the same way.

You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU-9250/issues/82#issuecomment-257251154 , or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qj4UCOkDOzt-7qV2o6Jhj 3GPxPKgks5q5bgDgaJpZM4KkbbE . https://github.com/notifications/beacon/AGY1qm5U-ZwWROEpA-b5v1BfQwYWBvkbks5 q5bgDgaJpZM4KkbbE.gif

Kryzzalid commented 7 years ago

Thank you for your help. I have also some experience with CJ. But when you don't have the money to buy good stuff, they are better than nothing. So, I decided to check my code and struggle with it a bit more. And the problem was in the IIC writing function. So, I finally got values from both modules. The values seems about stable, except for the gyroscopes. Their values jump like crazy, for example, from -100 to 200 in one reading without touching the board. Would you said it is normal without calibration? Because calibration is just adding some constant to the measured values. The gyroscope is set to 250dps.

Kryzzalid commented 7 years ago

I figured it out. I forgot to set the filter with CONFIG. Now the values seem stable.

kriswiner commented 7 years ago

Glad you got it working.

-----Original Message----- From: Kryzzalid [mailto:notifications@github.com] Sent: November 2, 2016 5:52 AM To: kriswiner/MPU-9250 Cc: Kris Winer; Comment Subject: Re: [kriswiner/MPU-9250] Magnetometer only returns zeros (#82)

I figured it out. I forgot to set the filter with CONFIG. Now the values seem stable.

You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU-9250/issues/82#issuecomment-257855239 , or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qgtrcNIhGoGLOXpPqAgfB WTrqm5iks5q6IdSgaJpZM4KkbbE . https://github.com/notifications/beacon/AGY1qv14VOAmDlF9_3uevIaSOAI5edT9ks5 q6IdSgaJpZM4KkbbE.gif

Garista commented 7 years ago

Hi there,

Please Kryzzalid, can you explain how do you finally solve it? Because I have the same problem and I am not able to give a solution...

Kryzzalid commented 7 years ago

Hi! My problem was a mistake I made when sending values to the registers. I forgot to specify the number of values I was sending. So, the configuration of the chip was all wrong that's why it didn't work.

Garista commented 7 years ago

Many thanks! Maybe the mistake is in my code too... I am able to read ID register but when I try tor read Measurement Data or Control it only returns zeros.

Kryzzalid commented 7 years ago

I had the same problem. I could read from every readable registers but the measurements were only zeros. I noticed there was a problem in the writing function when I wrote something in a register and read it right after, the value was different from what I wrote.

Garista commented 7 years ago

I think I'm not configuring the register properly because when I select the MODE in Control 1 Register and I try to read this register it shows zero as well.

Do you think I'm doing right?

StartI2C(); WriteI2C(AK8963_W); WriteI2C(0x0A); WriteI2C(0b00000000); StopI2C(); Delay10KTCYx(1);

StopI2C(); WriteI2C(AK8963_W); WriteI2C(0x0A); WriteI2C(0b00010110); StartI2C();

Many thanks.

Garista commented 7 years ago

StartI2C(); WriteI2C(AK8963_W); WriteI2C(0x0A); WriteI2C(0b00010110); Stop2C();

The last part was wrong but it still does not work...

Kryzzalid commented 7 years ago

I would say that the sequence seems to be alright but, I can't be sure since I have never seen those fonctions. How do you read the values from the registers? Because like Kriswiner mentioned, for the magnetometer AK8963 you have to read all the bytes: ST1 0x02, MAG_XOUT_L 0x03, MAG_XOUT_H 0x04, MAG_YOUT_L 0x05, MAG_YOUT_H 0x06, MAG_ZOUT_L 0x07, MAG_ZOUT_L 0x08 and ST2 0x09. So, you have to read all those 8 bytes each time you read measurement values.

kriswiner commented 7 years ago

Are you setting INT_CFG for bypass mode? If not, you can't talk with the AK8963C.

Garista commented 7 years ago

Hi again! Finally I was able to solve the problem but I still don't know how was wrong. I think it was the Start() and Stop() functions that I wrote here wrong. Many thanks!!

rajveersinhraol commented 7 years ago

hello, i still have the same issue reading i get -1

void maginit(float* destination){ Mscale = MFS_16BITS; // MFS_14BITS or MFS_16BITS, 14-bit or 16-bit magnetometer resolution Mmode = 0x06; // Either 8 Hz 0x02) or 100 Hz (0x06) magnetometer data ODR // scale resolutions per LSB for the sensors

uint8_t rawData[3];  // x/y/z gyro calibration data stored here

  writeByte(0x0c, AK8963_CNTL, 0x00); // Power down magnetometer
  Delayms(10);
  writeByte(0x0c, AK8963_CNTL, 0x0F); // Enter Fuse ROM access mode
  Delayms(10);
  readBytes(0x0c, AK8963_ASAX, 3, &rawData[0]);  // Read the x-, y-, and z-axis calibration values
  destination[0] =  (float)(rawData[0] - 128)/256.0f + 1.0f;   // Return x-axis sensitivity adjustment values, etc.
  destination[1] =  (float)(rawData[1] - 128)/256.0f + 1.0f;
  destination[2] =  (float)(rawData[2] - 128)/256.0f + 1.0f;
  writeByte(0x0c, AK8963_CNTL, 0x00); // Power down magnetometer
  Delayms(10);

// // Configure the magnetometer for continuous read and highest resolution // // set Mscale bit 4 to 1 (0) to enable 16 (14) bit resolution in CNTL register, // and enable continuous mode data acquisition Mmode (bits [3:0]), 0010 for 8 Hz and 0110 for 100 Hz sample rates writeByte(0x0c, AK8963_CNTL,Mscale << 4 | Mmode); // Set magnetometer data resolution and sample ODR

  Delayms(10);

} void readMagData(void) { uint8_t rawData[7]; // x/y/z gyro register data, ST2 register stored here, must read ST2 at end of data acquisition

// if(readByte(0x0c, AK8963_ST1) & 0x01) { // wait for magnetometer data ready bit to be set

        I2C_start(I2C2,0x0c<<1, I2C_Direction_Transmitter);
        I2C_write(I2C2, AK8963_ST1 | 0x80); // write address to the slave
        I2C_stop(I2C2);
        I2C_start(I2C2,0x0c<<1, I2C_Direction_Receiver); // start a transmission in Master receiver mode
        rawData[0] = I2C_read_ack(I2C2);
        rawData[1] = I2C_read_ack(I2C2);
        rawData[2] = I2C_read_ack(I2C2);
        rawData[3] = I2C_read_ack(I2C2);
        rawData[4] = I2C_read_ack(I2C2);
        rawData[5]=I2C_read_ack(I2C2);
        rawData[6]=I2C_read_ack(I2C2);
        rawData[7]=I2C_read_nack(I2C2);
        I2C_stop(I2C2);
        mx = (int16_t)(((int16_t)rawData[2] << 8) | rawData[1]) ;  // Turn the MSB and LSB into a signed 16-bit value
        my = (int16_t)(((int16_t)rawData[4] << 8) | rawData[3]) ;
        mz = (int16_t)(((int16_t)rawData[6] << 8) | rawData[5]) ;
    //  readByte(0x0c,AK8963_ST2)|0x08

// }

}

kriswiner commented 7 years ago

Did you put the MPU9250 in pass through mode?

On Wed, Dec 28, 2016 at 4:50 PM, rajveersinhraol notifications@github.com wrote:

hello, i still have the same issue reading i get -1

void maginit(float* destination){ Mscale = MFS_16BITS; // MFS_14BITS or MFS_16BITS, 14-bit or 16-bit magnetometer resolution Mmode = 0x06; // Either 8 Hz 0x02) or 100 Hz (0x06) magnetometer data ODR // scale resolutions per LSB for the sensors

uint8_t rawData[3]; // x/y/z gyro calibration data stored here

writeByte(0x0c, AK8963_CNTL, 0x00); // Power down magnetometer Delayms(10); writeByte(0x0c, AK8963_CNTL, 0x0F); // Enter Fuse ROM access mode Delayms(10); readBytes(0x0c, AK8963_ASAX, 3, &rawData[0]); // Read the x-, y-, and z-axis calibration values destination[0] = (float)(rawData[0] - 128)/256.0f + 1.0f; // Return x-axis sensitivity adjustment values, etc. destination[1] = (float)(rawData[1] - 128)/256.0f + 1.0f; destination[2] = (float)(rawData[2] - 128)/256.0f + 1.0f; writeByte(0x0c, AK8963_CNTL, 0x00); // Power down magnetometer Delayms(10);

// // Configure the magnetometer for continuous read and highest resolution // // set Mscale bit 4 to 1 (0) to enable 16 (14) bit resolution in CNTL register, // and enable continuous mode data acquisition Mmode (bits [3:0]), 0010 for 8 Hz and 0110 for 100 Hz sample rates writeByte(0x0c, AK8963_CNTL,Mscale << 4 | Mmode); // Set magnetometer data resolution and sample ODR

Delayms(10);

} void readMagData(void) { uint8_t rawData[7]; // x/y/z gyro register data, ST2 register stored here, must read ST2 at end of data acquisition

// if(readByte(0x0c, AK8963_ST1) & 0x01) { // wait for magnetometer data ready bit to be set

  I2C_start(I2C2,0x0c<<1, I2C_Direction_Transmitter);
  I2C_write(I2C2, AK8963_ST1 | 0x80); // write address to the slave
  I2C_stop(I2C2);
  I2C_start(I2C2,0x0c<<1, I2C_Direction_Receiver); // start a transmission in Master receiver mode
  rawData[0] = I2C_read_ack(I2C2);
  rawData[1] = I2C_read_ack(I2C2);
  rawData[2] = I2C_read_ack(I2C2);
  rawData[3] = I2C_read_ack(I2C2);
  rawData[4] = I2C_read_ack(I2C2);
  rawData[5]=I2C_read_ack(I2C2);
  rawData[6]=I2C_read_ack(I2C2);
  rawData[7]=I2C_read_nack(I2C2);
  I2C_stop(I2C2);
  mx = (int16_t)(((int16_t)rawData[2] << 8) | rawData[1]) ;  // Turn the MSB and LSB into a signed 16-bit value
  my = (int16_t)(((int16_t)rawData[4] << 8) | rawData[3]) ;
  mz = (int16_t)(((int16_t)rawData[6] << 8) | rawData[5]) ;

// readByte(0x0c,AK8963_ST2)|0x08

// }

}

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU-9250/issues/82#issuecomment-269565201, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qmU8M7_vIWWEl1eiLIT4AVuJfez9ks5rMwPmgaJpZM4KkbbE .

rajveersinhraol commented 7 years ago

i think so using writeByte(MPU9250_ADDRESS, INT_PIN_CFG, 0x22); writeByte(MPU9250_ADDRESS, INT_ENABLE, 0x01);

rajveersinhraol commented 7 years ago

i am using an stm32f4 with gcc on eclipse...

kriswiner commented 7 years ago

Do you get the correct WHO_AM_I return from the AK8963C? Maybe the I2C addressing is mesed up?

On Wed, Dec 28, 2016 at 4:59 PM, rajveersinhraol notifications@github.com wrote:

i am using an stm32f4 with gcc on eclipse...

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU-9250/issues/82#issuecomment-269565840, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qt856vma0XiIg0yvQfkvaSqyKdl5ks5rMwXsgaJpZM4KkbbE .

rajveersinhraol commented 7 years ago

hey i think i fixed that issue but my quartonion always result in the same value , q1=q2=q3=q4=0.5 for a weird reason.

TediumRemedy commented 7 years ago

Hello I am having exactly the same problem as @Kryzzalid had. I am able to read registers WHO_I_AM and INFO (which return 0x48 and 0x9a respectively), but the rest of the registers simply return 0x00.

I am using CJMCU-116 (Chinese Junk as @kriswiner put it :) ). After initializing the MPU itself (including setting 2nd bit into MPU9250_INT_PIN_CFG, which is a BYPASS_EN), I am writing 0x16 into AK8963_CNTL1. Then I just try to read 10 bytes in a row, starting with register WHO_AM_I (register 0x00). The response I am getting is 0x48 0x9a 0 0 0 0 0 0 0 0

I also tried reading 8 bytes in a row, starting with register 0x02. Same result - 0's.

I tried reading these registers one by one, initiating a new i2c "reading session" for each byte, getting same results - zeros.

I am wondering if I did (or didn't) something wrong during initialization of either MPU or the AK? I am able to get bytes from the gyro and accelerometer just fine (they are noisy and jumping from time to time, I suppose this is because I do not filter them and didn't calibrate the gyro and accelerometer, but at least they are not zeros). Only the magnetometer's measurements are 0's.

@Kryzzalid, Could you please share your AK8963 and MPU9250 initialization code, as well as the code that reads the actual measurements?

kriswiner commented 7 years ago

Can you verify that pin 1 of the MPU9250 is connected to something?

On my version they left this unconnected, which causes the mag either to work erratically or not at all.

Secondly, can you read the fuze ROM data? This is the factory axis sensitivity data which is read only. Another test of whether the AK8963C is working.

This is what I use to initialize the AK8963C:

void initAK8963(float * destination) { // First extract the factory calibration for each magnetometer axis uint8_t rawData[3]; // x/y/z gyro calibration data stored here writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer delay(10); writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x0F); // Enter Fuse ROM access mode delay(10); readBytes(AK8963_ADDRESS, AK8963_ASAX, 3, &rawData[0]); // Read the x-, y-, and z-axis calibration values destination[0] = (float)(rawData[0] - 128)/256. + 1.; // Return x-axis sensitivity adjustment values, etc. destination[1] = (float)(rawData[1] - 128)/256. + 1.; destination[2] = (float)(rawData[2] - 128)/256. + 1.; writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer delay(10); // Configure the magnetometer for continuous read and highest resolution // set Mscale bit 4 to 1 (0) to enable 16 (14) bit resolution in CNTL register, // and enable continuous mode data acquisition Mmode (bits [3:0]), 0010 for 8 Hz and 0110 for 100 Hz sample rates writeByte(AK8963_ADDRESS, AK8963_CNTL, Mscale << 4 | Mmode); // Set magnetometer data resolution and sample ODR delay(10); }

Notice the delays, you might need to add more delay depending on the quality of the I2C bus signals. Make sure you define Mscale and Mmode properly.

And of course, you need to set the MPU9250 in bypass mode, which you say you have done. Can you verify this by rading the INT_CFG register back?

If this doesn't work, you then need to try a different sensor breakout to be sure it is the software and not the hardware.

On Wed, Jan 25, 2017 at 7:54 AM, TediumRemedy notifications@github.com wrote:

Hello I am having exactly the same problem as @Kryzzalid https://github.com/Kryzzalid had. I am able to read registers WHO_I_AM and INFO (which return 0x48 and 0x9a respectively), but the rest of the registers simply return 0x00.

I am using CJMCU-116 (Chinese Junk as @kriswiner https://github.com/kriswiner put it :) ). After initializing the MPU itself (including setting 2nd bit into MPU9250_INT_PIN_CFG, which is a BYPASS_EN), I am writing 0x16 into AK8963_CNTL1. Then I just try to read 10 bytes in a row, starting with register WHO_AM_I (register 0x00). The response I am getting is 0x48 0x9a 0 0 0 0 0 0 0 0

I also tried reading 8 bytes in a row, starting with register 0x02. Same result - 0's.

I tried reading these register one by one, initiating a new i2c "reading session" for each byte, getting same results - zeros.

I am wondering if I did (or didn't) something wrong during initialization of either MPU or the AK? I am able to get bytes from the gyro and accelerometer just fine (they are noisy and jumping from time to time, I suppose this is because I do not filter them and didn't calibrate the gyro and accelerometer, but at least they are not zeros). Only the magnetometer's measurements are 0's.

@Kryzzalid https://github.com/Kryzzalid, Could you please post your AK8963 and MPU9250 initialization code, as well as the code that does measurements?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU-9250/issues/82#issuecomment-275146217, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qisEVc0vZDQdyCyxVGoFX89-8m4kks5rV3BHgaJpZM4KkbbE .

TediumRemedy commented 7 years ago

Hi @kriswiner Thank you for the elaborate response. My CJ board is apparently a newer version, and pin 1 is connected to pin 8 (checked this with multimeter), as the datasheet requests.

Regarding the fuze ROM data (three registers AK8963_ASAX=0x10, AK8963_ASAY=0x11, AK8963_ASAXZ=0x12?), I can read them.

I used your initialization code, including powering down the mag 2 times and added delays, now I am getting real bytes returned. Thank you for your help!

It looks like the high byte of every axis can only have values either 0xFF (means, negative direction?) or 0x00 (means positive direction), and the actual azimuth is specified only by the lowest byte. Is this correct?

kriswiner commented 7 years ago

You have to ready 7 bytes (including the status register) for the AK8963 to function properly in continuous mode.

TediumRemedy commented 7 years ago

@kriswiner yes I am reading all the values between (and including) the registers st1 and st2. As a result I am getting numbers that change when i rotate the board. Its just the high byte of each returned axis is either ff or 00 (while the low byte shows seemingly correct value). So I was just wondering if its normal? (Wrong "scale"? It looks like the high byte's ff value means something like "negative complement", when i rotate the board past 0 in the "decreasing direction" )

kriswiner commented 7 years ago

Yes, are you not using int16_t to do the two's complement conversion?

On Wed, Jan 25, 2017 at 6:32 PM, TediumRemedy notifications@github.com wrote:

@kriswiner https://github.com/kriswiner yes I am reading all the values between (and including) the registers st1 and st2. As a result I am getting numbers that change when i rotate the board. Its just the high byte of each returned axis is either ff or 00 (while the low byte shows seemingly correct value). So I was just wondering if its normal? (Wrong "scale"? It looks like the high byte's ff value means something like "negative complement", when i rotate the board past 0 in the "decreasing direction" )

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU-9250/issues/82#issuecomment-275293979, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qm89cpgrZOHVzvh1WnFdAIx7TYATks5rWAW0gaJpZM4KkbbE .

kriswiner commented 7 years ago

Try int16_t rawCount = (int16_t) ( (int16_t) (MSB << 8) | LSB);

TediumRemedy commented 7 years ago

That was it. Thanks!

adarshparavoor commented 3 years ago

@TediumRemedy can you share the full working code

MehranMsba commented 2 years ago

Hi @kriswiner. I have a problem with Mag read of MPU9250 module. I configured the INT_PIN_CFG and MPU9250_USER_CTRL and I can read WHO_AM_I_MPU9250, AK8963_WHO_AM_I with true values, Then I set AK8963 mode to Fuse ROM and read the ASAX,ASAY,ASAZ and calculate the values, Mag cal off X: 1.183594 Mag cal off Y: 1.187500 Mag cal off Z: 1.144531 But the mag data is always zero and DRDY bit will never be 1. I try to read ST2 and ST1 in loop,or try to read 7 bytes from AK8963_XOUT_L to ST2 ,or simple ST1 read and any combination of these that I can. I am completely disappointed! All data = 0 ! Some times The CTRL1 is zero too when I read back it! It's the code: Github Link What's wrong?

Thank you.

kriswiner commented 2 years ago

Might not be the code, there are a lot of fake MPU9250 out there so maybe try another board or two before focusing on the software. Generally, you need to read the data and ST2 to get data update from the AK8963C, as you know,, also, you need to put the device into continuous mode after reading the fuse ROM. This is demonstrated in all of the example sketches...

On Tue, Mar 1, 2022 at 5:40 PM MehranMsba @.***> wrote:

Hi @kriswiner https://github.com/kriswiner. I have a problem with Mag read of MPU9250 module. I configured the INT_PIN_CFG and MPU9250_USER_CTRL and I can read WHO_AM_I_MPU9250, AK8963_WHO_AM_I with true values, Then I set AK8963 mode to Fuse ROM and read the ASAX,ASAY,ASAZ and calculate the values, Mag cal off X: 1.183594 Mag cal off Y: 1.187500 Mag cal off Z: 1.144531 But the mag data is always zero and DRDY bit will never be 1. I try to read ST2 and ST1 in loop,or try to read 7 bytes from AK8963_XOUT_L to ST2 ,or simple ST1 read and any combination of these that I can. I am completely disappointed! All data = 0 ! Some times The CTRL1 is zero too when I read back it! It's the code: Github Link https://github.com/MehranMsba/CodeOnDiscuss/blob/main/main.c What's wrong?

Thank you.

— Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/82#issuecomment-1056045929, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKRFGHVRXPEE72UP7QLU53BKRANCNFSM4CURW3CA . 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.

You are receiving this because you were mentioned.Message ID: @.***>

MehranMsba commented 2 years ago

Thanks for your fast response. Ok so I must buy another module and test again. Something that I see is that the 100khz i2c connection is not work with ak8963 of mpu9250 and I changed it to 400khz to read "who am I" register correctly.

kriswiner commented 2 years ago

Sounds like something wrong with your connections or I2C API or MCU? Does any other I2C sensor work OK?

On Tue, Mar 1, 2022 at 6:02 PM MehranMsba @.***> wrote:

Thanks for your fast response. Ok so I must buy another module and test again. Something that I see is that the 100khz i2c connection is not work with ak8963 of mpu9250 and I changed it to 400khz to read "who am I" register correctly.

— Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/82#issuecomment-1056057438, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKTAYA4ZES3MKKFZ2KLU53D33ANCNFSM4CURW3CA . 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.

You are receiving this because you were mentioned.Message ID: @.***>

MehranMsba commented 2 years ago

Yes, I test mpu6050 too, Same API and same connection, there is no problem with mpu6050.

kriswiner commented 2 years ago

So could be a bad MPU9250. Try some other MPU9250 test sketches to be sure.

On Tue, Mar 1, 2022 at 11:16 PM MehranMsba @.***> wrote:

Yes, I test mpu6050 too, Same API and same connection, there is no problem with mpu6050.

— Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/82#issuecomment-1056434508, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKQZSZOSWDPRYUKDFXLU54IWHANCNFSM4CURW3CA . 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.

You are receiving this because you were mentioned.Message ID: @.***>

MehranMsba commented 2 years ago

Yes, I bought a new one. It is now work without problem. I tested the broken part again with same code and wiring, Accel and gyro is worked but mag data is zero. forget it, new one is work.

Thank you.