Advertisement
Aiduss

Untitled

May 15th, 2017
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 46.47 KB | None | 0 0
  1. /* MPU9250 Basic Example Code
  2. by: Kris Winer
  3. date: April 1, 2014
  4. license: Beerware - Use this code however you'd like. If you
  5. find it useful you can buy me a beer some time.
  6.  
  7. Demonstrate basic MPU-9250 functionality including parameterizing the register addresses, initializing the sensor,
  8. getting properly scaled accelerometer, gyroscope, and magnetometer data out. Added display functions to
  9. allow display to on breadboard monitor. Addition of 9 DoF sensor fusion using open source Madgwick and
  10. Mahony filter algorithms. Sketch runs on the 3.3 V 8 MHz Pro Mini and the Teensy 3.1.
  11.  
  12. SDA and SCL should have external pull-up resistors (to 3.3V).
  13. 10k resistors are on the EMSENSR-9250 breakout board.
  14.  
  15.  
  16. Hardware setup:
  17. MPU9250 ------------------ Arduino
  18. VDD ---------------------- 3.3V
  19. VDDI --------------------- 3.3V
  20. SDA ----------------------- A4
  21. SCL ----------------------- A5
  22. GND ---------------------- GND
  23.  
  24. Note: The MPU9250 is an I2C sensor and uses the Arduino Wire library.
  25. Because the sensor is not 5V tolerant, we are using a 3.3 V 8 MHz Pro Mini or a 3.3 V Teensy 3.1.
  26. We have disabled the internal pull-ups used by the Wire library in the Wire.h/twi.c utility file.
  27. We are also using the 400 kHz fast I2C mode by setting the TWI_FREQ to 400000L /twi.h utility file.
  28. */
  29. #include <SPI.h>
  30. #include <Wire.h>
  31. // 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
  32. // above document; the MPU9250 and MPU9150 are virtually identical but the latter has a different register map
  33. //
  34. //Magnetometer Registers
  35. #define AK8963_ADDRESS 0x0C
  36. #define WHO_AM_I_AK8963 0x00 // should return 0x48
  37. #define INFO 0x01
  38. #define AK8963_ST1 0x02 // data ready status bit 0
  39. #define AK8963_XOUT_L 0x03 // data
  40. #define AK8963_XOUT_H 0x04
  41. #define AK8963_YOUT_L 0x05
  42. #define AK8963_YOUT_H 0x06
  43. #define AK8963_ZOUT_L 0x07
  44. #define AK8963_ZOUT_H 0x08
  45. #define AK8963_ST2 0x09 // Data overflow bit 3 and data read error status bit 2
  46. #define AK8963_CNTL 0x0A // Power down (0000), single-measurement (0001), self-test (1000) and Fuse ROM (1111) modes on bits 3:0
  47. #define AK8963_ASTC 0x0C // Self test control
  48. #define AK8963_I2CDIS 0x0F // I2C disable
  49. #define AK8963_ASAX 0x10 // Fuse ROM x-axis sensitivity adjustment value
  50. #define AK8963_ASAY 0x11 // Fuse ROM y-axis sensitivity adjustment value
  51. #define AK8963_ASAZ 0x12 // Fuse ROM z-axis sensitivity adjustment value
  52.  
  53. #define SELF_TEST_X_GYRO 0x00
  54. #define SELF_TEST_Y_GYRO 0x01
  55. #define SELF_TEST_Z_GYRO 0x02
  56.  
  57. /*#define X_FINE_GAIN 0x03 // [7:0] fine gain
  58. #define Y_FINE_GAIN 0x04
  59. #define Z_FINE_GAIN 0x05
  60. #define XA_OFFSET_H 0x06 // User-defined trim values for accelerometer
  61. #define XA_OFFSET_L_TC 0x07
  62. #define YA_OFFSET_H 0x08
  63. #define YA_OFFSET_L_TC 0x09
  64. #define ZA_OFFSET_H 0x0A
  65. #define ZA_OFFSET_L_TC 0x0B */
  66.  
  67. #define SELF_TEST_X_ACCEL 0x0D
  68. #define SELF_TEST_Y_ACCEL 0x0E
  69. #define SELF_TEST_Z_ACCEL 0x0F
  70.  
  71. #define SELF_TEST_A 0x10
  72.  
  73. #define XG_OFFSET_H 0x13 // User-defined trim values for gyroscope
  74. #define XG_OFFSET_L 0x14
  75. #define YG_OFFSET_H 0x15
  76. #define YG_OFFSET_L 0x16
  77. #define ZG_OFFSET_H 0x17
  78. #define ZG_OFFSET_L 0x18
  79. #define SMPLRT_DIV 0x19
  80. #define CONFIG 0x1A
  81. #define GYRO_CONFIG 0x1B
  82. #define ACCEL_CONFIG 0x1C
  83. #define ACCEL_CONFIG2 0x1D
  84. #define LP_ACCEL_ODR 0x1E
  85. #define WOM_THR 0x1F
  86.  
  87. #define MOT_DUR 0x20 // Duration counter threshold for motion interrupt generation, 1 kHz rate, LSB = 1 ms
  88. #define ZMOT_THR 0x21 // Zero-motion detection threshold bits [7:0]
  89. #define ZRMOT_DUR 0x22 // Duration counter threshold for zero motion interrupt generation, 16 Hz rate, LSB = 64 ms
  90.  
  91. #define FIFO_EN 0x23
  92. #define I2C_MST_CTRL 0x24
  93. #define I2C_SLV0_ADDR 0x25
  94. #define I2C_SLV0_REG 0x26
  95. #define I2C_SLV0_CTRL 0x27
  96. #define I2C_SLV1_ADDR 0x28
  97. #define I2C_SLV1_REG 0x29
  98. #define I2C_SLV1_CTRL 0x2A
  99. #define I2C_SLV2_ADDR 0x2B
  100. #define I2C_SLV2_REG 0x2C
  101. #define I2C_SLV2_CTRL 0x2D
  102. #define I2C_SLV3_ADDR 0x2E
  103. #define I2C_SLV3_REG 0x2F
  104. #define I2C_SLV3_CTRL 0x30
  105. #define I2C_SLV4_ADDR 0x31
  106. #define I2C_SLV4_REG 0x32
  107. #define I2C_SLV4_DO 0x33
  108. #define I2C_SLV4_CTRL 0x34
  109. #define I2C_SLV4_DI 0x35
  110. #define I2C_MST_STATUS 0x36
  111. #define INT_PIN_CFG 0x37
  112. #define INT_ENABLE 0x38
  113. #define DMP_INT_STATUS 0x39 // Check DMP interrupt
  114. #define INT_STATUS 0x3A
  115. #define ACCEL_XOUT_H 0x3B
  116. #define ACCEL_XOUT_L 0x3C
  117. #define ACCEL_YOUT_H 0x3D
  118. #define ACCEL_YOUT_L 0x3E
  119. #define ACCEL_ZOUT_H 0x3F
  120. #define ACCEL_ZOUT_L 0x40
  121. #define TEMP_OUT_H 0x41
  122. #define TEMP_OUT_L 0x42
  123. #define GYRO_XOUT_H 0x43
  124. #define GYRO_XOUT_L 0x44
  125. #define GYRO_YOUT_H 0x45
  126. #define GYRO_YOUT_L 0x46
  127. #define GYRO_ZOUT_H 0x47
  128. #define GYRO_ZOUT_L 0x48
  129. #define EXT_SENS_DATA_00 0x49
  130. #define EXT_SENS_DATA_01 0x4A
  131. #define EXT_SENS_DATA_02 0x4B
  132. #define EXT_SENS_DATA_03 0x4C
  133. #define EXT_SENS_DATA_04 0x4D
  134. #define EXT_SENS_DATA_05 0x4E
  135. #define EXT_SENS_DATA_06 0x4F
  136. #define EXT_SENS_DATA_07 0x50
  137. #define EXT_SENS_DATA_08 0x51
  138. #define EXT_SENS_DATA_09 0x52
  139. #define EXT_SENS_DATA_10 0x53
  140. #define EXT_SENS_DATA_11 0x54
  141. #define EXT_SENS_DATA_12 0x55
  142. #define EXT_SENS_DATA_13 0x56
  143. #define EXT_SENS_DATA_14 0x57
  144. #define EXT_SENS_DATA_15 0x58
  145. #define EXT_SENS_DATA_16 0x59
  146. #define EXT_SENS_DATA_17 0x5A
  147. #define EXT_SENS_DATA_18 0x5B
  148. #define EXT_SENS_DATA_19 0x5C
  149. #define EXT_SENS_DATA_20 0x5D
  150. #define EXT_SENS_DATA_21 0x5E
  151. #define EXT_SENS_DATA_22 0x5F
  152. #define EXT_SENS_DATA_23 0x60
  153. #define MOT_DETECT_STATUS 0x61
  154. #define I2C_SLV0_DO 0x63
  155. #define I2C_SLV1_DO 0x64
  156. #define I2C_SLV2_DO 0x65
  157. #define I2C_SLV3_DO 0x66
  158. #define I2C_MST_DELAY_CTRL 0x67
  159. #define SIGNAL_PATH_RESET 0x68
  160. #define MOT_DETECT_CTRL 0x69
  161. #define USER_CTRL 0x6A // Bit 7 enable DMP, bit 3 reset DMP
  162. #define PWR_MGMT_1 0x6B // Device defaults to the SLEEP mode
  163. #define PWR_MGMT_2 0x6C
  164. #define DMP_BANK 0x6D // Activates a specific bank in the DMP
  165. #define DMP_RW_PNT 0x6E // Set read/write pointer to a specific start address in specified DMP bank
  166. #define DMP_REG 0x6F // Register in DMP from which to read or to which to write
  167. #define DMP_REG_1 0x70
  168. #define DMP_REG_2 0x71
  169. #define FIFO_COUNTH 0x72
  170. #define FIFO_COUNTL 0x73
  171. #define FIFO_R_W 0x74
  172. #define WHO_AM_I_MPU9250 0x75 // Should return 0x71
  173. #define XA_OFFSET_H 0x77
  174. #define XA_OFFSET_L 0x78
  175. #define YA_OFFSET_H 0x7A
  176. #define YA_OFFSET_L 0x7B
  177. #define ZA_OFFSET_H 0x7D
  178. #define ZA_OFFSET_L 0x7E
  179.  
  180. // Using the MSENSR-9250 breakout board, ADO is set to 0
  181. // Seven-bit device address is 110100 for ADO = 0 and 110101 for ADO = 1
  182. #define ADO 1
  183. #if ADO
  184. #define MPU9250_ADDRESS 0x69 // Device address when ADO = 1
  185. #else
  186. #define MPU9250_ADDRESS 0x68 // Device address when ADO = 0
  187. #define AK8963_ADDRESS 0x0C // Address of magnetometer
  188. #endif
  189.  
  190. #define AHRS true // set to false for basic data read
  191. #define SerialDebug false // set to true to get Serial output for debugging
  192.  
  193. // Set initial input parameters
  194. enum Ascale {
  195. AFS_2G = 0,
  196. AFS_4G,
  197. AFS_8G,
  198. AFS_16G
  199. };
  200.  
  201. enum Gscale {
  202. GFS_250DPS = 0,
  203. GFS_500DPS,
  204. GFS_1000DPS,
  205. GFS_2000DPS
  206. };
  207.  
  208. enum Mscale {
  209. MFS_14BITS = 0, // 0.6 mG per LSB
  210. MFS_16BITS // 0.15 mG per LSB
  211. };
  212.  
  213. // Specify sensor full scale
  214. uint8_t Gscale = GFS_250DPS;
  215. uint8_t Ascale = AFS_2G;
  216. uint8_t Mscale = MFS_16BITS; // Choose either 14-bit or 16-bit magnetometer resolution
  217. uint8_t Mmode = 0x02; // 2 for 8 Hz, 6 for 100 Hz continuous magnetometer data read
  218. float aRes, gRes, mRes; // scale resolutions per LSB for the sensors
  219.  
  220. // Pin definitions
  221. int intPin = 12; // These can be changed, 2 and 3 are the Arduinos ext int pins
  222. int myLed = 13; // Set up pin 13 led for toggling
  223.  
  224. int16_t accelCount[3]; // Stores the 16-bit signed accelerometer sensor output
  225. int16_t gyroCount[3]; // Stores the 16-bit signed gyro sensor output
  226. int16_t magCount[3]; // Stores the 16-bit signed magnetometer sensor output
  227. float magCalibration[3] = {0, 0, 0}, magbias[3] = {0, 0, 0}; // Factory mag calibration and mag bias
  228. float gyroBias[3] = {0, 0, 0}, accelBias[3] = {0, 0, 0}; // Bias corrections for gyro and accelerometer
  229. int16_t tempCount; // temperature raw count output
  230. float temperature; // Stores the real internal chip temperature in degrees Celsius
  231. float SelfTest[6]; // holds results of gyro and accelerometer self test
  232.  
  233. // global constants for 9 DoF fusion and AHRS (Attitude and Heading Reference System)
  234. float GyroMeasError = PI * (40.0f / 180.0f); // gyroscope measurement error in rads/s (start at 40 deg/s)
  235. float GyroMeasDrift = PI * (0.0f / 180.0f); // gyroscope measurement drift in rad/s/s (start at 0.0 deg/s/s)
  236. // There is a tradeoff in the beta parameter between accuracy and response speed.
  237. // In the original Madgwick study, beta of 0.041 (corresponding to GyroMeasError of 2.7 degrees/s) was found to give optimal accuracy.
  238. // However, with this value, the LSM9SD0 response time is about 10 seconds to a stable initial quaternion.
  239. // Subsequent changes also require a longish lag time to a stable output, not fast enough for a quadcopter or robot car!
  240. // By increasing beta (GyroMeasError) by about a factor of fifteen, the response time constant is reduced to ~2 sec
  241. // I haven't noticed any reduction in solution accuracy. This is essentially the I coefficient in a PID control sense;
  242. // the bigger the feedback coefficient, the faster the solution converges, usually at the expense of accuracy.
  243. // In any case, this is the free parameter in the Madgwick filtering and fusion scheme.
  244. float beta = sqrt(3.0f / 4.0f) * GyroMeasError; // compute beta
  245. float zeta = sqrt(3.0f / 4.0f) * GyroMeasDrift; // compute zeta, the other free parameter in the Madgwick scheme usually set to a small or zero value
  246. #define Kp 2.0f * 5.0f // these are the free parameters in the Mahony filter and fusion scheme, Kp for proportional feedback, Ki for integral//5.0f
  247. #define Ki 0.0f
  248.  
  249. uint32_t delt_t = 0; // used to control display output rate
  250. uint32_t count = 0, sumCount = 0; // used to control display output rate
  251. float pitch, yaw, roll;
  252. float deltat = 0.0f, sum = 0.0f; // integration interval for both filter schemes
  253. uint32_t lastUpdate = 0, firstUpdate = 0; // used to calculate integration interval
  254. uint32_t Now = 0; // used to calculate integration interval
  255.  
  256. float ax, ay, az, gx, gy, gz, mx, my, mz; // variables to hold latest sensor data values
  257. float q[4] = {1.0f, 0.0f, 0.0f, 0.0f}; // vector to hold quaternion
  258. float eInt[3] = {0.0f, 0.0f, 0.0f}; // vector to hold integral error for Mahony method
  259.  
  260.  
  261. void setup()
  262. {
  263. Wire.begin();
  264. // TWBR = 12; // 400 kbit/sec I2C speed
  265. Serial.begin(115200);
  266.  
  267. // Set up the interrupt pin, its set as active high, push-pull
  268. pinMode(intPin, INPUT);
  269. digitalWrite(intPin, LOW);
  270. pinMode(myLed, OUTPUT);
  271. digitalWrite(myLed, HIGH);
  272. if (SerialDebug){
  273. Serial.println("MPU9250");
  274. Serial.println("9-DOF 16-bit");
  275. Serial.println("motion sensor");
  276. Serial.println("60 ug LSB");
  277. }
  278. delay(100);
  279. // Read the WHO_AM_I register, this is a good test of communication
  280. byte c = readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250); // Read WHO_AM_I register for MPU-9250
  281. if(SerialDebug){
  282. Serial.print("MPU9250 "); Serial.print("I AM "); Serial.print(c, HEX); Serial.print(" I should be "); Serial.println(0x71, HEX);
  283. Serial.println("MPU9250");
  284. Serial.println("I AM");
  285. Serial.println(c, HEX);
  286. Serial.println("I Should Be");
  287. Serial.println(0x71, HEX);
  288. }
  289. delay(100);
  290.  
  291. if (c == 0x71) // WHO_AM_I should always be 0x68
  292. {
  293. if(SerialDebug){
  294. Serial.println("MPU9250 is online...");
  295. }
  296.  
  297. MPU9250SelfTest(SelfTest); // Start by performing self test and reporting values
  298.  
  299. if(SerialDebug){
  300. Serial.print("x-axis self test: acceleration trim within : "); Serial.print(SelfTest[0],1); Serial.println("% of factory value");
  301. Serial.print("y-axis self test: acceleration trim within : "); Serial.print(SelfTest[1],1); Serial.println("% of factory value");
  302. Serial.print("z-axis self test: acceleration trim within : "); Serial.print(SelfTest[2],1); Serial.println("% of factory value");
  303. Serial.print("x-axis self test: gyration trim within : "); Serial.print(SelfTest[3],1); Serial.println("% of factory value");
  304. Serial.print("y-axis self test: gyration trim within : "); Serial.print(SelfTest[4],1); Serial.println("% of factory value");
  305. Serial.print("z-axis self test: gyration trim within : "); Serial.print(SelfTest[5],1); Serial.println("% of factory value");
  306. }
  307.  
  308. calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers
  309.  
  310. if(SerialDebug){
  311. Serial.println("MPU9250 bias");
  312. Serial.println(" x y z ");
  313. Serial.println((int)(1000*accelBias[0]));
  314. Serial.println((int)(1000*accelBias[1]));
  315. Serial.println((int)(1000*accelBias[2]));
  316. Serial.println("mg");
  317. Serial.println(gyroBias[0], 1);
  318. Serial.println(gyroBias[1], 1);
  319. Serial.println(gyroBias[2], 1);
  320. Serial.println("o/s");
  321. }
  322.  
  323. delay(100);
  324.  
  325. initMPU9250();
  326.  
  327. if(SerialDebug){
  328. Serial.println("MPU9250 initialized for active data mode...."); // Initialize device for active mode read of acclerometer, gyroscope, and temperature
  329. }
  330.  
  331. // Read the WHO_AM_I register of the magnetometer, this is a good test of communication
  332. byte d = readByte(AK8963_ADDRESS, WHO_AM_I_AK8963); // Read WHO_AM_I register for AK8963
  333.  
  334. if(SerialDebug){
  335. Serial.print("AK8963 "); Serial.print("I AM "); Serial.print(d, HEX); Serial.print(" I should be "); Serial.println(0x48, HEX);
  336. Serial.println("AK8963");
  337. Serial.println("I AM");
  338. Serial.println(d, HEX);
  339. Serial.println("I Should Be");
  340. Serial.println(0x48, HEX);
  341. }
  342. delay(100);
  343.  
  344. // Get magnetometer calibration from AK8963 ROM
  345. initAK8963(magCalibration); // Initialize device for active mode read of magnetometer
  346.  
  347. if(SerialDebug) {
  348. Serial.println("AK8963 initialized for active data mode....");
  349.  
  350. Serial.println("Calibration values: ");
  351. Serial.print("X-Axis sensitivity adjustment value "); Serial.println(magCalibration[0], 2);
  352. Serial.print("Y-Axis sensitivity adjustment value "); Serial.println(magCalibration[1], 2);
  353. Serial.print("Z-Axis sensitivity adjustment value "); Serial.println(magCalibration[2], 2);
  354.  
  355. Serial.println("AK8963");
  356. Serial.println("ASAX ");
  357. Serial.println(magCalibration[0], 2);
  358. Serial.println("ASAY ");
  359. Serial.println(magCalibration[1], 2);
  360. Serial.println("ASAZ ");
  361. Serial.println(magCalibration[2], 2);
  362. }
  363. delay(100);
  364. }
  365. else
  366. {
  367. Serial.print("Could not connect to MPU9250: 0x");
  368. Serial.println(c, HEX);
  369. while(1) ; // Loop forever if communication doesn't happen
  370. }
  371. }
  372.  
  373. void loop()
  374. {
  375. // If intPin goes high, all data registers have new data
  376. if (readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) { // On interrupt, check if data ready interrupt
  377. readAccelData(accelCount); // Read the x/y/z adc values
  378. getAres();
  379.  
  380. // Now we'll calculate the accleration value into actual g's
  381. ax = (float)accelCount[0]*aRes; // - accelBias[0]; // get actual g value, this depends on scale being set
  382. ay = (float)accelCount[1]*aRes; // - accelBias[1];
  383. az = (float)accelCount[2]*aRes; // - accelBias[2];
  384.  
  385. readGyroData(gyroCount); // Read the x/y/z adc values
  386. getGres();
  387.  
  388. // Calculate the gyro value into actual degrees per second
  389. gx = (float)gyroCount[0]*gRes; // get actual gyro value, this depends on scale being set
  390. gy = (float)gyroCount[1]*gRes;
  391. gz = (float)gyroCount[2]*gRes;
  392.  
  393. readMagData(magCount); // Read the x/y/z adc values
  394. getMres();
  395. magbias[0] = +470.; // User environmental x-axis correction in milliGauss, should be automatically calculated
  396. magbias[1] = +120.; // User environmental x-axis correction in milliGauss
  397. magbias[2] = +125.; // User environmental x-axis correction in milliGauss
  398.  
  399. // Calculate the magnetometer values in milliGauss
  400. // Include factory calibration per data sheet and user environmental corrections
  401. mx = (float)magCount[0]*mRes*magCalibration[0] - magbias[0]; // get actual magnetometer value, this depends on scale being set
  402. my = (float)magCount[1]*mRes*magCalibration[1] - magbias[1];
  403. mz = (float)magCount[2]*mRes*magCalibration[2] - magbias[2];
  404. }
  405.  
  406. Now = micros();
  407. deltat = ((Now - lastUpdate)/1000000.0f); // set integration time by time elapsed since last filter update
  408. lastUpdate = Now;
  409.  
  410. sum += deltat; // sum for averaging filter update rate
  411. sumCount++;
  412.  
  413. // Sensors x (y)-axis of the accelerometer is aligned with the y (x)-axis of the magnetometer;
  414. // the magnetometer z-axis (+ down) is opposite to z-axis (+ up) of accelerometer and gyro!
  415. // We have to make some allowance for this orientationmismatch in feeding the output to the quaternion filter.
  416. // For the MPU-9250, we have chosen a magnetic rotation that keeps the sensor forward along the x-axis just like
  417. // in the LSM9DS0 sensor. This rotation can be modified to allow any convenient orientation convention.
  418. // This is ok by aircraft orientation standards!
  419. // Pass gyro rate as rad/s
  420. //MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz);
  421. MahonyQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz);
  422.  
  423.  
  424. if (!AHRS) {
  425. delt_t = millis() - count;
  426. if(delt_t > 500) {
  427.  
  428. if(SerialDebug) {
  429. // Print acceleration values in milligs!
  430. Serial.print("X-acceleration: "); Serial.print(1000*ax); Serial.print(" mg ");
  431. Serial.print("Y-acceleration: "); Serial.print(1000*ay); Serial.print(" mg ");
  432. Serial.print("Z-acceleration: "); Serial.print(1000*az); Serial.println(" mg ");
  433.  
  434. // Print gyro values in degree/sec
  435. Serial.print("X-gyro rate: "); Serial.print(gx, 3); Serial.print(" degrees/sec ");
  436. Serial.print("Y-gyro rate: "); Serial.print(gy, 3); Serial.print(" degrees/sec ");
  437. Serial.print("Z-gyro rate: "); Serial.print(gz, 3); Serial.println(" degrees/sec");
  438.  
  439. // Print mag values in degree/sec
  440. Serial.print("X-mag field: "); Serial.print(mx); Serial.print(" mG ");
  441. Serial.print("Y-mag field: "); Serial.print(my); Serial.print(" mG ");
  442. Serial.print("Z-mag field: "); Serial.print(mz); Serial.println(" mG");
  443.  
  444. tempCount = readTempData(); // Read the adc values
  445. temperature = ((float) tempCount) / 333.87 + 21.0; // Temperature in degrees Centigrade
  446. // Print temperature in degrees Centigrade
  447. Serial.print("Temperature is "); Serial.print(temperature, 1); Serial.println(" degrees C"); // Print T values to tenths of s degree C
  448. }
  449.  
  450. count = millis();
  451. digitalWrite(myLed, !digitalRead(myLed)); // toggle led
  452. }
  453. }
  454. else {
  455.  
  456. // Serial print and/or display at 0.5 s rate independent of data rates
  457. delt_t = millis() - count;
  458. if (delt_t > 0.5) { // update LCD once per half-second independent of read rate
  459.  
  460. if(SerialDebug) {
  461. Serial.print("ax = "); Serial.print((int)1000*ax);
  462. Serial.print(" ay = "); Serial.print((int)1000*ay);
  463. Serial.print(" az = "); Serial.print((int)1000*az); Serial.println(" mg");
  464. Serial.print("gx = "); Serial.print( gx, 2);
  465. Serial.print(" gy = "); Serial.print( gy, 2);
  466. Serial.print(" gz = "); Serial.print( gz, 2); Serial.println(" deg/s");
  467. Serial.print("mx = "); Serial.print( (int)mx );
  468. Serial.print(" my = "); Serial.print( (int)my );
  469. Serial.print(" mz = "); Serial.print( (int)mz ); Serial.println(" mG");
  470.  
  471. Serial.print("q0 = "); Serial.print(q[0]);
  472. Serial.print(" qx = "); Serial.print(q[1]);
  473. Serial.print(" qy = "); Serial.print(q[2]);
  474. Serial.print(" qz = "); Serial.println(q[3]);
  475. }
  476.  
  477. // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation.
  478. // In this coordinate system, the positive z-axis is down toward Earth.
  479. // 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.
  480. // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative.
  481. // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll.
  482. // These arise from the definition of the homogeneous rotation matrix constructed from quaternions.
  483. // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be
  484. // applied in the correct order which for this configuration is yaw, pitch, and then roll.
  485. // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links.
  486. 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]);
  487. pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
  488. 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]);
  489. pitch *= 180.0f / PI;
  490. yaw *= 180.0f / PI;
  491. yaw -= 8.33; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04; -=13.8
  492. roll *= 180.0f / PI;
  493.  
  494. if(SerialDebug) {
  495. Serial.print("Yaw, Pitch, Roll: ");
  496. Serial.print(yaw, 2);
  497. Serial.print(" ");
  498. Serial.print(pitch, 2);
  499. Serial.print(" ");
  500. Serial.println(roll, 2);
  501.  
  502. //Serial.print("rate = "); Serial.print((float)sumCount/sum, 2); Serial.println(" Hz");
  503. }
  504. //Serial.print("Yaw, Pitch, Roll: ");
  505. //Serial.print(yaw, 2);
  506. //Serial.print(";");
  507. //Serial.print(pitch, 2);
  508. //Serial.print(";");
  509. Serial.print(roll, 2);
  510. Serial.print("\n");
  511. //Serial.println("rt: "); Serial.println((float) sumCount / sum, 2); Serial.println(" Hz");
  512. //Serial.print("\n");
  513.  
  514. count = millis();
  515. sumCount = 0;
  516. sum = 0;
  517. }
  518. }
  519.  
  520. }
  521.  
  522. //===================================================================================================================
  523. //====== Set of useful function to access acceleration. gyroscope, magnetometer, and temperature data
  524. //===================================================================================================================
  525.  
  526. void getMres() {
  527. switch (Mscale)
  528. {
  529. // Possible magnetometer scales (and their register bit settings) are:
  530. // 14 bit resolution (0) and 16 bit resolution (1)
  531. case MFS_14BITS:
  532. mRes = 10.*4912./8190.; // Proper scale to return milliGauss
  533. break;
  534. case MFS_16BITS:
  535. mRes = 10.*4912./32760.0; // Proper scale to return milliGauss
  536. break;
  537. }
  538. }
  539.  
  540. void getGres() {
  541. switch (Gscale)
  542. {
  543. // Possible gyro scales (and their register bit settings) are:
  544. // 250 DPS (00), 500 DPS (01), 1000 DPS (10), and 2000 DPS (11).
  545. // Here's a bit of an algorith to calculate DPS/(ADC tick) based on that 2-bit value:
  546. case GFS_250DPS:
  547. gRes = 250.0/32768.0;
  548. break;
  549. case GFS_500DPS:
  550. gRes = 500.0/32768.0;
  551. break;
  552. case GFS_1000DPS:
  553. gRes = 1000.0/32768.0;
  554. break;
  555. case GFS_2000DPS:
  556. gRes = 2000.0/32768.0;
  557. break;
  558. }
  559. }
  560.  
  561. void getAres() {
  562. switch (Ascale)
  563. {
  564. // Possible accelerometer scales (and their register bit settings) are:
  565. // 2 Gs (00), 4 Gs (01), 8 Gs (10), and 16 Gs (11).
  566. // Here's a bit of an algorith to calculate DPS/(ADC tick) based on that 2-bit value:
  567. case AFS_2G:
  568. aRes = 2.0/32768.0;
  569. break;
  570. case AFS_4G:
  571. aRes = 4.0/32768.0;
  572. break;
  573. case AFS_8G:
  574. aRes = 8.0/32768.0;
  575. break;
  576. case AFS_16G:
  577. aRes = 16.0/32768.0;
  578. break;
  579. }
  580. }
  581.  
  582.  
  583. void readAccelData(int16_t * destination)
  584. {
  585. uint8_t rawData[6]; // x/y/z accel register data stored here
  586. readBytes(MPU9250_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]); // Read the six raw data registers into data array
  587. destination[0] = ((int16_t)rawData[0] << 8) | rawData[1] ; // Turn the MSB and LSB into a signed 16-bit value
  588. destination[1] = ((int16_t)rawData[2] << 8) | rawData[3] ;
  589. destination[2] = ((int16_t)rawData[4] << 8) | rawData[5] ;
  590. }
  591.  
  592.  
  593. void readGyroData(int16_t * destination)
  594. {
  595. uint8_t rawData[6]; // x/y/z gyro register data stored here
  596. readBytes(MPU9250_ADDRESS, GYRO_XOUT_H, 6, &rawData[0]); // Read the six raw data registers sequentially into data array
  597. destination[0] = ((int16_t)rawData[0] << 8) | rawData[1] ; // Turn the MSB and LSB into a signed 16-bit value
  598. destination[1] = ((int16_t)rawData[2] << 8) | rawData[3] ;
  599. destination[2] = ((int16_t)rawData[4] << 8) | rawData[5] ;
  600. }
  601.  
  602. void readMagData(int16_t * destination)
  603. {
  604. uint8_t rawData[7]; // x/y/z gyro register data, ST2 register stored here, must read ST2 at end of data acquisition
  605. if(readByte(AK8963_ADDRESS, AK8963_ST1) & 0x01) { // wait for magnetometer data ready bit to be set
  606. readBytes(AK8963_ADDRESS, AK8963_XOUT_L, 7, &rawData[0]); // Read the six raw data and ST2 registers sequentially into data array
  607. uint8_t c = rawData[6]; // End data read by reading ST2 register
  608. if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data
  609. destination[0] = ((int16_t)rawData[1] << 8) | rawData[0] ; // Turn the MSB and LSB into a signed 16-bit value
  610. destination[1] = ((int16_t)rawData[3] << 8) | rawData[2] ; // Data stored as little Endian
  611. destination[2] = ((int16_t)rawData[5] << 8) | rawData[4] ;
  612. }
  613. }
  614. }
  615.  
  616. int16_t readTempData()
  617. {
  618. uint8_t rawData[2]; // x/y/z gyro register data stored here
  619. readBytes(MPU9250_ADDRESS, TEMP_OUT_H, 2, &rawData[0]); // Read the two raw data registers sequentially into data array
  620. return ((int16_t)rawData[0] << 8) | rawData[1] ; // Turn the MSB and LSB into a 16-bit value
  621. }
  622.  
  623. void initAK8963(float * destination)
  624. {
  625. // First extract the factory calibration for each magnetometer axis
  626. uint8_t rawData[3]; // x/y/z gyro calibration data stored here
  627. writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer
  628. delay(10);
  629. writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x0F); // Enter Fuse ROM access mode
  630. delay(10);
  631. readBytes(AK8963_ADDRESS, AK8963_ASAX, 3, &rawData[0]); // Read the x-, y-, and z-axis calibration values
  632. destination[0] = (float)(rawData[0] - 128)/256. + 1.; // Return x-axis sensitivity adjustment values, etc.
  633. destination[1] = (float)(rawData[1] - 128)/256. + 1.;
  634. destination[2] = (float)(rawData[2] - 128)/256. + 1.;
  635. writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer
  636. delay(10);
  637. // Configure the magnetometer for continuous read and highest resolution
  638. // set Mscale bit 4 to 1 (0) to enable 16 (14) bit resolution in CNTL register,
  639. // and enable continuous mode data acquisition Mmode (bits [3:0]), 0010 for 8 Hz and 0110 for 100 Hz sample rates
  640. writeByte(AK8963_ADDRESS, AK8963_CNTL, Mscale << 4 | Mmode); // Set magnetometer data resolution and sample ODR
  641. delay(10);
  642. }
  643.  
  644.  
  645. void initMPU9250()
  646. {
  647. // wake up device
  648. writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x00); // Clear sleep mode bit (6), enable all sensors
  649. delay(100); // Wait for all registers to reset
  650.  
  651. // get stable time source
  652. writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x01); // Auto select clock source to be PLL gyroscope reference if ready else
  653. delay(200);
  654.  
  655. // Configure Gyro and Thermometer
  656. // Disable FSYNC and set thermometer and gyro bandwidth to 41 and 42 Hz, respectively;
  657. // minimum delay time for this setting is 5.9 ms, which means sensor fusion update rates cannot
  658. // be higher than 1 / 0.0059 = 170 Hz
  659. // DLPF_CFG = bits 2:0 = 011; this limits the sample rate to 1000 Hz for both
  660. // With the MPU9250, it is possible to get gyro sample rates of 32 kHz (!), 8 kHz, or 1 kHz
  661. writeByte(MPU9250_ADDRESS, CONFIG, 0x03);
  662.  
  663. // Set sample rate = gyroscope output rate/(1 + SMPLRT_DIV)
  664. writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x04); // Use a 200 Hz rate; a rate consistent with the filter update rate
  665. // determined inset in CONFIG above
  666.  
  667. // Set gyroscope full scale range
  668. // Range selects FS_SEL and AFS_SEL are 0 - 3, so 2-bit values are left-shifted into positions 4:3
  669. uint8_t c = readByte(MPU9250_ADDRESS, GYRO_CONFIG);
  670. // writeRegister(GYRO_CONFIG, c & ~0xE0); // Clear self-test bits [7:5]
  671. writeByte(MPU9250_ADDRESS, GYRO_CONFIG, c & ~0x02); // Clear Fchoice bits [1:0]
  672. writeByte(MPU9250_ADDRESS, GYRO_CONFIG, c & ~0x18); // Clear AFS bits [4:3]
  673. writeByte(MPU9250_ADDRESS, GYRO_CONFIG, c | Gscale << 3); // Set full scale range for the gyro
  674. // writeRegister(GYRO_CONFIG, c | 0x00); // Set Fchoice for the gyro to 11 by writing its inverse to bits 1:0 of GYRO_CONFIG
  675.  
  676. // Set accelerometer full-scale range configuration
  677. c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG);
  678. // writeRegister(ACCEL_CONFIG, c & ~0xE0); // Clear self-test bits [7:5]
  679. writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, c & ~0x18); // Clear AFS bits [4:3]
  680. writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, c | Ascale << 3); // Set full scale range for the accelerometer
  681.  
  682. // Set accelerometer sample rate configuration
  683. // It is possible to get a 4 kHz sample rate from the accelerometer by choosing 1 for
  684. // accel_fchoice_b bit [3]; in this case the bandwidth is 1.13 kHz
  685. c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG2);
  686. writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c & ~0x0F); // Clear accel_fchoice_b (bit 3) and A_DLPFG (bits [2:0])
  687. writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c | 0x03); // Set accelerometer rate to 1 kHz and bandwidth to 41 Hz
  688.  
  689. // The accelerometer, gyro, and thermometer are set to 1 kHz sample rates,
  690. // but all these rates are further reduced by a factor of 5 to 200 Hz because of the SMPLRT_DIV setting
  691.  
  692. // Configure Interrupts and Bypass Enable
  693. // Set interrupt pin active high, push-pull, hold interrupt pin level HIGH until interrupt cleared,
  694. // clear on read of INT_STATUS, and enable I2C_BYPASS_EN so additional chips
  695. // can join the I2C bus and all can be controlled by the Arduino as master
  696. writeByte(MPU9250_ADDRESS, INT_PIN_CFG, 0x22);
  697. writeByte(MPU9250_ADDRESS, INT_ENABLE, 0x01); // Enable data ready (bit 0) interrupt
  698. delay(100);
  699. }
  700.  
  701.  
  702. // Function which accumulates gyro and accelerometer data after device initialization. It calculates the average
  703. // of the at-rest readings and then loads the resulting offsets into accelerometer and gyro bias registers.
  704. void calibrateMPU9250(float * dest1, float * dest2)
  705. {
  706. uint8_t data[12]; // data array to hold accelerometer and gyro x, y, z, data
  707. uint16_t ii, packet_count, fifo_count;
  708. int32_t gyro_bias[3] = {0, 0, 0}, accel_bias[3] = {0, 0, 0};
  709.  
  710. // reset device
  711. writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x80); // Write a one to bit 7 reset bit; toggle reset device
  712. delay(100);
  713.  
  714. // get stable time source; Auto select clock source to be PLL gyroscope reference if ready
  715. // else use the internal oscillator, bits 2:0 = 001
  716. writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x01);
  717. writeByte(MPU9250_ADDRESS, PWR_MGMT_2, 0x00);
  718. delay(200);
  719.  
  720. // Configure device for bias calculation
  721. writeByte(MPU9250_ADDRESS, INT_ENABLE, 0x00); // Disable all interrupts
  722. writeByte(MPU9250_ADDRESS, FIFO_EN, 0x00); // Disable FIFO
  723. writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x00); // Turn on internal clock source
  724. writeByte(MPU9250_ADDRESS, I2C_MST_CTRL, 0x00); // Disable I2C master
  725. writeByte(MPU9250_ADDRESS, USER_CTRL, 0x00); // Disable FIFO and I2C master modes
  726. writeByte(MPU9250_ADDRESS, USER_CTRL, 0x0C); // Reset FIFO and DMP
  727. delay(15);
  728.  
  729. // Configure MPU6050 gyro and accelerometer for bias calculation
  730. writeByte(MPU9250_ADDRESS, CONFIG, 0x01); // Set low-pass filter to 188 Hz
  731. writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x00); // Set sample rate to 1 kHz
  732. writeByte(MPU9250_ADDRESS, GYRO_CONFIG, 0x00); // Set gyro full-scale to 250 degrees per second, maximum sensitivity
  733. writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, 0x00); // Set accelerometer full-scale to 2 g, maximum sensitivity
  734.  
  735. uint16_t gyrosensitivity = 131; // = 131 LSB/degrees/sec
  736. uint16_t accelsensitivity = 16384; // = 16384 LSB/g
  737.  
  738. // Configure FIFO to capture accelerometer and gyro data for bias calculation
  739. writeByte(MPU9250_ADDRESS, USER_CTRL, 0x40); // Enable FIFO
  740. writeByte(MPU9250_ADDRESS, FIFO_EN, 0x78); // Enable gyro and accelerometer sensors for FIFO (max size 512 bytes in MPU-9150)
  741. delay(40); // accumulate 40 samples in 40 milliseconds = 480 bytes
  742.  
  743. // At end of sample accumulation, turn off FIFO sensor read
  744. writeByte(MPU9250_ADDRESS, FIFO_EN, 0x00); // Disable gyro and accelerometer sensors for FIFO
  745. readBytes(MPU9250_ADDRESS, FIFO_COUNTH, 2, &data[0]); // read FIFO sample count
  746. fifo_count = ((uint16_t)data[0] << 8) | data[1];
  747. packet_count = fifo_count/12;// How many sets of full gyro and accelerometer data for averaging
  748.  
  749. for (ii = 0; ii < packet_count; ii++) {
  750. int16_t accel_temp[3] = {0, 0, 0}, gyro_temp[3] = {0, 0, 0};
  751. readBytes(MPU9250_ADDRESS, FIFO_R_W, 12, &data[0]); // read data for averaging
  752. accel_temp[0] = (int16_t) (((int16_t)data[0] << 8) | data[1] ) ; // Form signed 16-bit integer for each sample in FIFO
  753. accel_temp[1] = (int16_t) (((int16_t)data[2] << 8) | data[3] ) ;
  754. accel_temp[2] = (int16_t) (((int16_t)data[4] << 8) | data[5] ) ;
  755. gyro_temp[0] = (int16_t) (((int16_t)data[6] << 8) | data[7] ) ;
  756. gyro_temp[1] = (int16_t) (((int16_t)data[8] << 8) | data[9] ) ;
  757. gyro_temp[2] = (int16_t) (((int16_t)data[10] << 8) | data[11]) ;
  758.  
  759. accel_bias[0] += (int32_t) accel_temp[0]; // Sum individual signed 16-bit biases to get accumulated signed 32-bit biases
  760. accel_bias[1] += (int32_t) accel_temp[1];
  761. accel_bias[2] += (int32_t) accel_temp[2];
  762. gyro_bias[0] += (int32_t) gyro_temp[0];
  763. gyro_bias[1] += (int32_t) gyro_temp[1];
  764. gyro_bias[2] += (int32_t) gyro_temp[2];
  765.  
  766. }
  767. accel_bias[0] /= (int32_t) packet_count; // Normalize sums to get average count biases
  768. accel_bias[1] /= (int32_t) packet_count;
  769. accel_bias[2] /= (int32_t) packet_count;
  770. gyro_bias[0] /= (int32_t) packet_count;
  771. gyro_bias[1] /= (int32_t) packet_count;
  772. gyro_bias[2] /= (int32_t) packet_count;
  773.  
  774. if(accel_bias[2] > 0L) {accel_bias[2] -= (int32_t) accelsensitivity;} // Remove gravity from the z-axis accelerometer bias calculation
  775. else {accel_bias[2] += (int32_t) accelsensitivity;}
  776.  
  777. // Construct the gyro biases for push to the hardware gyro bias registers, which are reset to zero upon device startup
  778. 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
  779. data[1] = (-gyro_bias[0]/4) & 0xFF; // Biases are additive, so change sign on calculated average gyro biases
  780. data[2] = (-gyro_bias[1]/4 >> 8) & 0xFF;
  781. data[3] = (-gyro_bias[1]/4) & 0xFF;
  782. data[4] = (-gyro_bias[2]/4 >> 8) & 0xFF;
  783. data[5] = (-gyro_bias[2]/4) & 0xFF;
  784.  
  785. // Push gyro biases to hardware registers
  786. writeByte(MPU9250_ADDRESS, XG_OFFSET_H, data[0]);
  787. writeByte(MPU9250_ADDRESS, XG_OFFSET_L, data[1]);
  788. writeByte(MPU9250_ADDRESS, YG_OFFSET_H, data[2]);
  789. writeByte(MPU9250_ADDRESS, YG_OFFSET_L, data[3]);
  790. writeByte(MPU9250_ADDRESS, ZG_OFFSET_H, data[4]);
  791. writeByte(MPU9250_ADDRESS, ZG_OFFSET_L, data[5]);
  792.  
  793. // Output scaled gyro biases for display in the main program
  794. dest1[0] = (float) gyro_bias[0]/(float) gyrosensitivity;
  795. dest1[1] = (float) gyro_bias[1]/(float) gyrosensitivity;
  796. dest1[2] = (float) gyro_bias[2]/(float) gyrosensitivity;
  797.  
  798. // Construct the accelerometer biases for push to the hardware accelerometer bias registers. These registers contain
  799. // factory trim values which must be added to the calculated accelerometer biases; on boot up these registers will hold
  800. // non-zero values. In addition, bit 0 of the lower byte must be preserved since it is used for temperature
  801. // compensation calculations. Accelerometer bias registers expect bias input as 2048 LSB per g, so that
  802. // the accelerometer biases calculated above must be divided by 8.
  803.  
  804. int32_t accel_bias_reg[3] = {0, 0, 0}; // A place to hold the factory accelerometer trim biases
  805. readBytes(MPU9250_ADDRESS, XA_OFFSET_H, 2, &data[0]); // Read factory accelerometer trim values
  806. accel_bias_reg[0] = (int32_t) (((int16_t)data[0] << 8) | data[1]);
  807. readBytes(MPU9250_ADDRESS, YA_OFFSET_H, 2, &data[0]);
  808. accel_bias_reg[1] = (int32_t) (((int16_t)data[0] << 8) | data[1]);
  809. readBytes(MPU9250_ADDRESS, ZA_OFFSET_H, 2, &data[0]);
  810. accel_bias_reg[2] = (int32_t) (((int16_t)data[0] << 8) | data[1]);
  811.  
  812. uint32_t mask = 1uL; // Define mask for temperature compensation bit 0 of lower byte of accelerometer bias registers
  813. uint8_t mask_bit[3] = {0, 0, 0}; // Define array to hold mask bit for each accelerometer bias axis
  814.  
  815. for(ii = 0; ii < 3; ii++) {
  816. if((accel_bias_reg[ii] & mask)) mask_bit[ii] = 0x01; // If temperature compensation bit is set, record that fact in mask_bit
  817. }
  818.  
  819. // Construct total accelerometer bias, including calculated average accelerometer bias from above
  820. accel_bias_reg[0] -= (accel_bias[0]/8); // Subtract calculated averaged accelerometer bias scaled to 2048 LSB/g (16 g full scale)
  821. accel_bias_reg[1] -= (accel_bias[1]/8);
  822. accel_bias_reg[2] -= (accel_bias[2]/8);
  823.  
  824. data[0] = (accel_bias_reg[0] >> 8) & 0xFF;
  825. data[1] = (accel_bias_reg[0]) & 0xFF;
  826. data[1] = data[1] | mask_bit[0]; // preserve temperature compensation bit when writing back to accelerometer bias registers
  827. data[2] = (accel_bias_reg[1] >> 8) & 0xFF;
  828. data[3] = (accel_bias_reg[1]) & 0xFF;
  829. data[3] = data[3] | mask_bit[1]; // preserve temperature compensation bit when writing back to accelerometer bias registers
  830. data[4] = (accel_bias_reg[2] >> 8) & 0xFF;
  831. data[5] = (accel_bias_reg[2]) & 0xFF;
  832. data[5] = data[5] | mask_bit[2]; // preserve temperature compensation bit when writing back to accelerometer bias registers
  833.  
  834. // Apparently this is not working for the acceleration biases in the MPU-9250
  835. // Are we handling the temperature correction bit properly?
  836. // Push accelerometer biases to hardware registers
  837. writeByte(MPU9250_ADDRESS, XA_OFFSET_H, data[0]);
  838. writeByte(MPU9250_ADDRESS, XA_OFFSET_L, data[1]);
  839. writeByte(MPU9250_ADDRESS, YA_OFFSET_H, data[2]);
  840. writeByte(MPU9250_ADDRESS, YA_OFFSET_L, data[3]);
  841. writeByte(MPU9250_ADDRESS, ZA_OFFSET_H, data[4]);
  842. writeByte(MPU9250_ADDRESS, ZA_OFFSET_L, data[5]);
  843.  
  844. // Output scaled accelerometer biases for display in the main program
  845. dest2[0] = (float)accel_bias[0]/(float)accelsensitivity;
  846. dest2[1] = (float)accel_bias[1]/(float)accelsensitivity;
  847. dest2[2] = (float)accel_bias[2]/(float)accelsensitivity;
  848. }
  849.  
  850.  
  851. // Accelerometer and gyroscope self test; check calibration wrt factory settings
  852. void MPU9250SelfTest(float * destination) // Should return percent deviation from factory trim values, +/- 14 or less deviation is a pass
  853. {
  854. uint8_t rawData[6] = {0, 0, 0, 0, 0, 0};
  855. uint8_t selfTest[6];
  856. int16_t gAvg[3], aAvg[3], aSTAvg[3], gSTAvg[3];
  857. float factoryTrim[6];
  858. uint8_t FS = 0;
  859.  
  860. writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x00); // Set gyro sample rate to 1 kHz
  861. writeByte(MPU9250_ADDRESS, CONFIG, 0x02); // Set gyro sample rate to 1 kHz and DLPF to 92 Hz
  862. writeByte(MPU9250_ADDRESS, GYRO_CONFIG, 1<<FS); // Set full scale range for the gyro to 250 dps
  863. writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, 0x02); // Set accelerometer rate to 1 kHz and bandwidth to 92 Hz
  864. writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, 1<<FS); // Set full scale range for the accelerometer to 2 g
  865.  
  866. for( int ii = 0; ii < 200; ii++) { // get average current values of gyro and acclerometer
  867.  
  868. readBytes(MPU9250_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]); // Read the six raw data registers into data array
  869. aAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value
  870. aAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ;
  871. aAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ;
  872.  
  873. readBytes(MPU9250_ADDRESS, GYRO_XOUT_H, 6, &rawData[0]); // Read the six raw data registers sequentially into data array
  874. gAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value
  875. gAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ;
  876. gAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ;
  877. }
  878.  
  879. for (int ii =0; ii < 3; ii++) { // Get average of 200 values and store as average current readings
  880. aAvg[ii] /= 200;
  881. gAvg[ii] /= 200;
  882. }
  883.  
  884. // Configure the accelerometer for self-test
  885. writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, 0xE0); // Enable self test on all three axes and set accelerometer range to +/- 2 g
  886. writeByte(MPU9250_ADDRESS, GYRO_CONFIG, 0xE0); // Enable self test on all three axes and set gyro range to +/- 250 degrees/s
  887. delay(25); // Delay a while to let the device stabilize
  888.  
  889. for( int ii = 0; ii < 200; ii++) { // get average self-test values of gyro and acclerometer
  890.  
  891. readBytes(MPU9250_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]); // Read the six raw data registers into data array
  892. aSTAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value
  893. aSTAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ;
  894. aSTAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ;
  895.  
  896. readBytes(MPU9250_ADDRESS, GYRO_XOUT_H, 6, &rawData[0]); // Read the six raw data registers sequentially into data array
  897. gSTAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value
  898. gSTAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ;
  899. gSTAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ;
  900. }
  901.  
  902. for (int ii =0; ii < 3; ii++) { // Get average of 200 values and store as average self-test readings
  903. aSTAvg[ii] /= 200;
  904. gSTAvg[ii] /= 200;
  905. }
  906.  
  907. // Configure the gyro and accelerometer for normal operation
  908. writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, 0x00);
  909. writeByte(MPU9250_ADDRESS, GYRO_CONFIG, 0x00);
  910. delay(25); // Delay a while to let the device stabilize
  911.  
  912. // Retrieve accelerometer and gyro factory Self-Test Code from USR_Reg
  913. selfTest[0] = readByte(MPU9250_ADDRESS, SELF_TEST_X_ACCEL); // X-axis accel self-test results
  914. selfTest[1] = readByte(MPU9250_ADDRESS, SELF_TEST_Y_ACCEL); // Y-axis accel self-test results
  915. selfTest[2] = readByte(MPU9250_ADDRESS, SELF_TEST_Z_ACCEL); // Z-axis accel self-test results
  916. selfTest[3] = readByte(MPU9250_ADDRESS, SELF_TEST_X_GYRO); // X-axis gyro self-test results
  917. selfTest[4] = readByte(MPU9250_ADDRESS, SELF_TEST_Y_GYRO); // Y-axis gyro self-test results
  918. selfTest[5] = readByte(MPU9250_ADDRESS, SELF_TEST_Z_GYRO); // Z-axis gyro self-test results
  919.  
  920. // Retrieve factory self-test value from self-test code reads
  921. factoryTrim[0] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[0] - 1.0) )); // FT[Xa] factory trim calculation
  922. factoryTrim[1] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[1] - 1.0) )); // FT[Ya] factory trim calculation
  923. factoryTrim[2] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[2] - 1.0) )); // FT[Za] factory trim calculation
  924. factoryTrim[3] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[3] - 1.0) )); // FT[Xg] factory trim calculation
  925. factoryTrim[4] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[4] - 1.0) )); // FT[Yg] factory trim calculation
  926. factoryTrim[5] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[5] - 1.0) )); // FT[Zg] factory trim calculation
  927.  
  928. // Report results as a ratio of (STR - FT)/FT; the change from Factory Trim of the Self-Test Response
  929. // To get percent, must multiply by 100
  930. for (int i = 0; i < 3; i++) {
  931. destination[i] = 100.0*((float)(aSTAvg[i] - aAvg[i]))/factoryTrim[i]; // Report percent differences
  932. destination[i+3] = 100.0*((float)(gSTAvg[i] - gAvg[i]))/factoryTrim[i+3]; // Report percent differences
  933. }
  934.  
  935. }
  936.  
  937.  
  938. // Wire.h read and write protocols
  939. void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
  940. {
  941. Wire.beginTransmission(address); // Initialize the Tx buffer
  942. Wire.write(subAddress); // Put slave register address in Tx buffer
  943. Wire.write(data); // Put data in Tx buffer
  944. Wire.endTransmission(); // Send the Tx buffer
  945. }
  946.  
  947. uint8_t readByte(uint8_t address, uint8_t subAddress)
  948. {
  949. uint8_t data; // `data` will store the register data
  950. Wire.beginTransmission(address); // Initialize the Tx buffer
  951. Wire.write(subAddress); // Put slave register address in Tx buffer
  952. Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
  953. Wire.requestFrom(address, (uint8_t) 1); // Read one byte from slave register address
  954. data = Wire.read(); // Fill Rx buffer with result
  955. return data; // Return data read from slave register
  956. }
  957.  
  958. void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
  959. {
  960. Wire.beginTransmission(address); // Initialize the Tx buffer
  961. Wire.write(subAddress); // Put slave register address in Tx buffer
  962. Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
  963. uint8_t i = 0;
  964. Wire.requestFrom(address, count); // Read bytes from slave register address
  965. while (Wire.available()) {
  966. dest[i++] = Wire.read(); } // Put read results in the Rx buffer
  967. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement