Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 #include "mbed.h" 00002 #include "MPU9250.h" 00003 00004 float sum = 0; 00005 uint32_t sumCount = 0; 00006 char buffer[14]; 00007 float yaw_an = 0; 00008 int16_t gz_tmp; 00009 00010 MPU9250 mpu9250; 00011 00012 Timer t; 00013 00014 Serial pc(USBTX, USBRX); // tx, rx 00015 00016 00017 00018 int main() 00019 { 00020 pc.baud(115200); 00021 00022 //Set up I2C 00023 i2c.frequency(400000); // use fast (400 kHz) I2C 00024 00025 t.start(); 00026 00027 00028 00029 // Read the WHO_AM_I register, this is a good test of communication 00030 uint8_t whoami = mpu9250.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250); // Read WHO_AM_I register for MPU-9250 00031 pc.printf("I AM 0x%x\n\r", whoami); pc.printf("I SHOULD BE 0x71\n\r"); 00032 00033 if (whoami == 0x71) // WHO_AM_I should always be 0x68 00034 { 00035 pc.printf("MPU9250 WHO_AM_I is 0x%x\n\r", whoami); 00036 pc.printf("MPU9250 is online...\n\r"); 00037 wait(1); 00038 00039 mpu9250.resetMPU9250(); // Reset registers to default in preparation for device calibration 00040 mpu9250.MPU9250SelfTest(SelfTest); // Start by performing self test and reporting values 00041 pc.printf("x-axis self test: acceleration trim within : %f % of factory value\n\r", SelfTest[0]); 00042 pc.printf("y-axis self test: acceleration trim within : %f % of factory value\n\r", SelfTest[1]); 00043 pc.printf("z-axis self test: acceleration trim within : %f % of factory value\n\r", SelfTest[2]); 00044 pc.printf("x-axis self test: gyration trim within : %f % of factory value\n\r", SelfTest[3]); 00045 pc.printf("y-axis self test: gyration trim within : %f % of factory value\n\r", SelfTest[4]); 00046 pc.printf("z-axis self test: gyration trim within : %f % of factory value\n\r", SelfTest[5]); 00047 mpu9250.calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers 00048 pc.printf("x gyro bias = %f\n\r", gyroBias[0]); 00049 pc.printf("y gyro bias = %f\n\r", gyroBias[1]); 00050 pc.printf("z gyro bias = %f\n\r", gyroBias[2]); 00051 pc.printf("x accel bias = %f\n\r", accelBias[0]); 00052 pc.printf("y accel bias = %f\n\r", accelBias[1]); 00053 pc.printf("z accel bias = %f\n\r", accelBias[2]); 00054 wait(2); 00055 mpu9250.initMPU9250(); 00056 pc.printf("MPU9250 initialized for active data mode....\n\r"); // Initialize device for active mode read of acclerometer, gyroscope, and temperature 00057 mpu9250.initAK8963(magCalibration); 00058 pc.printf("AK8963 initialized for active data mode....\n\r"); // Initialize device for active mode read of magnetometer 00059 pc.printf("Accelerometer full-scale range = %f g\n\r", 2.0f*(float)(1<<Ascale)); 00060 pc.printf("Gyroscope full-scale range = %f deg/s\n\r", 250.0f*(float)(1<<Gscale)); 00061 if(Mscale == 0) pc.printf("Magnetometer resolution = 14 bits\n\r"); 00062 if(Mscale == 1) pc.printf("Magnetometer resolution = 16 bits\n\r"); 00063 if(Mmode == 2) pc.printf("Magnetometer ODR = 8 Hz\n\r"); 00064 if(Mmode == 6) pc.printf("Magnetometer ODR = 100 Hz\n\r"); 00065 wait(1); 00066 } 00067 else 00068 { 00069 pc.printf("Could not connect to MPU9250: \n\r"); 00070 pc.printf("%#x \n", whoami); 00071 00072 while(1) ; // Loop forever if communication doesn't happen 00073 } 00074 00075 mpu9250.getAres(); // Get accelerometer sensitivity 00076 mpu9250.getGres(); // Get gyro sensitivity 00077 mpu9250.getMres(); // Get magnetometer sensitivity 00078 pc.printf("Accelerometer sensitivity is %f LSB/g \n\r", 1.0f/aRes); 00079 pc.printf("Gyroscope sensitivity is %f LSB/deg/s \n\r", 1.0f/gRes); 00080 pc.printf("Magnetometer sensitivity is %f LSB/G \n\r", 1.0f/mRes); 00081 00082 while(1) { 00083 00084 // If intPin goes high, all data registers have new data 00085 if(mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) { // On interrupt, check if data ready interrupt 00086 00087 mpu9250.readAccelData(accelCount); // Read the x/y/z adc values 00088 // Now we'll calculate the accleration value into actual g's 00089 ax = (float)accelCount[0]*aRes - accelBias[0]; // get actual g value, this depends on scale being set 00090 ay = (float)accelCount[1]*aRes - accelBias[1]; 00091 az = (float)accelCount[2]*aRes - accelBias[2]; 00092 00093 mpu9250.readGyroData(gyroCount); // Read the x/y/z adc values 00094 // Calculate the gyro value into actual degrees per second 00095 gx = (float)gyroCount[0]*gRes - gyroBias[0]; // get actual gyro value, this depends on scale being set 00096 gy = (float)gyroCount[1]*gRes - gyroBias[1]; 00097 gz = (float)gyroCount[2]*gRes - gyroBias[2]; 00098 00099 mpu9250.readMagData(magCount); // Read the x/y/z adc values 00100 // Calculate the magnetometer values in milliGauss 00101 // Include factory calibration per data sheet and user environmental corrections 00102 mx = (float)magCount[0]*mRes*magCalibration[0] - magbias[0]; // get actual magnetometer value, this depends on scale being set 00103 my = (float)magCount[1]*mRes*magCalibration[1] - magbias[1]; 00104 mz = (float)magCount[2]*mRes*magCalibration[2] - magbias[2]; 00105 } 00106 00107 Now = t.read_us(); 00108 deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update 00109 lastUpdate = Now; 00110 gz_tmp = gz; 00111 yaw_an -= (float)gz_tmp * deltat; 00112 sum += deltat; 00113 00114 sumCount++; 00115 00116 // if(lastUpdate - firstUpdate > 10000000.0f) { 00117 // beta = 0.04; // decrease filter gain after stabilized 00118 // zeta = 0.015; // increasey bias drift gain after stabilized 00119 // } 00120 00121 // Pass gyro rate as rad/s 00122 mpu9250.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz); 00123 // mpu9250.MahonyQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz); 00124 00125 // Serial print and/or display at 0.5 s rate independent of data rates 00126 delt_t = t.read_ms() - count; 00127 if (delt_t > 500) { // update LCD once per half-second independent of read rate 00128 00129 pc.printf("ax = %f", 1000*ax); 00130 pc.printf(" ay = %f", 1000*ay); 00131 pc.printf(" az = %f mg\n\r", 1000*az); 00132 00133 pc.printf("gx = %f", gx); 00134 pc.printf(" gy = %f", gy); 00135 pc.printf(" gz = %f deg/s\n\r", gz); 00136 00137 pc.printf("mx = %f", mx); 00138 pc.printf(" my = %f", my); 00139 pc.printf(" mz = %f mG\n\r", mz); 00140 00141 tempCount = mpu9250.readTempData(); // Read the adc values 00142 temperature = ((float) tempCount) / 333.87f + 21.0f; // Temperature in degrees Centigrade 00143 pc.printf(" temperature = %f C\n\r", temperature); 00144 00145 pc.printf("q0 = %f\n\r", q[0]); 00146 pc.printf("q1 = %f\n\r", q[1]); 00147 pc.printf("q2 = %f\n\r", q[2]); 00148 pc.printf("q3 = %f\n\r", q[3]); 00149 00150 // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation. 00151 // In this coordinate system, the positive z-axis is down toward Earth. 00152 // Yaw is the angle between Sensor x-axis and Earth magnetic North (or true North if corrected for local declination, looking down on the sensor positive yaw is counterclockwise. 00153 // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative. 00154 // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll. 00155 // These arise from the definition of the homogeneous rotation matrix constructed from quaternions. 00156 // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be 00157 // applied in the correct order which for this configuration is yaw, pitch, and then roll. 00158 // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links. 00159 //yaw = atan2(2.0f * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3]); 00160 pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2])); 00161 roll = atan2(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]); 00162 pitch *= 180.0f / PI; 00163 //yaw *= 180.0f / PI; 00164 //yaw -= 13.8f; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04 00165 yaw = yaw_an; 00166 roll *= 180.0f / PI; 00167 00168 pc.printf("Yaw, Pitch, Roll: %f %f %f\n\r", yaw, pitch, roll); 00169 pc.printf("average rate = %f\n\r", (float) sumCount/sum); 00170 00171 myled= !myled; 00172 count = t.read_ms(); 00173 00174 if(count > 1<<21) { 00175 t.stop(); 00176 t.reset(); 00177 t.start(); // start the timer over again if ~30 minutes has passed 00178 count = 0; 00179 deltat= 0; 00180 lastUpdate = t.read_us(); 00181 } 00182 sum = 0; 00183 sumCount = 0; 00184 } 00185 } 00186 }
Generated on Sat Jul 23 2022 19:47:29 by
 1.7.2
 1.7.2