kriswiner / MPU9250

Arduino sketches for MPU9250 9DoF with AHRS sensor fusion
1.03k stars 471 forks source link

Problems communicating with AK8963 #381

Open jmarcelomb opened 5 years ago

jmarcelomb commented 5 years ago

Hi kriswiner, I've been reading posts about mpu9250, and I made this code to configure it and the ak:

defineMPU9250_AD 0x68

define MAG_AD 0x0C

define WHO_AM_I_AK8963 0x00 // should return 0x48

define MPU9250_WHO_AM_I 0x75 // should return 0x71

define PWR_MGMT_1_AD 0x6B

define GYRO_CONFIG_AD 0x1B

define ACCEL_CONFIG_1_AD 0x1C

define ACCEL_CONFIG_2_AD 0x1D

define CONFIG_AD 0x1A

define USER_CTRL_AD 0x6A

define INT_BYPASS_CONFIG_AD 0x37

define CNTL1_AD 0x0A //control 1 register address

void init_mpu(struct io_descriptor *I2C_io_received){

uint8_t tmp = 0;

I2C_io= I2C_io_received;

i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MPU9250_AD, I2C_M_SEVEN);

tmp = 0x01; platform_write(&SENSOR_BUS, PWR_MGMT_1_AD, &tmp, 1); //0000 0001 in binary, set the clock reference to X axis gyroscope to get a better accuracy

delay_ms(3); //wait for the mode changes

tmp = 0x08; platform_write(&SENSOR_BUS, ACCEL_CONFIG_1_AD, &tmp, 1); //0000 1000 in binary. Set the accel scale to 4g

platform_write(&SENSOR_BUS, GYRO_CONFIG_AD, &tmp, 1); //0000 1000 in binary. Set the gyro scale to 500 °/s and FCHOICE_B

tmp = 0x05; platform_write(&SENSOR_BUS, ACCEL_CONFIG_2_AD, &tmp, 1); //0000 0101 in binary. Turn on the internal low-pass filter for accelerometer with 10.2Hz bandwidth

platform_write(&SENSOR_BUS, CONFIG_AD, &tmp, 1); //0000 0101 in binary. Turn on the internal low-pass filter for gyroscope with 10Hz bandwidth

//Ak // Actually we don't need this step cause the reset value of the register 106 is 0x00 platform_write(&SENSOR_BUS, USER_CTRL_AD, &tmp, 1);

tmp = 0x02; platform_write(&SENSOR_BUS, INT_BYPASS_CONFIG_AD, &tmp, 1); //0000 0010 in binary, turn on the bypass multiplexer

i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MAG_AD, I2C_M_SEVEN); // setup the Magnetometer to fuse ROM access mode to get the Sensitivity Adjustment values and 16-bit output tmp = 0x1F; platform_write(&SENSOR_BUS, CNTL1_AD, &tmp, 1);//0001 1111 in binary

//Who am I test i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MPU9250_AD, I2C_M_SEVEN); platform_read(&SENSOR_BUS, MPU9250_WHO_AM_I, &tmp, 1);

if(tmp != 0x71) while(1){ }

i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MAG_AD, I2C_M_SEVEN); platform_read(&SENSOR_BUS, WHO_AM_I_AK8963, &tmp, 1);

if(tmp != 0x48) while(1){ }

delay_ms(100); //wait for the mode changes }

I know for sure that the read and writte is working, because I can read accel and gyro values. I can read the whoAmI from mpu, but I can't get it from ak8963. Is it possible that my ak8963 is not working inside the mpu9250?

I also have this functions for ak8963:

void sensitivity_ak_read(){

uint8_t sensibility[3];

//read the Sensitivit Adjustment values i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MAG_AD, I2C_M_SEVEN);

platform_read(&SENSOR_BUS, ASAX_AD, sensibility, 3);//0001 1111 in binary

asax = (sensibility[0]-128)*0.5/128+1;
asay = (sensibility[1]-128)*0.5/128+1;
asaz = (sensibility[2]-128)*0.5/128+1;

return;

}

void ak_switch_to_continuous_mode2(){

uint8_t tmp = 0;

//reset the Magnetometer to power down mode i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MAG_AD, I2C_M_SEVEN); platform_write(&SENSOR_BUS, CNTL1_AD, 0x00, 1);

//wait for the mode changes
delay_ms(100);

 //set the Magnetometer to continuous mode 2(100Hz) and 16-bit output
tmp = 0x16;
platform_write(&SENSOR_BUS, CNTL1_AD, &tmp, 1);   //0001 0110 in binary

//wait for the mode changes
delay_ms(100);

}

My order of calling to configure is: init_mpu(I2C_io); sensitivity_ak_read(); ak_switch_to_continuous_mode2();

I will snif the I2C to see if it is respondig, but what do you think? Is my configuration correct?

Best regards, João Borges

Edited: I couldn't format the code the right way.

kriswiner commented 5 years ago

Where do you place the MPU9250 in passthrough mod?

On Sat, Jul 13, 2019 at 2:59 AM João Borges notifications@github.com wrote:

Hi kriswiner, I've been reading posts about mpu9250, and I made this code to configure it and the ak:

`

defineMPU9250_AD 0x68

define MAG_AD 0x0C

define WHO_AM_I_AK8963 0x00 // should return 0x48

define MPU9250_WHO_AM_I 0x75 // should return 0x71

define PWR_MGMT_1_AD 0x6B

define GYRO_CONFIG_AD 0x1B

define ACCEL_CONFIG_1_AD 0x1C

define ACCEL_CONFIG_2_AD 0x1D

define CONFIG_AD 0x1A

define USER_CTRL_AD 0x6A

define INT_BYPASS_CONFIG_AD 0x37

define CNTL1_AD 0x0A //control 1 register address

void init_mpu(struct io_descriptor *I2C_io_received){

uint8_t tmp = 0;

I2C_io= I2C_io_received;

i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MPU9250_AD, I2C_M_SEVEN);

tmp = 0x01; platform_write(&SENSOR_BUS, PWR_MGMT_1_AD, &tmp, 1); //0000 0001 in binary, set the clock reference to X axis gyroscope to get a better accuracy

delay_ms(3); //wait for the mode changes

tmp = 0x08; platform_write(&SENSOR_BUS, ACCEL_CONFIG_1_AD, &tmp, 1); //0000 1000 in binary. Set the accel scale to 4g

platform_write(&SENSOR_BUS, GYRO_CONFIG_AD, &tmp, 1); //0000 1000 in binary. Set the gyro scale to 500 °/s and FCHOICE_B

tmp = 0x05; platform_write(&SENSOR_BUS, ACCEL_CONFIG_2_AD, &tmp, 1); //0000 0101 in binary. Turn on the internal low-pass filter for accelerometer with 10.2Hz bandwidth

platform_write(&SENSOR_BUS, CONFIG_AD, &tmp, 1); //0000 0101 in binary. Turn on the internal low-pass filter for gyroscope with 10Hz bandwidth

//Ak // Actually we don't need this step cause the reset value of the register 106 is 0x00 platform_write(&SENSOR_BUS, USER_CTRL_AD, &tmp, 1);

tmp = 0x02; platform_write(&SENSOR_BUS, INT_BYPASS_CONFIG_AD, &tmp, 1); //0000 0010 in binary, turn on the bypass multiplexer

i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MAG_AD, I2C_M_SEVEN); // setup the Magnetometer to fuse ROM access mode to get the Sensitivity Adjustment values and 16-bit output tmp = 0x1F; platform_write(&SENSOR_BUS, CNTL1_AD, &tmp, 1);//0001 1111 in binary

//Who am I test i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MPU9250_AD, I2C_M_SEVEN); platform_read(&SENSOR_BUS, MPU9250_WHO_AM_I, &tmp, 1);

if(tmp != 0x71) while(1){ }

i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MAG_AD, I2C_M_SEVEN); platform_read(&SENSOR_BUS, WHO_AM_I_AK8963, &tmp, 1);

if(tmp != 0x48) while(1){ }

delay_ms(100); //wait for the mode changes } `

I know for sure that the read and writte is working, because I can read accel and gyro values. I can read the whoAmI from mpu, but I can't get it from ak8963. Is it possible that my ak8963 is not working inside the mpu9250?

I also have this functions for ak8963: `void sensitivity_ak_read(){

uint8_t sensibility[3];

//read the Sensitivit Adjustment values i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MAG_AD, I2C_M_SEVEN);

platform_read(&SENSOR_BUS, ASAX_AD, sensibility, 3);//0001 1111 in binary

asax = (sensibility[0]-128)*0.5/128+1;

asay = (sensibility[1]-128)*0.5/128+1;

asaz = (sensibility[2]-128)*0.5/128+1;

return;

}

void ak_switch_to_continuous_mode2(){

uint8_t tmp = 0;

//reset the Magnetometer to power down mode i2c_m_sync_set_slaveaddr(&SENSOR_BUS, MAG_AD, I2C_M_SEVEN); platform_write(&SENSOR_BUS, CNTL1_AD, 0x00, 1);

//wait for the mode changes

delay_ms(100);

//set the Magnetometer to continuous mode 2(100Hz) and 16-bit output

tmp = 0x16;

platform_write(&SENSOR_BUS, CNTL1_AD, &tmp, 1); //0001 0110 in binary

//wait for the mode changes

delay_ms(100);

}`

My order of calling to configure is: init_mpu(I2C_io); sensitivity_ak_read(); ak_switch_to_continuous_mode2();

I will snif the I2C to see if it is respondig, but what do you think? Is my configuration correct?

Best regards, João Borges

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/381?email_source=notifications&email_token=ABTDLKXGAU7ER3WKA37YH7DP7GRR3A5CNFSM4IC2GJ7KYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4G7ARIFA, or mute the thread https://github.com/notifications/unsubscribe-auth/ABTDLKR2LG7CA3EFT4KTAPTP7GRR3ANCNFSM4IC2GJ7A .

jmarcelomb commented 5 years ago

Thanks for your reply.

After your response I added this and still doesn't work: image

With that defines: image

kriswiner commented 5 years ago

No idea, try another sensor.

On Sat, Jul 13, 2019 at 8:54 AM João Borges notifications@github.com wrote:

Thanks for your reply.

After your response I added this and still don't work: [image: image] https://user-images.githubusercontent.com/35546901/61173683-78ac2f00-a58e-11e9-9b0c-9dd4b38ef69c.png

With that defines: [image: image] https://user-images.githubusercontent.com/35546901/61173701-c759c900-a58e-11e9-83cd-57d4a87c335a.png

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/381?email_source=notifications&email_token=ABTDLKUJ6NT67VCSCR2RTT3P7H3BTA5CNFSM4IC2GJ7KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZ3UG6I#issuecomment-511132537, or mute the thread https://github.com/notifications/unsubscribe-auth/ABTDLKWOWRL6N7YKHVAJPWTP7H3BTANCNFSM4IC2GJ7A .

jmarcelomb commented 5 years ago

I will try to use another sensor. Thanks anyway for your attention.

kriswiner commented 5 years ago

You might want to take a look at the various Arduino sketches. These are not platformio but will show you how to properly configure the AK8963C.

On Sat, Jul 13, 2019 at 9:29 AM João Borges notifications@github.com wrote:

Closed #381 https://github.com/kriswiner/MPU9250/issues/381.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/381?email_source=notifications&email_token=ABTDLKRPUVF4MRACXJMIDETP7H7F5A5CNFSM4IC2GJ7KYY3PNVWWK3TUL52HS4DFWZEXG43VMVCXMZLOORHG65DJMZUWGYLUNFXW5KTDN5WW2ZLOORPWSZGOSPPN4HI#event-2480856605, or mute the thread https://github.com/notifications/unsubscribe-auth/ABTDLKV7O62ABIDQOD3H3KLP7H7F5ANCNFSM4IC2GJ7A .

jmarcelomb commented 5 years ago

Hi kris,

I bought another one and I can get everything working fine. My problem now is that I can't understand the parameters of MadgwickQuaternionUpdate, I'm using: MadgwickQuaternionUpdate(_ax, +_ay, -_az, _gx, _gy, -_gz, _hy, _hx, _hz);.

I already saw you talk about NED, but I can't figure it out.

Taking this into account:

image

and beeing here: image

I'm correcting yaw adding 1.6.

With the board this way: image

Being North to -Y. I'm getting: image

Respectively roll, pitch and yaw.

Can you help me figure out how can I put the initial position close to 0,0,0?

My code: ´while (1) { readSensor();

      for(uint8_t i = 0; i < 10; i++) { // iterate a fixed number of times per data read cycle
        Now = _system_time_get(0);
        deltat = ((Now - lastUpdate)/1000000.0f); // set integration time by time elapsed since last filter update
        lastUpdate = Now;

        sum += deltat; // sum for averaging filter update rate
        sumCount++;

        MadgwickQuaternionUpdate(_ax, +_ay, -_az, _gx, _gy, -_gz,  _hy,  _hx, _hz);
      }

    if(sumCount > 50)
    {

          // Define rotation matrix from quaternions
      a12 =   2.0f * (q[1] * q[2] + q[0] * q[3]);
      a22 =   q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3];
      a31 =   2.0f * (q[0] * q[1] + q[2] * q[3]);
      a32 =   2.0f * (q[1] * q[3] - q[0] * q[2]);
      a33 =   q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3];
      pitch = -asinf(a32);
      roll  = atan2f(a31, a33);
      yaw   = atan2f(a12, a22);
      pitch *= 180.0f / pi;
      yaw   *= 180.0f / pi;
      //yaw   += 13.8f; // Declination at Danville, California is 13 degrees 48minutes and 47 seconds on 2014-04-04
      yaw   += 1.6f;
      if(yaw < 0) yaw   += 360.0f; // Ensure yaw stays between 0 and 360
      roll  *= 180.0f / pi;

    printf("%2.2f\t%2.2f\t%2.2f\r\n",roll,pitch,yaw);

   // printf("rate = %f Hz\r\n",(float)sumCount/sum);
    sumCount = 0;
    sum = 0;    
    }
  }`

My processor is operating at 16Mhz. I convert at readSensors accelerometer, gyro and magnetomer to 1->9,8, rad/s and uT respectively.

kriswiner commented 5 years ago

If you point the sensor board edge you have selected to be at North toward the North, you should get 0 degrees for yaw.

1) select which board edge is to be North, which accel axis points along this direction? Which accel axis points E and D? Repeat for gyro and mag. Then call the fusion filter as (aN, aE, aD, gN, gE, gD, mN, mE,, mD).

On Thu, Aug 1, 2019 at 6:06 AM João Borges notifications@github.com wrote:

Reopened #381 https://github.com/kriswiner/MPU9250/issues/381.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/381?email_source=notifications&email_token=ABTDLKU7D6M7ZMQ23TYZ4Q3QCLNWDA5CNFSM4IC2GJ7KYY3PNVWWK3TUL52HS4DFWZEXG43VMVCXMZLOORHG65DJMZUWGYLUNFXW5KTDN5WW2ZLOORPWSZGOS2LT6FI#event-2526494485, or mute the thread https://github.com/notifications/unsubscribe-auth/ABTDLKQTHFPHARDOJ3LYEILQCLNWDANCNFSM4IC2GJ7A .