Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9140304
  • 博文数量: 1725
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 19840
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1725)

文章存档

2024年(1)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: Android平台

2017-10-09 19:43:04

https://wenku.baidu.com/view/8401d0e359eef8c75ebfb367.html
https://github.com/Hydr0Dr4gon/MPU9250-on-Teensy-LC/tree/master/Teensy_Tracker_Sketch


点击(此处)折叠或打开

  1. /* Dragon Labs VR Headset Tracker
  2.   by: Mark Hodgkinson
  3.   date: 20 September 2017
  4.   license: MIT Licence
  5.   Derived heavily from Kris Winer's example code for the MPU9250 and infinitellamas's code for an
  6.   Arduino Tracker for OSVR. Many thanks to both of them for making their code public and doing
  7.   most of the heavy lifting.
  8.   This is the Teensy code for the Dragon Labs VR Headset
  9.   Hardware:
  10.   Teensy LC
  11.   InvenSense MPU9250 on Sparkfun breakout
  12. */

  13. #include <i2c_t3.h>


  14. // 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
  15. // above document; the MPU9250 and MPU9150 are virtually identical but the latter has a different register map
  16. //
  17. //Magnetometer Registers
  18. #define AK8963_ADDRESS 0x0C
  19. #define AK8963_WHO_AM_I 0x00 // should return 0x48
  20. #define AK8963_INFO 0x01
  21. #define AK8963_ST1 0x02 // data ready status bit 0
  22. #define AK8963_XOUT_L 0x03 // data
  23. #define AK8963_XOUT_H 0x04
  24. #define AK8963_YOUT_L 0x05
  25. #define AK8963_YOUT_H 0x06
  26. #define AK8963_ZOUT_L 0x07
  27. #define AK8963_ZOUT_H 0x08
  28. #define AK8963_ST2 0x09 // Data overflow bit 3 and data read error status bit 2
  29. #define AK8963_CNTL 0x0A // Power down (0000), single-measurement (0001), self-test (1000) and Fuse ROM (1111) modes on bits 3:0
  30. #define AK8963_ASTC 0x0C // Self test control
  31. #define AK8963_I2CDIS 0x0F // I2C disable
  32. #define AK8963_ASAX 0x10 // Fuse ROM x-axis sensitivity adjustment value
  33. #define AK8963_ASAY 0x11 // Fuse ROM y-axis sensitivity adjustment value
  34. #define AK8963_ASAZ 0x12 // Fuse ROM z-axis sensitivity adjustment value

  35. #define SELF_TEST_X_GYRO 0x00
  36. #define SELF_TEST_Y_GYRO 0x01
  37. #define SELF_TEST_Z_GYRO 0x02

  38. #define SELF_TEST_X_ACCEL 0x0D
  39. #define SELF_TEST_Y_ACCEL 0x0E
  40. #define SELF_TEST_Z_ACCEL 0x0F

  41. #define SELF_TEST_A 0x10

  42. #define XG_OFFSET_H 0x13 // User-defined trim values for gyroscope
  43. #define XG_OFFSET_L 0x14
  44. #define YG_OFFSET_H 0x15
  45. #define YG_OFFSET_L 0x16
  46. #define ZG_OFFSET_H 0x17
  47. #define ZG_OFFSET_L 0x18
  48. #define SMPLRT_DIV 0x19
  49. #define CONFIG 0x1A
  50. #define GYRO_CONFIG 0x1B
  51. #define ACCEL_CONFIG 0x1C
  52. #define ACCEL_CONFIG2 0x1D
  53. #define LP_ACCEL_ODR 0x1E
  54. #define WOM_THR 0x1F

  55. #define MOT_DUR 0x20 // Duration counter threshold for motion interrupt generation, 1 kHz rate, LSB = 1 ms
  56. #define ZMOT_THR 0x21 // Zero-motion detection threshold bits [7:0]
  57. #define ZRMOT_DUR 0x22 // Duration counter threshold for zero motion interrupt generation, 16 Hz rate, LSB = 64 ms

  58. #define FIFO_EN 0x23
  59. #define I2C_MST_CTRL 0x24
  60. #define I2C_SLV0_ADDR 0x25
  61. #define I2C_SLV0_REG 0x26
  62. #define I2C_SLV0_CTRL 0x27
  63. #define I2C_SLV1_ADDR 0x28
  64. #define I2C_SLV1_REG 0x29
  65. #define I2C_SLV1_CTRL 0x2A
  66. #define I2C_SLV2_ADDR 0x2B
  67. #define I2C_SLV2_REG 0x2C
  68. #define I2C_SLV2_CTRL 0x2D
  69. #define I2C_SLV3_ADDR 0x2E
  70. #define I2C_SLV3_REG 0x2F
  71. #define I2C_SLV3_CTRL 0x30
  72. #define I2C_SLV4_ADDR 0x31
  73. #define I2C_SLV4_REG 0x32
  74. #define I2C_SLV4_DO 0x33
  75. #define I2C_SLV4_CTRL 0x34
  76. #define I2C_SLV4_DI 0x35
  77. #define I2C_MST_STATUS 0x36
  78. #define INT_PIN_CFG 0x37
  79. #define INT_ENABLE 0x38
  80. #define DMP_INT_STATUS 0x39 // Check DMP interrupt
  81. #define INT_STATUS 0x3A
  82. #define ACCEL_XOUT_H 0x3B
  83. #define ACCEL_XOUT_L 0x3C
  84. #define ACCEL_YOUT_H 0x3D
  85. #define ACCEL_YOUT_L 0x3E
  86. #define ACCEL_ZOUT_H 0x3F
  87. #define ACCEL_ZOUT_L 0x40
  88. #define TEMP_OUT_H 0x41
  89. #define TEMP_OUT_L 0x42
  90. #define GYRO_XOUT_H 0x43
  91. #define GYRO_XOUT_L 0x44
  92. #define GYRO_YOUT_H 0x45
  93. #define GYRO_YOUT_L 0x46
  94. #define GYRO_ZOUT_H 0x47
  95. #define GYRO_ZOUT_L 0x48
  96. #define EXT_SENS_DATA_00 0x49
  97. #define EXT_SENS_DATA_01 0x4A
  98. #define EXT_SENS_DATA_02 0x4B
  99. #define EXT_SENS_DATA_03 0x4C
  100. #define EXT_SENS_DATA_04 0x4D
  101. #define EXT_SENS_DATA_05 0x4E
  102. #define EXT_SENS_DATA_06 0x4F
  103. #define EXT_SENS_DATA_07 0x50
  104. #define EXT_SENS_DATA_08 0x51
  105. #define EXT_SENS_DATA_09 0x52
  106. #define EXT_SENS_DATA_10 0x53
  107. #define EXT_SENS_DATA_11 0x54
  108. #define EXT_SENS_DATA_12 0x55
  109. #define EXT_SENS_DATA_13 0x56
  110. #define EXT_SENS_DATA_14 0x57
  111. #define EXT_SENS_DATA_15 0x58
  112. #define EXT_SENS_DATA_16 0x59
  113. #define EXT_SENS_DATA_17 0x5A
  114. #define EXT_SENS_DATA_18 0x5B
  115. #define EXT_SENS_DATA_19 0x5C
  116. #define EXT_SENS_DATA_20 0x5D
  117. #define EXT_SENS_DATA_21 0x5E
  118. #define EXT_SENS_DATA_22 0x5F
  119. #define EXT_SENS_DATA_23 0x60
  120. #define MOT_DETECT_STATUS 0x61
  121. #define I2C_SLV0_DO 0x63
  122. #define I2C_SLV1_DO 0x64
  123. #define I2C_SLV2_DO 0x65
  124. #define I2C_SLV3_DO 0x66
  125. #define I2C_MST_DELAY_CTRL 0x67
  126. #define SIGNAL_PATH_RESET 0x68
  127. #define MOT_DETECT_CTRL 0x69
  128. #define USER_CTRL 0x6A // Bit 7 enable DMP, bit 3 reset DMP
  129. #define PWR_MGMT_1 0x6B // Device defaults to the SLEEP mode
  130. #define PWR_MGMT_2 0x6C
  131. #define DMP_BANK 0x6D // Activates a specific bank in the DMP
  132. #define DMP_RW_PNT 0x6E // Set read/write pointer to a specific start address in specified DMP bank
  133. #define DMP_REG 0x6F // Register in DMP from which to read or to which to write
  134. #define DMP_REG_1 0x70
  135. #define DMP_REG_2 0x71
  136. #define FIFO_COUNTH 0x72
  137. #define FIFO_COUNTL 0x73
  138. #define FIFO_R_W 0x74
  139. #define WHO_AM_I_MPU9250 0x75 // Should return 0x71
  140. #define XA_OFFSET_H 0x77
  141. #define XA_OFFSET_L 0x78
  142. #define YA_OFFSET_H 0x7A
  143. #define YA_OFFSET_L 0x7B
  144. #define ZA_OFFSET_H 0x7D
  145. #define ZA_OFFSET_L 0x7E

  146. // Using the MSENSR-9250 breakout board, ADO is set to 0
  147. // Seven-bit device address is 110100 for ADO = 0 and 110101 for ADO = 1
  148. //#define ADO 0
  149. #if ADO
  150. #define MPU9250_ADDRESS 0x69 // Device address when ADO = 1
  151. #else
  152. #define MPU9250_ADDRESS 0x68 // Device address when ADO = 0
  153. #define AK8963_ADDRESS 0x0C // Address of magnetometer
  154. #endif

  155. // Set initial input parameters
  156. enum Ascale {
  157.   AFS_2G = 0,
  158.   AFS_4G,
  159.   AFS_8G,
  160.   AFS_16G
  161. };

  162. enum Gscale {
  163.   GFS_250DPS = 0,
  164.   GFS_500DPS,
  165.   GFS_1000DPS,
  166.   GFS_2000DPS
  167. };

  168. enum Mscale {
  169.   MFS_14BITS = 0, // 0.6 mG per LSB
  170.   MFS_16BITS // 0.15 mG per LSB
  171. };

  172. // Specify sensor full scale
  173. uint8_t Gscale = GFS_250DPS;
  174. uint8_t Ascale = AFS_2G;
  175. uint8_t Mscale = MFS_16BITS; // Choose either 14-bit or 16-bit magnetometer resolution
  176. uint8_t Mmode = 0x02; // 2 for 8 Hz, 6 for 100 Hz continuous magnetometer data read
  177. float aRes, gRes, mRes; // scale resolutions per LSB for the sensors

  178. //// Pin definitions
  179. //int intPin = 12; // These can be changed, 2 and 3 are the Arduinos ext int pins
  180. //int adoPin = 8;
  181. //int LEDPin = 13;

  182. int16_t accelCount[3]; // Stores the 16-bit signed accelerometer sensor output
  183. int16_t gyroCount[3]; // Stores the 16-bit signed gyro sensor output
  184. int16_t magCount[3]; // Stores the 16-bit signed magnetometer sensor output
  185. float magCalibration[3] = {0, 0, 0}, magbias[3] = {0, 0, 0}; // Factory mag calibration and mag bias
  186. float gyroBias[3] = {0, 0, 0}, accelBias[3] = {0, 0, 0}; // Bias corrections for gyro and accelerometer
  187. int16_t tempCount; // temperature raw count output
  188. float temperature; // Stores the real internal chip temperature in degrees Celsius
  189. float SelfTest[6]; // holds results of gyro and accelerometer self test

  190. // global constants for 9 DoF fusion and AHRS (Attitude and Heading Reference System)
  191. float GyroMeasError = PI * (40.0f / 180.0f); // gyroscope measurement error in rads/s (start at 40 deg/s)
  192. float GyroMeasDrift = PI * (0.0f / 180.0f); // gyroscope measurement drift in rad/s/s (start at 0.0 deg/s/s)

  193. // There is a tradeoff in the beta parameter between accuracy and response speed.
  194. // In the original Madgwick study, beta of 0.041 (corresponding to GyroMeasError of 2.7 degrees/s) was found to give optimal accuracy.
  195. // However, with this value, the LSM9SD0 response time is about 10 seconds to a stable initial quaternion.
  196. // Subsequent changes also require a longish lag time to a stable output, not fast enough for a quadcopter or robot
  197. // By increasing beta (GyroMeasError) by about a factor of fifteen, the response time constant is reduced to ~2 sec
  198. // I haven't noticed any reduction in solution accuracy. This is essentially the I coefficient in a PID control sense;
  199. // the bigger the feedback coefficient, the faster the solution converges, usually at the expense of accuracy.
  200. // In any case, this is the free parameter in the Madgwick filtering and fusion scheme.
  201. float beta = sqrt(3.0f / 4.0f) * GyroMeasError; // compute beta
  202. 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
  203. #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
  204. #define Ki 0.0f

  205. uint32_t delt_t = 0; // used to control display output rate
  206. uint32_t count = 0, sumCount = 0; // used to control display output rate
  207. //float pitch, yaw, roll;
  208. float deltat = 0.0f, sum = 0.0f; // integration interval for both filter schemes
  209. uint32_t lastUpdate = 0, firstUpdate = 0; // used to calculate integration interval
  210. uint32_t Now = 0; // used to calculate integration interval

  211. float ax, ay, az, gx, gy, gz, mx, my, mz; // variables to hold latest sensor data values
  212. float q[4] = {1.0f, 0.0f, 0.0f, 0.0f}; // vector to hold quaternion
  213. float eInt[3] = {0.0f, 0.0f, 0.0f}; // vector to hold integral error for Mahony method


  214. void setup()
  215. {
  216.   // Setup for Master mode, pins 18/19, external pullups, 400kHz
  217.   Wire1.begin(I2C_MASTER, 0x68, I2C_PINS_22_23, I2C_PULLUP_EXT, I2C_RATE_100);
  218.   Serial.begin(115200);

  219.   // Read the WHO_AM_I register, this is a good test of communication
  220.   byte c = readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250); // Read WHO_AM_I register for MPU-9250
  221.   //Serial.print("MPU9250 "); Serial.print("I AM "); Serial.print(c, HEX); Serial.print(" I should be "); Serial.println(0x71, HEX);
  222.   delay(5000);

  223.   if (c == 0x71) // WHO_AM_I should always be 0x68
  224.   {
  225.     Serial.println("C:Begin"); //Signal calibrating sensors

  226.     MPU9250SelfTest(SelfTest); // Start by performing self test and reporting values
  227.     delay(5000);

  228.     calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers
  229.     delay(1000);

  230.     initMPU9250(); // Initialize device for active mode read of acclerometer, gyroscope, and temperature

  231.     delay(1000);

  232.     // Get magnetometer calibration from AK8963 ROM
  233.     initAK8963(magCalibration); // Initialize device for active mode read of magnetometer
  234.     
  235.     Serial.println("C:End"); //Signals done with calibration
  236.     
  237.   }
  238.   else
  239.   {
  240.     Serial.print("E:");
  241.     Serial.print("Could not connect to MPU9250: 0x");
  242.     Serial.println(c, HEX);
  243.     while (1) ; // Loop forever if communication doesn't happen
  244.   }
  245. }

  246. void loop()
  247. {
  248.   // If intPin goes high, all data registers have new data
  249.   if (readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) { // On interrupt, check if data ready interrupt
  250.     readAccelData(accelCount); // Read the x/y/z adc values
  251.     getAres();

  252.     // Now we'll calculate the accleration value into actual g's
  253.     ax = (float)accelCount[0] * aRes; // - accelBias[0]; // get actual g value, this depends on scale being set
  254.     ay = (float)accelCount[1] * aRes; // - accelBias[1];
  255.     az = (float)accelCount[2] * aRes; // - accelBias[2];

  256.     readGyroData(gyroCount); // Read the x/y/z adc values
  257.     getGres();

  258.     // Calculate the gyro value into actual degrees per second
  259.     gx = (float)gyroCount[0] * gRes; // get actual gyro value, this depends on scale being set
  260.     gy = (float)gyroCount[1] * gRes;
  261.     gz = (float)gyroCount[2] * gRes;

  262.     readMagData(magCount); // Read the x/y/z adc values
  263.     getMres();
  264.     magbias[0] = +470.; // User environmental x-axis correction in milliGauss, should be automatically calculated
  265.     magbias[1] = +120.; // User environmental x-axis correction in milliGauss
  266.     magbias[2] = +125.; // User environmental x-axis correction in milliGauss

  267.     // Calculate the magnetometer values in milliGauss
  268.     // Include factory calibration per data sheet and user environmental corrections
  269.     mx = (float)magCount[0] * mRes * magCalibration[0] - magbias[0]; // get actual magnetometer value, this depends on scale being set
  270.     my = (float)magCount[1] * mRes * magCalibration[1] - magbias[1];
  271.     mz = (float)magCount[2] * mRes * magCalibration[2] - magbias[2];
  272.   }

  273.   Now = micros();
  274.   deltat = ((Now - lastUpdate) / 1000000.0f); // set integration time by time elapsed since last filter update
  275.   lastUpdate = Now;

  276.   sum += deltat; // sum for averaging filter update rate
  277.   sumCount++;

  278.   // Sensors x (y)-axis of the accelerometer is aligned with the y (x)-axis of the magnetometer;
  279.   // the magnetometer z-axis (+ down) is opposite to z-axis (+ up) of accelerometer and
  280.   // We have to make some allowance for this orientationmismatch in feeding the output to the quaternion filter.
  281.   
  282.   MadgwickQuaternionUpdate(ax, ay, az, gx * PI / 180.0f, gy * PI / 180.0f, gz * PI / 180.0f, my, mx, mz);

  283.       Serial.print("Q:");
  284.       Serial.print(q[0], 5); //Print qw
  285.       Serial.print(",");
  286.       Serial.print(q[1], 5); //Print qx
  287.       Serial.print(",");
  288.       Serial.print(q[2], 5); //Print qy
  289.       Serial.print(",");
  290.       Serial.println(q[3], 5); //Print qz
  291. }



  292. //===================================================================================================================
  293. //====== Set of useful function to access acceleration. gyroscope, magnetometer, and temperature data
  294. //===================================================================================================================

  295. void getMres() {
  296.   switch (Mscale)
  297.   {
  298.     // Possible magnetometer scales (and their register bit settings) are:
  299.     // 14 bit resolution (0) and 16 bit resolution (1)
  300.     case MFS_14BITS:
  301.       mRes = 10.*4912. / 8190.; // Proper scale to return milliGauss
  302.       break;
  303.     case MFS_16BITS:
  304.       mRes = 10.*4912. / 32760.0; // Proper scale to return milliGauss
  305.       break;
  306.   }
  307. }

  308. void getGres() {
  309.   switch (Gscale)
  310.   {
  311.     // Possible gyro scales (and their register bit settings) are:
  312.     // 250 DPS (00), 500 DPS (01), 1000 DPS (10), and 2000 DPS (11).
  313.     // Here's a bit of an algorith to calculate DPS/(ADC tick) based on that 2-bit value:
  314.     case GFS_250DPS:
  315.       gRes = 250.0 / 32768.0;
  316.       break;
  317.     case GFS_500DPS:
  318.       gRes = 500.0 / 32768.0;
  319.       break;
  320.     case GFS_1000DPS:
  321.       gRes = 1000.0 / 32768.0;
  322.       break;
  323.     case GFS_2000DPS:
  324.       gRes = 2000.0 / 32768.0;
  325.       break;
  326.   }
  327. }

  328. void getAres() {
  329.   switch (Ascale)
  330.   {
  331.     // Possible accelerometer scales (and their register bit settings) are:
  332.     // 2 Gs (00), 4 Gs (01), 8 Gs (10), and 16 Gs (11).
  333.     // Here's a bit of an algorith to calculate DPS/(ADC tick) based on that 2-bit value:
  334.     case AFS_2G:
  335.       aRes = 2.0 / 32768.0;
  336.       break;
  337.     case AFS_4G:
  338.       aRes = 4.0 / 32768.0;
  339.       break;
  340.     case AFS_8G:
  341.       aRes = 8.0 / 32768.0;
  342.       break;
  343.     case AFS_16G:
  344.       aRes = 16.0 / 32768.0;
  345.       break;
  346.   }
  347. }


  348. void readAccelData(int16_t * destination)
  349. {
  350.   uint8_t rawData[6]; // x/y/z accel register data stored here
  351.   readBytes(MPU9250_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]); // Read the six raw data registers into data array
  352.   destination[0] = ((int16_t)rawData[0] << 8) | rawData[1] ; // Turn the MSB and LSB into a signed 16-bit value
  353.   destination[1] = ((int16_t)rawData[2] << 8) | rawData[3] ;
  354.   destination[2] = ((int16_t)rawData[4] << 8) | rawData[5] ;
  355. }


  356. void readGyroData(int16_t * destination)
  357. {
  358.   uint8_t rawData[6]; // x/y/z gyro register data stored here
  359.   readBytes(MPU9250_ADDRESS, GYRO_XOUT_H, 6, &rawData[0]); // Read the six raw data registers sequentially into data array
  360.   destination[0] = ((int16_t)rawData[0] << 8) | rawData[1] ; // Turn the MSB and LSB into a signed 16-bit value
  361.   destination[1] = ((int16_t)rawData[2] << 8) | rawData[3] ;
  362.   destination[2] = ((int16_t)rawData[4] << 8) | rawData[5] ;
  363. }

  364. void readMagData(int16_t * destination)
  365. {
  366.   uint8_t rawData[7]; // x/y/z gyro register data, ST2 register stored here, must read ST2 at end of data acquisition
  367.   if (readByte(AK8963_ADDRESS, AK8963_ST1) & 0x01) { // wait for magnetometer data ready bit to be set
  368.     readBytes(AK8963_ADDRESS, AK8963_XOUT_L, 7, &rawData[0]); // Read the six raw data and ST2 registers sequentially into data array
  369.     uint8_t c = rawData[6]; // End data read by reading ST2 register
  370.     if (!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data
  371.       destination[0] = ((int16_t)rawData[1] << 8) | rawData[0] ; // Turn the MSB and LSB into a signed 16-bit value
  372.       destination[1] = ((int16_t)rawData[3] << 8) | rawData[2] ; // Data stored as little Endian
  373.       destination[2] = ((int16_t)rawData[5] << 8) | rawData[4] ;
  374.     }
  375.   }
  376. }

  377. void initAK8963(float * destination)
  378. {
  379.   // First extract the factory calibration for each magnetometer axis
  380.   uint8_t rawData[3]; // x/y/z gyro calibration data stored here
  381.   writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer
  382.   delay(10);
  383.   writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x0F); // Enter Fuse ROM access mode
  384.   delay(10);
  385.   readBytes(AK8963_ADDRESS, AK8963_ASAX, 3, &rawData[0]); // Read the x-, y-, and z-axis calibration values
  386.   destination[0] = (float)(rawData[0] - 128) / 256. + 1.; // Return x-axis sensitivity adjustment values, etc.
  387.   destination[1] = (float)(rawData[1] - 128) / 256. + 1.;
  388.   destination[2] = (float)(rawData[2] - 128) / 256. + 1.;
  389.   writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer
  390.   delay(10);
  391.   // Configure the magnetometer for continuous read and highest resolution
  392.   // set Mscale bit 4 to 1 (0) to enable 16 (14) bit resolution in CNTL register,
  393.   // and enable continuous mode data acquisition Mmode (bits [3:0]), 0010 for 8 Hz and 0110 for 100 Hz sample rates
  394.   writeByte(AK8963_ADDRESS, AK8963_CNTL, Mscale << 4 | Mmode); // Set magnetometer data resolution and sample ODR
  395.   delay(10);
  396. }


  397. void initMPU9250()
  398. {
  399.   // wake up device
  400.   writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x00); // Clear sleep mode bit (6), enable all sensors
  401.   delay(100); // Wait for all registers to reset

  402.   // get stable time source
  403.   writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x01); // Auto select clock source to be PLL gyroscope reference if ready else
  404.   delay(200);

  405.   // Configure Gyro and Thermometer
  406.   // Disable FSYNC and set thermometer and gyro bandwidth to 41 and 42 Hz, respectively;
  407.   // minimum delay time for this setting is 5.9 ms, which means sensor fusion update rates cannot
  408.   // be higher than 1 / 0.0059 = 170 Hz
  409.   // DLPF_CFG = bits 2:0 = 011; this limits the sample rate to 1000 Hz for both
  410.   // With the MPU9250, it is possible to get gyro sample rates of 32 kHz (!), 8 kHz, or 1 kHz
  411.   writeByte(MPU9250_ADDRESS, CONFIG, 0x03);

  412.   // Set sample rate = gyroscope output rate/(1 + SMPLRT_DIV)
  413.   writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x04); // Use a 200 Hz rate; a rate consistent with the filter update rate
  414.   // determined inset in CONFIG above

  415.   // Set gyroscope full scale range
  416.   // Range selects FS_SEL and GFS_SEL are 0 - 3, so 2-bit values are left-shifted into positions 4:3
  417.   uint8_t c = readByte(MPU9250_ADDRESS, GYRO_CONFIG); // get current GYRO_CONFIG register value
  418.   // c = c & ~0xE0; // Clear self-test bits [7:5]
  419.   c = c & ~0x03; // Clear Fchoice bits [1:0]
  420.   c = c & ~0x18; // Clear GFS bits [4:3]
  421.   c = c | Gscale << 3; // Set full scale range for the gyro
  422.   // c =| 0x00; // Set Fchoice for the gyro to 11 by writing its inverse to bits 1:0 of GYRO_CONFIG
  423.   writeByte(MPU9250_ADDRESS, GYRO_CONFIG, c ); // Write new GYRO_CONFIG value to register

  424.   // Set accelerometer full-scale range configuration
  425.   c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG); // get current ACCEL_CONFIG register value
  426.   // c = c & ~0xE0; // Clear self-test bits [7:5]
  427.   c = c & ~0x18; // Clear AFS bits [4:3]
  428.   c = c | Ascale << 3; // Set full scale range for the accelerometer
  429.   writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, c); // Write new ACCEL_CONFIG register value

  430.   // Set accelerometer sample rate configuration
  431.   // It is possible to get a 4 kHz sample rate from the accelerometer by choosing 1 for
  432.   // accel_fchoice_b bit [3]; in this case the bandwidth is 1.13 kHz
  433.   c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG2); // get current ACCEL_CONFIG2 register value
  434.   c = c & ~0x0F; // Clear accel_fchoice_b (bit 3) and A_DLPFG (bits [2:0])
  435.   c = c | 0x03; // Set accelerometer rate to 1 kHz and bandwidth to 41 Hz
  436.   writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c); // Write new ACCEL_CONFIG2 register value

  437.   // The accelerometer, gyro, and thermometer are set to 1 kHz sample rates,
  438.   // but all these rates are further reduced by a factor of 5 to 200 Hz because of the SMPLRT_DIV setting

  439.   // Configure Interrupts and Bypass Enable
  440.   // Set interrupt pin active high, push-pull, hold interrupt pin level HIGH until interrupt cleared,
  441.   // clear on read of INT_STATUS, and enable I2C_BYPASS_EN so additional chips
  442.   // can join the I2C bus and all can be controlled by the Arduino as master
  443.   writeByte(MPU9250_ADDRESS, INT_PIN_CFG, 0x22);
  444.   writeByte(MPU9250_ADDRESS, INT_ENABLE, 0x01); // Enable data ready (bit 0) interrupt
  445.   delay(100);
  446. }


  447. // Function which accumulates gyro and accelerometer data after device initialization. It calculates the average
  448. // of the at-rest readings and then loads the resulting offsets into accelerometer and gyro bias registers.
  449. void calibrateMPU9250(float * dest1, float * dest2)
  450. {
  451.   uint8_t data[12]; // data array to hold accelerometer and gyro x, y, z, data
  452.   uint16_t ii, packet_count, fifo_count;
  453.   int32_t gyro_bias[3] = {0, 0, 0}, accel_bias[3] = {0, 0, 0};

  454.   // reset device
  455.   writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x80); // Write a one to bit 7 reset bit; toggle reset device
  456.   delay(100);

  457.   // get stable time source; Auto select clock source to be PLL gyroscope reference if ready
  458.   // else use the internal oscillator, bits 2:0 = 001
  459.   writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x01);
  460.   writeByte(MPU9250_ADDRESS, PWR_MGMT_2, 0x00);
  461.   delay(200);

  462.   // Configure device for bias calculation
  463.   writeByte(MPU9250_ADDRESS, INT_ENABLE, 0x00); // Disable all interrupts
  464.   writeByte(MPU9250_ADDRESS, FIFO_EN, 0x00); // Disable FIFO
  465.   writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x00); // Turn on internal clock source
  466.   writeByte(MPU9250_ADDRESS, I2C_MST_CTRL, 0x00); // Disable I2C master
  467.   writeByte(MPU9250_ADDRESS, USER_CTRL, 0x00); // Disable FIFO and I2C master modes
  468.   writeByte(MPU9250_ADDRESS, USER_CTRL, 0x0C); // Reset FIFO and DMP
  469.   delay(15);

  470.   // Configure MPU6050 gyro and accelerometer for bias calculation
  471.   writeByte(MPU9250_ADDRESS, CONFIG, 0x01); // Set low-pass filter to 188 Hz
  472.   writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x00); // Set sample rate to 1 kHz
  473.   writeByte(MPU9250_ADDRESS, GYRO_CONFIG, 0x00); // Set gyro full-scale to 250 degrees per second, maximum sensitivity
  474.   writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, 0x00); // Set accelerometer full-scale to 2 g, maximum sensitivity

  475.   uint16_t gyrosensitivity = 131; // = 131 LSB/degrees/sec
  476.   uint16_t accelsensitivity = 16384; // = 16384 LSB/g

  477.   // Configure FIFO to capture accelerometer and gyro data for bias calculation
  478.   writeByte(MPU9250_ADDRESS, USER_CTRL, 0x40); // Enable FIFO
  479.   writeByte(MPU9250_ADDRESS, FIFO_EN, 0x78); // Enable gyro and accelerometer sensors for FIFO (max size 512 bytes in MPU-9150)
  480.   delay(40); // accumulate 40 samples in 40 milliseconds = 480 bytes

  481.   // At end of sample accumulation, turn off FIFO sensor read
  482.   writeByte(MPU9250_ADDRESS, FIFO_EN, 0x00); // Disable gyro and accelerometer sensors for FIFO
  483.   readBytes(MPU9250_ADDRESS, FIFO_COUNTH, 2, &data[0]); // read FIFO sample count
  484.   fifo_count = ((uint16_t)data[0] << 8) | data[1];
  485.   packet_count = fifo_count / 12; // How many sets of full gyro and accelerometer data for averaging

  486.   for (ii = 0; ii < packet_count; ii++) {
  487.     int16_t accel_temp[3] = {0, 0, 0}, gyro_temp[3] = {0, 0, 0};
  488.     readBytes(MPU9250_ADDRESS, FIFO_R_W, 12, &data[0]); // read data for averaging
  489.     accel_temp[0] = (int16_t) (((int16_t)data[0] << 8) | data[1] ) ; // Form signed 16-bit integer for each sample in FIFO
  490.     accel_temp[1] = (int16_t) (((int16_t)data[2] << 8) | data[3] ) ;
  491.     accel_temp[2] = (int16_t) (((int16_t)data[4] << 8) | data[5] ) ;
  492.     gyro_temp[0] = (int16_t) (((int16_t)data[6] << 8) | data[7] ) ;
  493.     gyro_temp[1] = (int16_t) (((int16_t)data[8] << 8) | data[9] ) ;
  494.     gyro_temp[2] = (int16_t) (((int16_t)data[10] << 8) | data[11]) ;

  495.     accel_bias[0] += (int32_t) accel_temp[0]; // Sum individual signed 16-bit biases to get accumulated signed 32-bit biases
  496.     accel_bias[1] += (int32_t) accel_temp[1];
  497.     accel_bias[2] += (int32_t) accel_temp[2];
  498.     gyro_bias[0] += (int32_t) gyro_temp[0];
  499.     gyro_bias[1] += (int32_t) gyro_temp[1];
  500.     gyro_bias[2] += (int32_t) gyro_temp[2];

  501.   }
  502.   accel_bias[0] /= (int32_t) packet_count; // Normalize sums to get average count biases
  503.   accel_bias[1] /= (int32_t) packet_count;
  504.   accel_bias[2] /= (int32_t) packet_count;
  505.   gyro_bias[0] /= (int32_t) packet_count;
  506.   gyro_bias[1] /= (int32_t) packet_count;
  507.   gyro_bias[2] /= (int32_t) packet_count;

  508.   if (accel_bias[2] > 0L) {
  509.     accel_bias[2] -= (int32_t) accelsensitivity; // Remove gravity from the z-axis accelerometer bias calculation
  510.   }
  511.   else {
  512.     accel_bias[2] += (int32_t) accelsensitivity;
  513.   }

  514.   // Construct the gyro biases for push to the hardware gyro bias registers, which are reset to zero upon device startup
  515.   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
  516.   data[1] = (-gyro_bias[0] / 4) & 0xFF; // Biases are additive, so change sign on calculated average gyro biases
  517.   data[2] = (-gyro_bias[1] / 4 >> 8) & 0xFF;
  518.   data[3] = (-gyro_bias[1] / 4) & 0xFF;
  519.   data[4] = (-gyro_bias[2] / 4 >> 8) & 0xFF;
  520.   data[5] = (-gyro_bias[2] / 4) & 0xFF;

  521.   // Push gyro biases to hardware registers
  522.   writeByte(MPU9250_ADDRESS, XG_OFFSET_H, data[0]);
  523.   writeByte(MPU9250_ADDRESS, XG_OFFSET_L, data[1]);
  524.   writeByte(MPU9250_ADDRESS, YG_OFFSET_H, data[2]);
  525.   writeByte(MPU9250_ADDRESS, YG_OFFSET_L, data[3]);
  526.   writeByte(MPU9250_ADDRESS, ZG_OFFSET_H, data[4]);
  527.   writeByte(MPU9250_ADDRESS, ZG_OFFSET_L, data[5]);

  528.   // Output scaled gyro biases for display in the main program
  529.   dest1[0] = (float) gyro_bias[0] / (float) gyrosensitivity;
  530.   dest1[1] = (float) gyro_bias[1] / (float) gyrosensitivity;
  531.   dest1[2] = (float) gyro_bias[2] / (float) gyrosensitivity;

  532.   // Construct the accelerometer biases for push to the hardware accelerometer bias registers. These registers contain
  533.   // factory trim values which must be added to the calculated accelerometer biases; on boot up these registers will hold
  534.   // non-zero values. In addition, bit 0 of the lower byte must be preserved since it is used for temperature
  535.   // compensation calculations. Accelerometer bias registers expect bias input as 2048 LSB per g, so that
  536.   // the accelerometer biases calculated above must be divided by 8.

  537.   int32_t accel_bias_reg[3] = {0, 0, 0}; // A place to hold the factory accelerometer trim biases
  538.   readBytes(MPU9250_ADDRESS, XA_OFFSET_H, 2, &data[0]); // Read factory accelerometer trim values
  539.   accel_bias_reg[0] = (int32_t) (((int16_t)data[0] << 8) | data[1]);
  540.   readBytes(MPU9250_ADDRESS, YA_OFFSET_H, 2, &data[0]);
  541.   accel_bias_reg[1] = (int32_t) (((int16_t)data[0] << 8) | data[1]);
  542.   readBytes(MPU9250_ADDRESS, ZA_OFFSET_H, 2, &data[0]);
  543.   accel_bias_reg[2] = (int32_t) (((int16_t)data[0] << 8) | data[1]);

  544.   uint32_t mask = 1uL; // Define mask for temperature compensation bit 0 of lower byte of accelerometer bias registers
  545.   uint8_t mask_bit[3] = {0, 0, 0}; // Define array to hold mask bit for each accelerometer bias axis

  546.   for (ii = 0; ii < 3; ii++) {
  547.     if ((accel_bias_reg[ii] & mask)) mask_bit[ii] = 0x01; // If temperature compensation bit is set, record that fact in mask_bit
  548.   }

  549.   // Construct total accelerometer bias, including calculated average accelerometer bias from above
  550.   accel_bias_reg[0] -= (accel_bias[0] / 8); // Subtract calculated averaged accelerometer bias scaled to 2048 LSB/g (16 g full scale)
  551.   accel_bias_reg[1] -= (accel_bias[1] / 8);
  552.   accel_bias_reg[2] -= (accel_bias[2] / 8);

  553.   data[0] = (accel_bias_reg[0] >> 8) & 0xFF;
  554.   data[1] = (accel_bias_reg[0]) & 0xFF;
  555.   data[1] = data[1] | mask_bit[0]; // preserve temperature compensation bit when writing back to accelerometer bias registers
  556.   data[2] = (accel_bias_reg[1] >> 8) & 0xFF;
  557.   data[3] = (accel_bias_reg[1]) & 0xFF;
  558.   data[3] = data[3] | mask_bit[1]; // preserve temperature compensation bit when writing back to accelerometer bias registers
  559.   data[4] = (accel_bias_reg[2] >> 8) & 0xFF;
  560.   data[5] = (accel_bias_reg[2]) & 0xFF;
  561.   data[5] = data[5] | mask_bit[2]; // preserve temperature compensation bit when writing back to accelerometer bias registers

  562.   // Apparently this is not working for the acceleration biases in the MPU-9250
  563.   // Are we handling the temperature correction bit properly?
  564.   // Push accelerometer biases to hardware registers
  565.   writeByte(MPU9250_ADDRESS, XA_OFFSET_H, data[0]);
  566.   writeByte(MPU9250_ADDRESS, XA_OFFSET_L, data[1]);
  567.   writeByte(MPU9250_ADDRESS, YA_OFFSET_H, data[2]);
  568.   writeByte(MPU9250_ADDRESS, YA_OFFSET_L, data[3]);
  569.   writeByte(MPU9250_ADDRESS, ZA_OFFSET_H, data[4]);
  570.   writeByte(MPU9250_ADDRESS, ZA_OFFSET_L, data[5]);

  571.   // Output scaled accelerometer biases for display in the main program
  572.   dest2[0] = (float)accel_bias[0] / (float)accelsensitivity;
  573.   dest2[1] = (float)accel_bias[1] / (float)accelsensitivity;
  574.   dest2[2] = (float)accel_bias[2] / (float)accelsensitivity;
  575. }

  576. // Accelerometer and gyroscope self test; check calibration wrt factory settings
  577. void MPU9250SelfTest(float * destination) // Should return percent deviation from factory trim values, +/- 14 or less deviation is a pass
  578. {
  579.   uint8_t rawData[6] = {0, 0, 0, 0, 0, 0};
  580.   uint8_t selfTest[6];
  581.   int32_t gAvg[3] = {0}, aAvg[3] = {0}, aSTAvg[3] = {0}, gSTAvg[3] = {0};
  582.   float factoryTrim[6];
  583.   uint8_t FS = 0;

  584.   writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x00); // Set gyro sample rate to 1 kHz
  585.   writeByte(MPU9250_ADDRESS, CONFIG, 0x02); // Set gyro sample rate to 1 kHz and DLPF to 92 Hz
  586.   writeByte(MPU9250_ADDRESS, GYRO_CONFIG, FS << 3); // Set full scale range for the gyro to 250 dps
  587.   writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, 0x02); // Set accelerometer rate to 1 kHz and bandwidth to 92 Hz
  588.   writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, FS << 3); // Set full scale range for the accelerometer to 2 g

  589.   for ( int ii = 0; ii < 200; ii++) { // get average current values of gyro and acclerometer

  590.     readBytes(MPU9250_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]); // Read the six raw data registers into data array
  591.     aAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value
  592.     aAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ;
  593.     aAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ;

  594.     readBytes(MPU9250_ADDRESS, GYRO_XOUT_H, 6, &rawData[0]); // Read the six raw data registers sequentially into data array
  595.     gAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value
  596.     gAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ;
  597.     gAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ;
  598.   }

  599.   for (int ii = 0; ii < 3; ii++) { // Get average of 200 values and store as average current readings
  600.     aAvg[ii] /= 200;
  601.     gAvg[ii] /= 200;
  602.   }

  603.   // Configure the accelerometer for self-test
  604.   writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, 0xE0); // Enable self test on all three axes and set accelerometer range to +/- 2 g
  605.   writeByte(MPU9250_ADDRESS, GYRO_CONFIG, 0xE0); // Enable self test on all three axes and set gyro range to +/- 250 degrees/s
  606.   delay(25); // Delay a while to let the device stabilize

  607.   for ( int ii = 0; ii < 200; ii++) { // get average self-test values of gyro and acclerometer

  608.     readBytes(MPU9250_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]); // Read the six raw data registers into data array
  609.     aSTAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value
  610.     aSTAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ;
  611.     aSTAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ;

  612.     readBytes(MPU9250_ADDRESS, GYRO_XOUT_H, 6, &rawData[0]); // Read the six raw data registers sequentially into data array
  613.     gSTAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value
  614.     gSTAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ;
  615.     gSTAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ;
  616.   }

  617.   for (int ii = 0; ii < 3; ii++) { // Get average of 200 values and store as average self-test readings
  618.     aSTAvg[ii] /= 200;
  619.     gSTAvg[ii] /= 200;
  620.   }

  621.   // Configure the gyro and accelerometer for normal operation
  622.   writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, 0x00);
  623.   writeByte(MPU9250_ADDRESS, GYRO_CONFIG, 0x00);
  624.   delay(25); // Delay a while to let the device stabilize

  625.   // Retrieve accelerometer and gyro factory Self-Test Code from USR_Reg
  626.   selfTest[0] = readByte(MPU9250_ADDRESS, SELF_TEST_X_ACCEL); // X-axis accel self-test results
  627.   selfTest[1] = readByte(MPU9250_ADDRESS, SELF_TEST_Y_ACCEL); // Y-axis accel self-test results
  628.   selfTest[2] = readByte(MPU9250_ADDRESS, SELF_TEST_Z_ACCEL); // Z-axis accel self-test results
  629.   selfTest[3] = readByte(MPU9250_ADDRESS, SELF_TEST_X_GYRO); // X-axis gyro self-test results
  630.   selfTest[4] = readByte(MPU9250_ADDRESS, SELF_TEST_Y_GYRO); // Y-axis gyro self-test results
  631.   selfTest[5] = readByte(MPU9250_ADDRESS, SELF_TEST_Z_GYRO); // Z-axis gyro self-test results

  632.   // Retrieve factory self-test value from self-test code reads
  633.   factoryTrim[0] = (float)(2620 / 1 << FS) * (pow( 1.01 , ((float)selfTest[0] - 1.0) )); // FT[Xa] factory trim calculation
  634.   factoryTrim[1] = (float)(2620 / 1 << FS) * (pow( 1.01 , ((float)selfTest[1] - 1.0) )); // FT[Ya] factory trim calculation
  635.   factoryTrim[2] = (float)(2620 / 1 << FS) * (pow( 1.01 , ((float)selfTest[2] - 1.0) )); // FT[Za] factory trim calculation
  636.   factoryTrim[3] = (float)(2620 / 1 << FS) * (pow( 1.01 , ((float)selfTest[3] - 1.0) )); // FT[Xg] factory trim calculation
  637.   factoryTrim[4] = (float)(2620 / 1 << FS) * (pow( 1.01 , ((float)selfTest[4] - 1.0) )); // FT[Yg] factory trim calculation
  638.   factoryTrim[5] = (float)(2620 / 1 << FS) * (pow( 1.01 , ((float)selfTest[5] - 1.0) )); // FT[Zg] factory trim calculation

  639.   // Report results as a ratio of (STR - FT)/FT; the change from Factory Trim of the Self-Test Response
  640.   // To get percent, must multiply by 100
  641.   for (int i = 0; i < 3; i++) {
  642.     destination[i] = 100.0 * ((float)(aSTAvg[i] - aAvg[i])) / factoryTrim[i] - 100.; // Report percent differences
  643.     destination[i + 3] = 100.0 * ((float)(gSTAvg[i] - gAvg[i])) / factoryTrim[i + 3] - 100.; // Report percent differences
  644.   }

  645. }



  646. void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
  647. {
  648.   Wire1.beginTransmission(address); // Initialize the Tx buffer
  649.   Wire1.write(subAddress); // Put slave register address in Tx buffer
  650.   Wire1.write(data); // Put data in Tx buffer
  651.   Wire1.endTransmission(); // Send the Tx buffer
  652. }

  653. uint8_t readByte(uint8_t address, uint8_t subAddress)
  654. {
  655.   uint8_t data; // `data` will store the register data
  656.   Wire1.beginTransmission(address); // Initialize the Tx buffer
  657.   Wire1.write(subAddress);     // Put slave register address in Tx buffer
  658.   Wire1.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive
  659.   //    Wire1.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
  660.   //    Wire1.requestFrom(address, 1); // Read one byte from slave register address
  661.   Wire1.requestFrom(address, (size_t) 1); // Read one byte from slave register address
  662.   data = Wire1.read(); // Fill Rx buffer with result
  663.   return data; // Return data read from slave register
  664. }

  665. void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
  666. {
  667.   Wire1.beginTransmission(address); // Initialize the Tx buffer
  668.   Wire1.write(subAddress); // Put slave register address in Tx buffer
  669.   Wire1.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive
  670.   //    Wire1.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
  671.   uint8_t i = 0;
  672.   // Wire1.requestFrom(address, count); // Read bytes from slave register address
  673.   Wire1.requestFrom(address, (size_t) count); // Read bytes from slave register address
  674.   while (Wire1.available()) {
  675.     dest[i++] = Wire1.read();
  676.   } // Put read results in the Rx buffer
  677. }


