Akira Heya
/
MPU9250_I2C_test
test
MPU9250 I2C通信 注意:プルアップ抵抗を入れるのを忘れないように
Diff: MPU9250.h
- Revision:
- 3:e7be5e23013d
- Parent:
- 2:4e59a37182df
diff -r 4e59a37182df -r e7be5e23013d MPU9250.h --- a/MPU9250.h Tue Aug 05 01:37:23 2014 +0000 +++ b/MPU9250.h Mon Jul 25 05:54:41 2022 +0000 @@ -1,12 +1,12 @@ +//------------------------------------------------------------------------------ +// Attitude measurement using IMU(MPU-9250) +//------------------------------------------------------------------------------ #ifndef MPU9250_H #define MPU9250_H #include "mbed.h" #include "math.h" - -// See also MPU-9250 Register Map and Descriptions, Revision 4.0, RM-MPU-9250A-00, Rev. 1.4, 9/9/2013 for registers not listed in -// above document; the MPU9250 and MPU9150 are virtually identical but the latter has a different register map -// + //Magnetometer Registers #define AK8963_ADDRESS 0x0C<<1 #define WHO_AM_I_AK8963 0x00 // should return 0x48 @@ -30,7 +30,8 @@ #define SELF_TEST_Y_GYRO 0x01 #define SELF_TEST_Z_GYRO 0x02 -/*#define X_FINE_GAIN 0x03 // [7:0] fine gain +/* +#define X_FINE_GAIN 0x03 // [7:0] fine gain #define Y_FINE_GAIN 0x04 #define Z_FINE_GAIN 0x05 #define XA_OFFSET_H 0x06 // User-defined trim values for accelerometer @@ -38,7 +39,8 @@ #define YA_OFFSET_H 0x08 #define YA_OFFSET_L_TC 0x09 #define ZA_OFFSET_H 0x0A -#define ZA_OFFSET_L_TC 0x0B */ +#define ZA_OFFSET_L_TC 0x0B +*/ #define SELF_TEST_X_ACCEL 0x0D #define SELF_TEST_Y_ACCEL 0x0E @@ -153,7 +155,6 @@ #define ZA_OFFSET_H 0x7D #define ZA_OFFSET_L 0x7E -// Using the MSENSR-9250 breakout board, ADO is set to 0 // Seven-bit device address is 110100 for ADO = 0 and 110101 for ADO = 1 //mbed uses the eight-bit device address, so shift seven-bit addresses left by one! #define ADO 0 @@ -190,25 +191,27 @@ float aRes, gRes, mRes; // scale resolutions per LSB for the sensors //Set up I2C, (SDA,SCL) -I2C i2c(I2C_SDA, I2C_SCL); +I2C i2c(p9, p10); -DigitalOut myled(LED1); - // Pin definitions -int intPin = 12; // These can be changed, 2 and 3 are the Arduinos ext int pins - int16_t accelCount[3]; // Stores the 16-bit signed accelerometer sensor output int16_t gyroCount[3]; // Stores the 16-bit signed gyro sensor output int16_t magCount[3]; // Stores the 16-bit signed magnetometer sensor output float magCalibration[3] = {0, 0, 0}, magbias[3] = {0, 0, 0}; // Factory mag calibration and mag bias float gyroBias[3] = {0, 0, 0}, accelBias[3] = {0, 0, 0}; // Bias corrections for gyro and accelerometer -float ax, ay, az, gx, gy, gz, mx, my, mz; // variables to hold latest sensor data values +float ax, ay, az, gx, gy, gz, mx, my, mz; // variables to hold latest sensor data values +float th_ax, th_ay, th_az; +float th_ax_LPF, th_ay_LPF, th_az_LPF; +float pre_th_ax, pre_th_ay, pre_th_az; +float th_gx, th_gy, th_gz; +float pre_gx, pre_gy, pre_gz; +float th_x, th_y, th_z, th_x_d, th_y_d, th_z_d; int16_t tempCount; // Stores the real internal chip temperature in degrees Celsius float temperature; float SelfTest[6]; -int delt_t = 0; // used to control display output rate -int count = 0; // used to control display output rate +float delt_t = 0.0f; // used to display output rate +float sum_dt = 0.0f; // // parameters for 6 DoF sensor fusion calculations float PI = 3.14159265358979323846f; @@ -221,7 +224,7 @@ float pitch, yaw, roll; float deltat = 0.0f; // integration interval for both filter schemes -int lastUpdate = 0, firstUpdate = 0, Now = 0; // used to calculate integration interval // used to calculate integration interval +float lastUpdate = 0.0f, firstUpdate = 0.0f, Now = 0.0f; // used to calculate integration interval // used to calculate integration interval float q[4] = {1.0f, 0.0f, 0.0f, 0.0f}; // vector to hold quaternion float eInt[3] = {0.0f, 0.0f, 0.0f}; // vector to hold integral error for Mahony method @@ -263,7 +266,6 @@ dest[ii] = data[ii]; } } - void getMres() { switch (Mscale) @@ -279,7 +281,6 @@ } } - void getGres() { switch (Gscale) { @@ -301,7 +302,6 @@ } } - void getAres() { switch (Ascale) { @@ -348,11 +348,12 @@ if(readByte(AK8963_ADDRESS, AK8963_ST1) & 0x01) { // wait for magnetometer data ready bit to be set readBytes(AK8963_ADDRESS, AK8963_XOUT_L, 7, &rawData[0]); // Read the six raw data and ST2 registers sequentially into data array uint8_t c = rawData[6]; // End data read by reading ST2 register - if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data + if(!(c & 0x08)) + { // Check if magnetic sensor overflow set, if not then report data destination[0] = (int16_t)(((int16_t)rawData[1] << 8) | rawData[0]); // Turn the MSB and LSB into a signed 16-bit value destination[1] = (int16_t)(((int16_t)rawData[3] << 8) | rawData[2]) ; // Data stored as little Endian destination[2] = (int16_t)(((int16_t)rawData[5] << 8) | rawData[4]) ; - } + } } } @@ -364,11 +365,12 @@ } -void resetMPU9250() { +void resetMPU9250() +{ // reset device writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x80); // Write a one to bit 7 reset bit; toggle reset device wait(0.1); - } +} void initAK8963(float * destination) { @@ -428,7 +430,7 @@ // It is possible to get a 4 kHz sample rate from the accelerometer by choosing 1 for // accel_fchoice_b bit [3]; in this case the bandwidth is 1.13 kHz c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG2); - writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c & ~0x0F); // Clear accel_fchoice_b (bit 3) and A_DLPFG (bits [2:0]) + writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c & ~0x0F); // Clear accel_fchoice_b (bit 3) and A_DLPFG (bits [2:0]) writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c | 0x03); // Set accelerometer rate to 1 kHz and bandwidth to 41 Hz // The accelerometer, gyro, and thermometer are set to 1 kHz sample rates, @@ -488,7 +490,8 @@ fifo_count = ((uint16_t)data[0] << 8) | data[1]; packet_count = fifo_count/12;// How many sets of full gyro and accelerometer data for averaging - for (ii = 0; ii < packet_count; ii++) { + for (ii = 0; ii < packet_count; ii++) + { int16_t accel_temp[3] = {0, 0, 0}, gyro_temp[3] = {0, 0, 0}; readBytes(MPU9250_ADDRESS, FIFO_R_W, 12, &data[0]); // read data for averaging accel_temp[0] = (int16_t) (((int16_t)data[0] << 8) | data[1] ) ; // Form signed 16-bit integer for each sample in FIFO @@ -503,9 +506,9 @@ accel_bias[2] += (int32_t) accel_temp[2]; gyro_bias[0] += (int32_t) gyro_temp[0]; gyro_bias[1] += (int32_t) gyro_temp[1]; - gyro_bias[2] += (int32_t) gyro_temp[2]; - -} + gyro_bias[2] += (int32_t) gyro_temp[2]; + } + accel_bias[0] /= (int32_t) packet_count; // Normalize sums to get average count biases accel_bias[1] /= (int32_t) packet_count; accel_bias[2] /= (int32_t) packet_count; @@ -513,16 +516,16 @@ gyro_bias[1] /= (int32_t) packet_count; gyro_bias[2] /= (int32_t) packet_count; - if(accel_bias[2] > 0L) {accel_bias[2] -= (int32_t) accelsensitivity;} // Remove gravity from the z-axis accelerometer bias calculation - else {accel_bias[2] += (int32_t) accelsensitivity;} + if(accel_bias[2] > 0L) {accel_bias[2] -= (int32_t) accelsensitivity;} // Remove gravity from the z-axis accelerometer bias calculation + else {accel_bias[2] += (int32_t) accelsensitivity;} -// Construct the gyro biases for push to the hardware gyro bias registers, which are reset to zero upon device startup - data[0] = (-gyro_bias[0]/4 >> 8) & 0xFF; // Divide by 4 to get 32.9 LSB per deg/s to conform to expected bias input format - data[1] = (-gyro_bias[0]/4) & 0xFF; // Biases are additive, so change sign on calculated average gyro biases - data[2] = (-gyro_bias[1]/4 >> 8) & 0xFF; - data[3] = (-gyro_bias[1]/4) & 0xFF; - data[4] = (-gyro_bias[2]/4 >> 8) & 0xFF; - data[5] = (-gyro_bias[2]/4) & 0xFF; + // Construct the gyro biases for push to the hardware gyro bias registers, which are reset to zero upon device startup + data[0] = (-gyro_bias[0]/4 >> 8) & 0xFF; // Divide by 4 to get 32.9 LSB per deg/s to conform to expected bias input format + data[1] = (-gyro_bias[0]/4) & 0xFF; // Biases are additive, so change sign on calculated average gyro biases + data[2] = (-gyro_bias[1]/4 >> 8) & 0xFF; + data[3] = (-gyro_bias[1]/4) & 0xFF; + data[4] = (-gyro_bias[2]/4 >> 8) & 0xFF; + data[5] = (-gyro_bias[2]/4) & 0xFF; /// Push gyro biases to hardware registers /* writeByte(MPU9250_ADDRESS, XG_OFFSET_H, data[0]); @@ -532,9 +535,9 @@ writeByte(MPU9250_ADDRESS, ZG_OFFSET_H, data[4]); writeByte(MPU9250_ADDRESS, ZG_OFFSET_L, data[5]); */ - dest1[0] = (float) gyro_bias[0]/(float) gyrosensitivity; // construct gyro bias in deg/s for later manual subtraction - dest1[1] = (float) gyro_bias[1]/(float) gyrosensitivity; - dest1[2] = (float) gyro_bias[2]/(float) gyrosensitivity; + dest1[0] = (float) gyro_bias[0]/(float) gyrosensitivity; // construct gyro bias in deg/s for later manual subtraction + dest1[1] = (float) gyro_bias[1]/(float) gyrosensitivity; + dest1[2] = (float) gyro_bias[2]/(float) gyrosensitivity; // Construct the accelerometer biases for push to the hardware accelerometer bias registers. These registers contain // factory trim values which must be added to the calculated accelerometer biases; on boot up these registers will hold @@ -542,35 +545,35 @@ // compensation calculations. Accelerometer bias registers expect bias input as 2048 LSB per g, so that // the accelerometer biases calculated above must be divided by 8. - int32_t accel_bias_reg[3] = {0, 0, 0}; // A place to hold the factory accelerometer trim biases - readBytes(MPU9250_ADDRESS, XA_OFFSET_H, 2, &data[0]); // Read factory accelerometer trim values - accel_bias_reg[0] = (int16_t) ((int16_t)data[0] << 8) | data[1]; - readBytes(MPU9250_ADDRESS, YA_OFFSET_H, 2, &data[0]); - accel_bias_reg[1] = (int16_t) ((int16_t)data[0] << 8) | data[1]; - readBytes(MPU9250_ADDRESS, ZA_OFFSET_H, 2, &data[0]); - accel_bias_reg[2] = (int16_t) ((int16_t)data[0] << 8) | data[1]; + int32_t accel_bias_reg[3] = {0, 0, 0}; // A place to hold the factory accelerometer trim biases + readBytes(MPU9250_ADDRESS, XA_OFFSET_H, 2, &data[0]); // Read factory accelerometer trim values + accel_bias_reg[0] = (int16_t) ((int16_t)data[0] << 8) | data[1]; + readBytes(MPU9250_ADDRESS, YA_OFFSET_H, 2, &data[0]); + accel_bias_reg[1] = (int16_t) ((int16_t)data[0] << 8) | data[1]; + readBytes(MPU9250_ADDRESS, ZA_OFFSET_H, 2, &data[0]); + accel_bias_reg[2] = (int16_t) ((int16_t)data[0] << 8) | data[1]; - uint32_t mask = 1uL; // Define mask for temperature compensation bit 0 of lower byte of accelerometer bias registers - uint8_t mask_bit[3] = {0, 0, 0}; // Define array to hold mask bit for each accelerometer bias axis + uint32_t mask = 1uL; // Define mask for temperature compensation bit 0 of lower byte of accelerometer bias registers + uint8_t mask_bit[3] = {0, 0, 0}; // Define array to hold mask bit for each accelerometer bias axis - for(ii = 0; ii < 3; ii++) { - if(accel_bias_reg[ii] & mask) mask_bit[ii] = 0x01; // If temperature compensation bit is set, record that fact in mask_bit - } + for(ii = 0; ii < 3; ii++) { + if(accel_bias_reg[ii] & mask) mask_bit[ii] = 0x01; // If temperature compensation bit is set, record that fact in mask_bit + } - // Construct total accelerometer bias, including calculated average accelerometer bias from above - accel_bias_reg[0] -= (accel_bias[0]/8); // Subtract calculated averaged accelerometer bias scaled to 2048 LSB/g (16 g full scale) - accel_bias_reg[1] -= (accel_bias[1]/8); - accel_bias_reg[2] -= (accel_bias[2]/8); + // Construct total accelerometer bias, including calculated average accelerometer bias from above + accel_bias_reg[0] -= (accel_bias[0]/8); // Subtract calculated averaged accelerometer bias scaled to 2048 LSB/g (16 g full scale) + accel_bias_reg[1] -= (accel_bias[1]/8); + accel_bias_reg[2] -= (accel_bias[2]/8); - data[0] = (accel_bias_reg[0] >> 8) & 0xFF; - data[1] = (accel_bias_reg[0]) & 0xFF; - data[1] = data[1] | mask_bit[0]; // preserve temperature compensation bit when writing back to accelerometer bias registers - data[2] = (accel_bias_reg[1] >> 8) & 0xFF; - data[3] = (accel_bias_reg[1]) & 0xFF; - data[3] = data[3] | mask_bit[1]; // preserve temperature compensation bit when writing back to accelerometer bias registers - data[4] = (accel_bias_reg[2] >> 8) & 0xFF; - data[5] = (accel_bias_reg[2]) & 0xFF; - data[5] = data[5] | mask_bit[2]; // preserve temperature compensation bit when writing back to accelerometer bias registers + data[0] = (accel_bias_reg[0] >> 8) & 0xFF; + data[1] = (accel_bias_reg[0]) & 0xFF; + data[1] = data[1] | mask_bit[0]; // preserve temperature compensation bit when writing back to accelerometer bias registers + data[2] = (accel_bias_reg[1] >> 8) & 0xFF; + data[3] = (accel_bias_reg[1]) & 0xFF; + data[3] = data[3] | mask_bit[1]; // preserve temperature compensation bit when writing back to accelerometer bias registers + data[4] = (accel_bias_reg[2] >> 8) & 0xFF; + data[5] = (accel_bias_reg[2]) & 0xFF; + data[5] = data[5] | mask_bit[2]; // preserve temperature compensation bit when writing back to accelerometer bias registers // Apparently this is not working for the acceleration biases in the MPU-9250 // Are we handling the temperature correction bit properly? @@ -617,7 +620,9 @@ gAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ; } - for (int ii =0; ii < 3; ii++) { // Get average of 200 values and store as average current readings + for (int ii =0; ii < 3; ii++) + { + // Get average of 200 values and store as average current readings aAvg[ii] /= 200; gAvg[ii] /= 200; } @@ -625,22 +630,25 @@ // Configure the accelerometer for self-test writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, 0xE0); // Enable self test on all three axes and set accelerometer range to +/- 2 g writeByte(MPU9250_ADDRESS, GYRO_CONFIG, 0xE0); // Enable self test on all three axes and set gyro range to +/- 250 degrees/s - delay(25); // Delay a while to let the device stabilize + //delay(25); // Delay a while to let the device stabilize - for( int ii = 0; ii < 200; ii++) { // get average self-test values of gyro and acclerometer - + for( int ii = 0; ii < 200; ii++) + { + // get average self-test values of gyro and acclerometer readBytes(MPU9250_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]); // Read the six raw data registers into data array aSTAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value aSTAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ; aSTAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ; - readBytes(MPU9250_ADDRESS, GYRO_XOUT_H, 6, &rawData[0]); // Read the six raw data registers sequentially into data array + readBytes(MPU9250_ADDRESS, GYRO_XOUT_H, 6, &rawData[0]); // Read the six raw data registers sequentially into data array gSTAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value gSTAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ; gSTAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ; } - for (int ii =0; ii < 3; ii++) { // Get average of 200 values and store as average self-test readings + for (int ii =0; ii < 3; ii++) + { + // Get average of 200 values and store as average self-test readings aSTAvg[ii] /= 200; gSTAvg[ii] /= 200; } @@ -648,7 +656,7 @@ // Configure the gyro and accelerometer for normal operation writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, 0x00); writeByte(MPU9250_ADDRESS, GYRO_CONFIG, 0x00); - delay(25); // Delay a while to let the device stabilize + //delay(25); // Delay a while to let the device stabilize // Retrieve accelerometer and gyro factory Self-Test Code from USR_Reg selfTest[0] = readByte(MPU9250_ADDRESS, SELF_TEST_X_ACCEL); // X-axis accel self-test results @@ -668,7 +676,8 @@ // Report results as a ratio of (STR - FT)/FT; the change from Factory Trim of the Self-Test Response // To get percent, must multiply by 100 - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) + { destination[i] = 100.0*((float)(aSTAvg[i] - aAvg[i]))/factoryTrim[i]; // Report percent differences destination[i+3] = 100.0*((float)(gSTAvg[i] - gAvg[i]))/factoryTrim[i+3]; // Report percent differences }