kriswiner / MPU9250

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

ak8963 configure #85

Open sexyday opened 8 years ago

sexyday commented 8 years ago

void Init_MPU6050() { I2CWrite_MPU6050(I2C_ADDR,PWR_MGMT_1, 0x00); // I2CWrite_MPU6050(I2C_ADDR,SMPLRT_DIV, 0x00); //1khz //I2CWrite_MPU6050(I2C_ADDR,SMPLRT_DIV, 0x07); I2CWrite_MPU6050(I2C_ADDR,CONFIG, 0x02); I2CWrite_MPU6050(I2C_ADDR,GYRO_CONFIG, 0x00); //250dps //I2CWrite_MPU6050(I2C_ADDR,GYRO_CONFIG, 0x03); I2CWrite_MPU6050(I2C_ADDR,ACCEL_CONFIG, 0x00); //2g I2CWrite_MPU6050(I2C_ADDR,ACCEL_CONFIG2,0x02);//lpf I2CWrite_MPU6050(AK8963_ADDRESS,AK8963_CNTL1,0x02);// continute mode I2CWrite_MPU6050(I2C_ADDR,INT_PIN_CFG,0x02); }

void mag() { // I2CWrite_MPU6050(AK8963_ADDRESS,AK8963_CNTL1,0x02); if(I2CRead_MPU6050(AK8963_ADDRESS,AK8963_ST1)&0x01) { m[0] = I2CRead_MPU6050(AK8963_ADDRESS,AK8963_XOUT_L); // read Gyroscope X_Low value m[1] = I2CRead_MPU6050(AK8963_ADDRESS,AK8963_XOUT_H); // read Gyroscope X_High value

                    m[2] = I2CRead_MPU6050(AK8963_ADDRESS,AK8963_YOUT_L); // read Gyroscope Y_Low  value
                    m[3] = I2CRead_MPU6050(AK8963_ADDRESS,AK8963_YOUT_H); // read Gyroscope Y_High value

                    m[4] = I2CRead_MPU6050(AK8963_ADDRESS,AK8963_ZOUT_L); // read Gyroscope Z_Low  value
                    m[5] = I2CRead_MPU6050(AK8963_ADDRESS,AK8963_ZOUT_H); // read Gyroscope Z_High value
                    m[6]=I2CRead_MPU6050(AK8963_ADDRESS,AK8963_ST2);

                    if(!(m[6]&0x08))
                    {mX=((m[1]<<8)+m[0])*50/256*4912/8190.00;
                     mY=((m[3]<<8)+m[2])*52/256*4912/8190.00;
                     mZ=((m[5]<<8)+m[4])*40/256*4912/8190.00;}

                    printf("mX=%d, mY=%d, mZ=%d\n", (int)mX, (int)mY,(int) mZ);
                    }

excuse me kris,i can't read mag data stable.it sometimes stop reading or return the same data while i move or rotate mpu9255(the wire is still connected) .do i miss somethings ?the INT pin must be used?

MikeFair commented 8 years ago

I2CWrite_MPU6050(AK8963_ADDRESS,AK8963_CNTL1,0x02);// continute mode I2CWrite_MPU6050(I2C_ADDR,INT_PIN_CFG,0x02);

These lines should be reversed; you should first put the MPU in I2C_BYPASS mode (INT_PIN_CFG=0x02) before attempting to access the AK8963 directly.

    I2CWrite_MPU6050(I2C_ADDR,INT_PIN_CFG,0x02);
    I2CWrite_MPU6050(AK8963_ADDRESS,AK8963_CNTL1,0x02);// continuous mode 8Hz

If you keep getting the same data back, then odds are the AK8963 has dropped back into power down mode.

Add a printf on AK8963_CNTL1 to your output; It should be 0x02 all the time from what you've set above.

kriswiner commented 8 years ago

Thanks Mike, I'd like to respond to your posts properly but there is some utility work affecting my internet and phone access for the last few days and continuing so my responses have to be brief.

On the issue of multiple mpu9250 you are quite right about using the slave registers embedded in the mpu6500 asic, but I have always found this quite difficult to use correctly. The easiest way is to simply toggle the Int_cfg register to put first one mpu9250 and then the other into pass through mode reading the mag data as appropriate from each or any mpu9250. Yes, this is clunky, but it is also robust and easy to implement. If you have a tried and true Arduino implementation of using the slave registers I would like to try it and I am sure others would also benefit.

Kris

Sent from my iPhone

On Nov 7, 2016, at 6:11 PM, Mike Fair notifications@github.com wrote:

I2CWrite_MPU6050(AK8963_ADDRESS,AK8963_CNTL1,0x02);// continute mode I2CWrite_MPU6050(I2C_ADDR,INT_PIN_CFG,0x02);

These lines should be reversed; you should first put the MPU in I2C_BYPASS mode (INT_PIN_CFG=0x02) before attempting to access the AK8963 directly.

I2CWrite_MPU6050(I2C_ADDR,INT_PIN_CFG,0x02);
I2CWrite_MPU6050(AK8963_ADDRESS,AK8963_CNTL1,0x02);// continuous mode 8Hz

If you keep getting the same data back, then odds are the AK8963 has dropped back into power down mode.

Add a printf on AK8963_CNTL1 to your output; It should be 0x02 all the time from what you've set above.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

MikeFair commented 8 years ago

Wow, what timeliness! I just posted a request (#86) with code that should make the slaves easier to work with!

I've used similar code (using a modified MPU9250 library descended from the I2CDev codebase) to pull (1) the mag data + the accel/temp/gyro of a second downstream MPU; and (2) the accel/gyro data of two downstream MPUs (0x68/0x69) and the mag data using Slave4 (it's difficult when you only have a 24 byte buffer to put things and int16 data points to track).

The code I posted still relies on using the I2C_BYPASS to initially configure the AK8963; but in the next comment I'm posting code that shows how to do it using Slave4 (the "immediate transaction" Slave).

I separated it out because it needs helper functions that wait for the "Save4Done" flag to get set after you initiate a transaction and each txn can only work one byte at a time. So you've got a couple loops going on to implement something like "readBytes" and "writeBytes". But once I got those working it got interesting quite quickly.

sexyday commented 7 years ago

i have new questions.i want to make the quadcopter and how to convert mag data into angle? https://code.google.com/archive/p/sf9domahrs/ (i cant figure out from this website) do i have to calibrate mag data to 0?

kriswiner commented 7 years ago

Not sure what you mean here. If you have 9 D0F sensor data why not use a Madgwick or Mahoney filter to get quaternions and Euler angles?