点击(此处)折叠或打开

  1. // Implementation of Sebastian Madgwick's "...efficient orientation filter for... inertial/magnetic sensor arrays"
  2. // (see http://www.x-io.co.uk/category/open-source/ for examples and more details)
  3. // which fuses acceleration, rotation rate, and magnetic moments to produce a quaternion-based estimate of absolute
  4. // device orientation -- which can be converted to yaw, pitch, and roll. Useful for stabilizing quadcopters, etc.
  5. // The performance of the orientation filter is at least as good as conventional Kalman-based filtering algorithms
  6. // but is much less computationally intensive---it can be performed on a 3.3 V Pro Mini operating at 8 MHz!
  7.         void MadgwickQuaternionUpdate(float ax, float ay, float az, float gx, float gy, float gz, float mx, float my, float mz)
  8.         {
  9.             float q1 = q[0], q2 = q[1], q3 = q[2], q4 = q[3]; // short name local variable for readability
  10.             float norm;
  11.             float hx, hy, _2bx, _2bz;
  12.             float s1, s2, s3, s4;
  13.             float qDot1, qDot2, qDot3, qDot4;

  14.             // Auxiliary variables to avoid repeated arithmetic
  15.             float _2q1mx;
  16.             float _2q1my;
  17.             float _2q1mz;
  18.             float _2q2mx;
  19.             float _4bx;
  20.             float _4bz;
  21.             float _2q1 = 2.0f * q1;
  22.             float _2q2 = 2.0f * q2;
  23.             float _2q3 = 2.0f * q3;
  24.             float _2q4 = 2.0f * q4;
  25.             float _2q1q3 = 2.0f * q1 * q3;
  26.             float _2q3q4 = 2.0f * q3 * q4;
  27.             float q1q1 = q1 * q1;
  28.             float q1q2 = q1 * q2;
  29.             float q1q3 = q1 * q3;
  30.             float q1q4 = q1 * q4;
  31.             float q2q2 = q2 * q2;
  32.             float q2q3 = q2 * q3;
  33.             float q2q4 = q2 * q4;
  34.             float q3q3 = q3 * q3;
  35.             float q3q4 = q3 * q4;
  36.             float q4q4 = q4 * q4;

  37.             // Normalise accelerometer measurement
  38.             norm = sqrtf(ax * ax + ay * ay + az * az);
  39.             if (norm == 0.0f) return; // handle NaN
  40.             norm = 1.0f/norm;
  41.             ax *= norm;
  42.             ay *= norm;
  43.             az *= norm;

  44.             // Normalise magnetometer measurement
  45.             norm = sqrtf(mx * mx + my * my + mz * mz);
  46.             if (norm == 0.0f) return; // handle NaN
  47.             norm = 1.0f/norm;
  48.             mx *= norm;
  49.             my *= norm;
  50.             mz *= norm;

  51.             // Reference direction of Earth's magnetic field
  52.             _2q1mx = 2.0f * q1 * mx;
  53.             _2q1my = 2.0f * q1 * my;
  54.             _2q1mz = 2.0f * q1 * mz;
  55.             _2q2mx = 2.0f * q2 * mx;
  56.             hx = mx * q1q1 - _2q1my * q4 + _2q1mz * q3 + mx * q2q2 + _2q2 * my * q3 + _2q2 * mz * q4 - mx * q3q3 - mx * q4q4;
  57.             hy = _2q1mx * q4 + my * q1q1 - _2q1mz * q2 + _2q2mx * q3 - my * q2q2 + my * q3q3 + _2q3 * mz * q4 - my * q4q4;
  58.             _2bx = sqrtf(hx * hx + hy * hy);
  59.             _2bz = -_2q1mx * q3 + _2q1my * q2 + mz * q1q1 + _2q2mx * q4 - mz * q2q2 + _2q3 * my * q4 - mz * q3q3 + mz * q4q4;
  60.             _4bx = 2.0f * _2bx;
  61.             _4bz = 2.0f * _2bz;

  62.             // Gradient decent algorithm corrective step
  63.             s1 = -_2q3 * (2.0f * q2q4 - _2q1q3 - ax) + _2q2 * (2.0f * q1q2 + _2q3q4 - ay) - _2bz * q3 * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (-_2bx * q4 + _2bz * q2) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + _2bx * q3 * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
  64.             s2 = _2q4 * (2.0f * q2q4 - _2q1q3 - ax) + _2q1 * (2.0f * q1q2 + _2q3q4 - ay) - 4.0f * q2 * (1.0f - 2.0f * q2q2 - 2.0f * q3q3 - az) + _2bz * q4 * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (_2bx * q3 + _2bz * q1) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + (_2bx * q4 - _4bz * q2) * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
  65.             s3 = -_2q1 * (2.0f * q2q4 - _2q1q3 - ax) + _2q4 * (2.0f * q1q2 + _2q3q4 - ay) - 4.0f * q3 * (1.0f - 2.0f * q2q2 - 2.0f * q3q3 - az) + (-_4bx * q3 - _2bz * q1) * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (_2bx * q2 + _2bz * q4) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + (_2bx * q1 - _4bz * q3) * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
  66.             s4 = _2q2 * (2.0f * q2q4 - _2q1q3 - ax) + _2q3 * (2.0f * q1q2 + _2q3q4 - ay) + (-_4bx * q4 + _2bz * q2) * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (-_2bx * q1 + _2bz * q3) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + _2bx * q2 * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
  67.             norm = sqrtf(s1 * s1 + s2 * s2 + s3 * s3 + s4 * s4); // normalise step magnitude
  68.             norm = 1.0f/norm;
  69.             s1 *= norm;
  70.             s2 *= norm;
  71.             s3 *= norm;
  72.             s4 *= norm;

  73.             // Compute rate of change of quaternion
  74.             qDot1 = 0.5f * (-q2 * gx - q3 * gy - q4 * gz) - beta * s1;
  75.             qDot2 = 0.5f * (q1 * gx + q3 * gz - q4 * gy) - beta * s2;
  76.             qDot3 = 0.5f * (q1 * gy - q2 * gz + q4 * gx) - beta * s3;
  77.             qDot4 = 0.5f * (q1 * gz + q2 * gy - q3 * gx) - beta * s4;

  78.             // Integrate to yield quaternion
  79.             q1 += qDot1 * deltat;
  80.             q2 += qDot2 * deltat;
  81.             q3 += qDot3 * deltat;
  82.             q4 += qDot4 * deltat;
  83.             norm = sqrtf(q1 * q1 + q2 * q2 + q3 * q3 + q4 * q4); // normalise quaternion
  84.             norm = 1.0f/norm;
  85.             q[0] = q1 * norm;
  86.             q[1] = q2 * norm;
  87.             q[2] = q3 * norm;
  88.             q[3] = q4 * norm;

  89.         }
  90.   
  91.   
  92.   
  93.  // Similar to Madgwick scheme but uses proportional and integral filtering on the error between estimated reference vectors and
  94.  // measured ones.
  95.             void MahonyQuaternionUpdate(float ax, float ay, float az, float gx, float gy, float gz, float mx, float my, float mz)
  96.         {
  97.             float q1 = q[0], q2 = q[1], q3 = q[2], q4 = q[3]; // short name local variable for readability
  98.             float norm;
  99.             float hx, hy, bx, bz;
  100.             float vx, vy, vz, wx, wy, wz;
  101.             float ex, ey, ez;
  102.             float pa, pb, pc;

  103.             // Auxiliary variables to avoid repeated arithmetic
  104.             float q1q1 = q1 * q1;
  105.             float q1q2 = q1 * q2;
  106.             float q1q3 = q1 * q3;
  107.             float q1q4 = q1 * q4;
  108.             float q2q2 = q2 * q2;
  109.             float q2q3 = q2 * q3;
  110.             float q2q4 = q2 * q4;
  111.             float q3q3 = q3 * q3;
  112.             float q3q4 = q3 * q4;
  113.             float q4q4 = q4 * q4;

  114.             // Normalise accelerometer measurement
  115.             norm = sqrtf(ax * ax + ay * ay + az * az);
  116.             if (norm == 0.0f) return; // handle NaN
  117.             norm = 1.0f / norm; // use reciprocal for division
  118.             ax *= norm;
  119.             ay *= norm;
  120.             az *= norm;

  121.             // Normalise magnetometer measurement
  122.             norm = sqrtf(mx * mx + my * my + mz * mz);
  123.             if (norm == 0.0f) return; // handle NaN
  124.             norm = 1.0f / norm; // use reciprocal for division
  125.             mx *= norm;
  126.             my *= norm;
  127.             mz *= norm;

  128.             // Reference direction of Earth




采用 MPU9250的话.
首先配置
MPU_9250_I2C_SLAVE_ADDR = 0x68        MPU_9250_I2C_DEVICE_ID = 0x71

  1.         write_byte_data(PWR_MGMT_1, 0x01)  /* Reset device. */
  2.         time_sleep(0.1)
  3.         write_byte_data(PWR_MGMT_1, 0x00)  /* Wake up chip. */

  4.         write_byte_data(CONFIG, 0x03)       //0x1A --> accel bandwidth=44 delay=4.9ms  gyroscope:band width=42Hz, delay=4.8ms 1Khz  : 低通滤波
  5.         write_byte_data(SMPLRT_DIV, 0x09)    //0x19  --> 采样频率= 陀螺仪输出频率 / ( 1+SMPLRT_DIV).  根据低通滤波设置, 陀螺仪输出频率为 1KHz. 这样设定采样频率为 100Hz. 即 FIFO输出/DMP采样/运动检测都基于此采样频率.
  6.         write_byte_data(GYRO_CONFIG, gyro_range << 3) //0x1B--> GYRO_RANGE_250
  7.         write_byte_data(ACCEL_CONFIG, accel_range << 3) //0x1C --> ACCEL_RANGE_2G
  8.         write_byte_data(ACCEL_CONFIG_2, 0x03) //低通滤波二配置.
  9.         write_byte_data(INT_PIN_CFG, 0x02) //0x37 --> 直接访问扩展IIC.即访问磁力计
从寄存器的取值为 ADC的值.  16 位 ADC 的 加速度/ 角速度 对应的实际数值转化过来, 扣除最初的符号位. 
实际加速度值 = 寄存器值 / (精度 2.0g/32768.0)  // ACCEL_RANGE_2G 
实际角速度值 = (寄存器值 / (精度 250.0/32768.0) )  * PI/180.0f     // GYRO_RANGE_250 时
最高为1时, 记得变换成 负值.

角速度

采样完毕, INT_STATUS = 0x3A 寄存器 0x01 设置, 从寄存器 ACCEL_OUT 0x3B/GYRO_OUT 0x41 读出信息, 转化成实际速度值.


计算四元数


点击(此处)折叠或打开

  1. #include "IMU.h"

  2. #include "math.h"

  3. #include "Maths.h"

  4. // ==================================================================================

  5. //加Q: 4 4 8 2 2 2 46 5 讨论

  6. // 描述:

  7. // 必须定义'halfT '为周期的一半,以及滤波器的参数Kp和Ki

  8. // 四元数'q0', 'q1', 'q2', 'q3'定义为全局变量

  9. // 需要在每一个采样周期调用'IMUupdate()'函数

  10. // 陀螺仪数据单位是弧度/秒,加速度计的单位无关重要,因为会被规范化

  11. // ==================================================================================

  12. #define Kp 90.0f // 比例常数

  13. #define Ki 0.001f // 积分常数

  14. #define halfT 0.0005f//半周期

  15. #define T    0.001f // 周期为1ms

  16. // ==================================================================================

  17. // 变量定义

  18. float q0 = 1, q1 = 0, q2 = 0, q3 = 0; // 四元数

  19. float exInt = 0, eyInt = 0, ezInt = 0; // 误差积分累计值

  20. // ==================================================================================

  21. // 函数原型:void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az)

  22. // 功 能:互补滤波进行姿态解算

  23. // 输 入:陀螺仪数据及加速度计数据

  24. // ==================================================================================

  25. void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az)

  26. {

  27. float norm;

  28. float vx, vy, vz;

  29. float ex, ey, ez;

  30. //四元数积分,求得当前的姿态

  31. float q0_last = q0;

  32. float q1_last = q1;

  33. float q2_last = q2;

  34. float q3_last = q3;

  35. //把加速度计的三维向量转成单位向量

  36. norm = invSqrt(ax*ax + ay*ay + az*az);

  37. ax = ax * norm;

  38. ay = ay * norm;

  39. az = az * norm;

  40. //估计重力加速度方向在飞行器坐标系中的表示,为四元数表示的旋转矩阵的第三行

  41. vx = 2*(q1*q3 - q0*q2);

  42. vy = 2*(q0*q1 + q2*q3);

  43. vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;

  44. //加速度计读取的方向与重力加速度方向的差值,用向量叉乘计算

  45. ex = ay*vz - az*vy;

  46. ey = az*vx - ax*vz;

  47. ez = ax*vy - ay*vx;

  48. //误差累积,已与积分常数相乘

  49. exInt = exInt + ex*Ki;

  50. eyInt = eyInt + ey*Ki;

  51. ezInt = ezInt + ez*Ki;

  52. //用叉积误差来做PI修正陀螺零偏,即抵消陀螺读数中的偏移量

  53. gx = gx + Kp*ex + exInt;

  54. gy = gy + Kp*ey + eyInt;

  55. gz = gz + Kp*ez + ezInt;

  56. //一阶近似算法

  57. q0 = q0_last + (-q1_last*gx - q2_last*gy - q3_last*gz)*halfT;

  58. q1 = q1_last + ( q0_last*gx + q2_last*gz - q3_last*gy)*halfT;

  59. q2 = q2_last + ( q0_last*gy - q1_last*gz + q3_last*gx)*halfT;

  60. q3 = q3_last + ( q0_last*gz + q1_last*gy - q2_last*gx)*halfT;

  61. //    //二阶近似算法

  62. //    float delta2 = (gx*gx + gy*gy + gz*gz)*T*T;

  63. //    q0 = q0_last*(1-delta2/8) + (-q1_last*gx - q2_last*gy - q3_last*gz)*halfT;

  64. //    q1 = q1_last*(1-delta2/8) + ( q0_last*gx + q2_last*gz - q3_last*gy)*halfT;

  65. //    q2 = q2_last*(1-delta2/8) + ( q0_last*gy - q1_last*gz + q3_last*gx)*halfT;

  66. //    q3 = q3_last*(1-delta2/8) + ( q0_last*gz + q1_last*gy - q2_last*gx)*halfT;

  67. //    //三阶近似算法

  68. //    float delta2 = (gx*gx + gy*gy + gz*gz)*T*T;

  69. //    q0 = q0_last*(1-delta2/8) + (-q1_last*gx - q2_last*gy - q3_last*gz)*T*(0.5 - delta2/48);

  70. //    q1 = q1_last*(1-delta2/8) + ( q0_last*gx + q2_last*gz - q3_last*gy)*T*(0.5 - delta2/48);

  71. //    q2 = q2_last*(1-delta2/8) + ( q0_last*gy - q1_last*gz + q3_last*gx)*T*(0.5 - delta2/48);

  72. //    q3 = q3_last*(1-delta2/8) + ( q0_last*gz + q1_last*gy - q2_last*gx)*T*(0.5 - delta2/48);

  73. //    //四阶近似算法

  74. //    float delta2 = (gx*gx + gy*gy + gz*gz)*T*T;

  75. //    q0 = q0_last*(1 - delta2/8 + delta2*delta2/384) + (-q1_last*gx - q2_last*gy - q3_last*gz)*T*(0.5 - delta2/48);

  76. //    q1 = q1_last*(1 - delta2/8 + delta2*delta2/384) + ( q0_last*gx + q2_last*gz - q3_last*gy)*T*(0.5 - delta2/48);

  77. //    q2 = q2_last*(1 - delta2/8 + delta2*delta2/384) + ( q0_last*gy - q1_last*gz + q3_last*gx)*T*(0.5 - delta2/48);

  78. //    q3 = q3_last*(1 - delta2/8 + delta2*delta2/384) + ( q0_last*gz + q1_last*gy - q2_last*gx)*T*(0.5 - delta2/48);

  79. //四元数规范化

  80. norm = invSqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);

  81. q0 = q0 * norm;

  82. q1 = q1 * norm;

  83. q2 = q2 * norm;

  84. q3 = q3 * norm;

  85. //out_angle.yaw += filter_gyro.z * RawData_to_Angle * 0.001f;

  86. out_angle.yaw = atan2(2 * q1 * q2 + 2 * q0 * q3, -2 * q2*q2 - 2 * q3* q3 + 1)* 57.3;

  87. }

  88. //Pitch是围绕X轴旋转,也叫作俯仰角

  89. //roll是围绕Y轴旋转,也叫作翻滚角

  90. //yaw是围绕Z轴旋转,也叫作偏航角

  91. /******************************************************************************

  92. 函数原型:    void Get_Eulerian_Angle(struct _out_angle *angle)

  93. 功 能:    四元数转欧拉角

  94. *******************************************************************************/

  95. void Get_Eulerian_Angle(struct _out_angle *angle)

  96. {

  97. angle->pitch = -atan2(2.0f*(q0*q1 + q2*q3),q0*q0 - q1*q1 - q2*q2 + q3*q3)*Radian_to_Angle;

  98. angle->roll = asin (2.0f*(q0*q2 - q1*q3))*Radian_to_Angle;

  99. Angle.pitch = angle->pitch;

  100. Angle.roll = angle->roll;

  101. Angle.yaw = out_angle.yaw;

  102. }




阅读(10265) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~