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.
Fork of ESC by
IMU.h
00001 00002 #include "MPU6050.h" 00003 #include "communication.h" 00004 00005 float sum = 0; 00006 uint32_t sumCount = 0; 00007 00008 Timer t; 00009 00010 void IMUinit(MPU6050 &mpu6050) 00011 { 00012 t.start(); 00013 00014 // Read the WHO_AM_I register, this is a good test of communication 00015 uint8_t whoami = mpu6050.readByte(MPU6050_ADDRESS, WHO_AM_I_MPU6050); // Read WHO_AM_I register for MPU-6050 00016 pc.printf("I AM 0x%x\n\r", whoami); 00017 pc.printf("I SHOULD BE 0x68\n\r"); 00018 00019 if (whoami == 0x68) { // WHO_AM_I should always be 0x68 00020 pc.printf("MPU6050 is online..."); 00021 wait(1); 00022 //lcd.clear(); 00023 //lcd.printString("MPU6050 OK", 0, 0); 00024 00025 00026 mpu6050.MPU6050SelfTest(SelfTest); // Start by performing self test and reporting values 00027 pc.printf("x-axis self test: acceleration trim within : "); 00028 pc.printf("%f", SelfTest[0]); 00029 pc.printf("% of factory value \n\r"); 00030 pc.printf("y-axis self test: acceleration trim within : "); 00031 pc.printf("%f", SelfTest[1]); 00032 pc.printf("% of factory value \n\r"); 00033 pc.printf("z-axis self test: acceleration trim within : "); 00034 pc.printf("%f", SelfTest[2]); 00035 pc.printf("% of factory value \n\r"); 00036 pc.printf("x-axis self test: gyration trim within : "); 00037 pc.printf("%f", SelfTest[3]); 00038 pc.printf("% of factory value \n\r"); 00039 pc.printf("y-axis self test: gyration trim within : "); 00040 pc.printf("%f", SelfTest[4]); 00041 pc.printf("% of factory value \n\r"); 00042 pc.printf("z-axis self test: gyration trim within : "); 00043 pc.printf("%f", SelfTest[5]); 00044 pc.printf("% of factory value \n\r"); 00045 wait(1); 00046 00047 if(SelfTest[0] < 1.0f && SelfTest[1] < 1.0f && SelfTest[2] < 1.0f && SelfTest[3] < 1.0f && SelfTest[4] < 1.0f && SelfTest[5] < 1.0f) { 00048 mpu6050.resetMPU6050(); // Reset registers to default in preparation for device calibration 00049 mpu6050.calibrateMPU6050(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers 00050 mpu6050.initMPU6050(); 00051 pc.printf("MPU6050 initialized for active data mode....\n\r"); // Initialize device for active mode read of acclerometer, gyroscope, and temperature 00052 wait(2); 00053 } else { 00054 pc.printf("Device did not the pass self-test!\n\r"); 00055 } 00056 } else { 00057 pc.printf("Could not connect to MPU6050: \n\r"); 00058 pc.printf("%#x \n", whoami); 00059 00060 while(1) ; // Loop forever if communication doesn't happen 00061 } 00062 } 00063 00064 00065 void IMUPrintData(MPU6050 &mpu6050) 00066 { 00067 // If data ready bit set, all data registers have new data 00068 if(mpu6050.readByte(MPU6050_ADDRESS, INT_STATUS) & 0x01) { // check if data ready interrupt 00069 mpu6050.readAccelData(accelCount); // Read the x/y/z adc values 00070 mpu6050.getAres(); 00071 00072 // Now we'll calculate the accleration value into actual g's 00073 ax = (float)accelCount[0]*aRes - accelBias[0]; // get actual g value, this depends on scale being set 00074 ay = (float)accelCount[1]*aRes - accelBias[1]; 00075 az = (float)accelCount[2]*aRes - accelBias[2]; 00076 00077 mpu6050.readGyroData(gyroCount); // Read the x/y/z adc values 00078 mpu6050.getGres(); 00079 00080 // Calculate the gyro value into actual degrees per second 00081 gx = (float)gyroCount[0]*gRes; // - gyroBias[0]; // get actual gyro value, this depends on scale being set 00082 gy = (float)gyroCount[1]*gRes; // - gyroBias[1]; 00083 gz = (float)gyroCount[2]*gRes; // - gyroBias[2]; 00084 00085 tempCount = mpu6050.readTempData(); // Read the x/y/z adc values 00086 temperature = (tempCount) / 340. + 36.53; // Temperature in degrees Centigrade 00087 } 00088 00089 Now = t.read_us(); 00090 deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update 00091 lastUpdate = Now; 00092 00093 sum += deltat; 00094 sumCount++; 00095 00096 if(lastUpdate - firstUpdate > 10000000.0f) { 00097 beta = 0.04; // decrease filter gain after stabilized 00098 zeta = 0.015; // increasey bias drift gain after stabilized 00099 } 00100 00101 // Pass gyro rate as rad/s 00102 mpu6050.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f); 00103 00104 // Serial print and/or display at 0.5 s rate independent of data rates 00105 delt_t = t.read_ms() - count; 00106 if (delt_t > 500) { // update LCD once per half-second independent of read rate 00107 00108 pc.printf("ax = %f", 1000*ax); 00109 pc.printf(" ay = %f", 1000*ay); 00110 pc.printf(" az = %f mg\n\r", 1000*az); 00111 00112 pc.printf("gx = %f", gx); 00113 pc.printf(" gy = %f", gy); 00114 pc.printf(" gz = %f deg/s\n\r", gz); 00115 00116 pc.printf(" temperature = %f C\n\r", temperature); 00117 00118 pc.printf("q0 = %f\n\r", q[0]); 00119 pc.printf("q1 = %f\n\r", q[1]); 00120 pc.printf("q2 = %f\n\r", q[2]); 00121 pc.printf("q3 = %f\n\r", q[3]); 00122 00123 // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation. 00124 // In this coordinate system, the positive z-axis is down toward Earth. 00125 // 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. 00126 // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative. 00127 // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll. 00128 // These arise from the definition of the homogeneous rotation matrix constructed from quaternions. 00129 // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be 00130 // applied in the correct order which for this configuration is yaw, pitch, and then roll. 00131 // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links. 00132 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]); 00133 pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2])); 00134 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]); 00135 pitch *= 180.0f / PI; 00136 yaw *= 180.0f / PI; 00137 roll *= 180.0f / PI; 00138 00139 // pc.printf("Yaw, Pitch, Roll: \n\r"); 00140 // pc.printf("%f", yaw); 00141 // pc.printf(", "); 00142 // pc.printf("%f", pitch); 00143 // pc.printf(", "); 00144 // pc.printf("%f\n\r", roll); 00145 // pc.printf("average rate = "); pc.printf("%f", (sumCount/sum)); pc.printf(" Hz\n\r"); 00146 00147 pc.printf("Yaw, Pitch, Roll: %f %f %f\n\r", yaw, pitch, roll); 00148 pc.printf("average rate = %f\n\r", (float) sumCount/sum); 00149 00150 //myled= !myled; 00151 count = t.read_ms(); 00152 sum = 0; 00153 sumCount = 0; 00154 } 00155 } 00156 00157 void IMUUpdate(MPU6050 &mpu6050) 00158 { 00159 // If data ready bit set, all data registers have new data 00160 if(mpu6050.readByte(MPU6050_ADDRESS, INT_STATUS) & 0x01) { // check if data ready interrupt 00161 mpu6050.readAccelData(accelCount); // Read the x/y/z adc values 00162 mpu6050.getAres(); 00163 00164 // Now we'll calculate the accleration value into actual g's 00165 ax = (float)accelCount[0]*aRes - accelBias[0]; // get actual g value, this depends on scale being set 00166 ay = (float)accelCount[1]*aRes - accelBias[1]; 00167 az = (float)accelCount[2]*aRes - accelBias[2]; 00168 00169 mpu6050.readGyroData(gyroCount); // Read the x/y/z adc values 00170 mpu6050.getGres(); 00171 00172 // Calculate the gyro value into actual degrees per second 00173 gx = (float)gyroCount[0]*gRes; // - gyroBias[0]; // get actual gyro value, this depends on scale being set 00174 gy = (float)gyroCount[1]*gRes; // - gyroBias[1]; 00175 gz = (float)gyroCount[2]*gRes; // - gyroBias[2]; 00176 00177 tempCount = mpu6050.readTempData(); // Read the x/y/z adc values 00178 temperature = (tempCount) / 340. + 36.53; // Temperature in degrees Centigrade 00179 } 00180 00181 Now = t.read_us(); 00182 deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update 00183 lastUpdate = Now; 00184 00185 sum += deltat; 00186 sumCount++; 00187 00188 if(lastUpdate - firstUpdate > 10000000.0f) { 00189 beta = 0.04; // decrease filter gain after stabilized 00190 zeta = 0.015; // increasey bias drift gain after stabilized 00191 } 00192 00193 // Pass gyro rate as rad/s 00194 mpu6050.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f); 00195 00196 // Serial print and/or display at 0.5 s rate independent of data rates 00197 delt_t = t.read_ms() - count; 00198 00199 // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation. 00200 // In this coordinate system, the positive z-axis is down toward Earth. 00201 // 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. 00202 // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative. 00203 // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll. 00204 // These arise from the definition of the homogeneous rotation matrix constructed from quaternions. 00205 // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be 00206 // applied in the correct order which for this configuration is yaw, pitch, and then roll. 00207 // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links. 00208 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]); 00209 pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2])); 00210 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]); 00211 pitch *= 180.0f / PI; 00212 yaw *= 180.0f / PI; 00213 roll *= 180.0f / PI; 00214 00215 count = t.read_ms(); 00216 sum = 0; 00217 sumCount = 0; 00218 00219 }
Generated on Sat Jul 16 2022 12:25:49 by
1.7.2
