Advertisement
HarzSR

MPU6050

Jan 31st, 2017
1,017
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.77 KB | None | 0 0
  1. #include "I2Cdev.h" // I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
  2. #include "MPU6050_6Axis_MotionApps20.h"
  3. #include "MPU6050.h" // not necessary if using MotionApps include file
  4.  
  5. #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  6. #include "Wire.h"
  7. #endif
  8.  
  9. MPU6050 mpu;
  10. //MPU6050 mpu(0x69); // <-- use for AD0 high
  11.  
  12. /* ======================
  13. | Pin | Connection |
  14. ======================
  15. | A4 | (SDA) |
  16. | A5 | (SCL) |
  17. | 3.3V | VCC |
  18. | GND | GND |
  19. | 2 | INIT |
  20. ====================== */
  21.  
  22. // Uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual
  23. // quaternion components in a [w, x, y, z] format (not best for parsing
  24. // on a remote host such as Processing or something though)
  25.  
  26. // #define OUTPUT_READABLE_QUATERNION
  27.  
  28. // Uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles
  29. // (in degrees) calculated from the quaternions coming from the FIFO.
  30. // Note that Euler angles suffer from gimbal lock - http://en.wikipedia.org/wiki/Gimbal_lock
  31.  
  32. // #define OUTPUT_READABLE_EULER
  33.  
  34. // Uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/
  35. // pitch/roll angles (in degrees) calculated from the quaternions coming
  36. // from the FIFO. Note this also requires gravity vector calculations.
  37. // Also note that yaw/pitch/roll angles suffer from gimbal lock - http://en.wikipedia.org/wiki/Gimbal_lock
  38.  
  39. #define OUTPUT_READABLE_YAWPITCHROLL
  40.  
  41. // Uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration
  42. // components with gravity removed. This acceleration reference frame is
  43. // not compensated for orientation, so +X is always +X according to the
  44. // sensor, just without the effects of gravity. If you want acceleration
  45. // compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead.
  46.  
  47. // #define OUTPUT_READABLE_REALACCEL
  48.  
  49. // Uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration
  50. // components with gravity removed and adjusted for the world frame of
  51. // reference (yaw is relative to initial orientation, since no magnetometer
  52. // is present in this case). Could be quite handy in some cases.
  53.  
  54. // #define OUTPUT_READABLE_WORLDACCEL
  55.  
  56. // Uncomment "OUTPUT_TEAPOT" if you want output that matches the
  57. // format used for the InvenSense teapot demo
  58.  
  59. // #define OUTPUT_TEAPOT
  60.  
  61. #define INTERRUPT_PIN 2 // INIT for MPU6050
  62. #define LED_PIN 13 // Arduino is 13 for Indication
  63.  
  64. bool blinkState = false;
  65.  
  66. // MPU Control / Status Vars
  67. bool dmpReady = false; // Set true if DMP init was successful
  68. uint8_t mpuIntStatus; // Holds actual interrupt status byte from MPU
  69. uint8_t devStatus; // Return status after each device operation (0 = success, !0 = error)
  70. uint16_t packetSize; // Expected DMP packet size (default is 42 bytes)
  71. uint16_t fifoCount; // Count of all bytes currently in FIFO
  72. uint8_t fifoBuffer[64]; // FIFO storage buffer
  73.  
  74. // Orientation / Motion Vars
  75. Quaternion q; // [w, x, y, z] Quaternion Container
  76. VectorInt16 aa; // [x, y, z] Accelorometer Sensor Measurements
  77. VectorInt16 aaReal; // [x, y, z] Gravity - Free Accelorometer Sensor Measurements
  78. VectorInt16 aaWorld; // [x, y, z] World - Frame Accelorometer Sensor Measurements
  79. VectorFloat gravity; // [x, y, z] Gravity Vector
  80. float euler[3]; // [psi, theta, phi] Euler angle container
  81. float ypr[3]; // [yaw, pitch, roll] Yaw / Pitch / Roll Container and Gravity Vector
  82.  
  83. // Packet Structure for InvenSense teapot demo
  84. uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };
  85.  
  86. // ================================================================
  87. // === INTERRUPT DETECTION ROUTINE ===
  88. // ================================================================
  89.  
  90. volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
  91.  
  92. void dmpDataReady()
  93. {
  94. mpuInterrupt = true;
  95. }
  96.  
  97. // ================================================================
  98. // === INITIAL SETUP ===
  99. // ================================================================
  100.  
  101. void setup()
  102. {
  103. // Join I2C bus (I2Cdev Library doesn't do this automatically)
  104. #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  105. Wire.begin();
  106. Wire.setClock(400000);
  107. #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  108. Fastwire::setup(400, true);
  109. #endif
  110.  
  111. // Initialize Serial Communication (115200 chosen because it is required for Teapot Demo output, but it's really up to you depending on your project)
  112. Serial.begin(115200);
  113.  
  114. while (!Serial);
  115. // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio
  116. // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to
  117. // the baud timing being too misaligned with processor ticks. You must use
  118. // 38400 or slower in these cases, or use some kind of external separate
  119. // crystal solution for the UART timer.
  120.  
  121. // Initialize Device
  122. Serial.println(F("Initializing I2C devices..."));
  123. mpu.initialize();
  124. pinMode(INTERRUPT_PIN, INPUT);
  125.  
  126. // Verify Connection
  127. Serial.println(F("Testing device connections..."));
  128. Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
  129.  
  130. // Wait for ready
  131. Serial.println(F("\nSend any character to begin DMP programming and demo: "));
  132. while (Serial.available() && Serial.read()); // Empty Buffer
  133. while (!Serial.available()); // Wait for Data
  134. while (Serial.available() && Serial.read()); // Empty Buffer Again
  135.  
  136. // Load and Configure the DMP
  137. Serial.println(F("Initializing DMP..."));
  138. devStatus = mpu.dmpInitialize();
  139.  
  140. // Supply your own Gyro Offsets here, scaled for Minimum Sensitivity
  141. mpu.setXGyroOffset(220);
  142. mpu.setYGyroOffset(76);
  143. mpu.setZGyroOffset(-85);
  144. mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
  145.  
  146. // make sure it worked (returns 0 if so)
  147. if (devStatus == 0)
  148. {
  149. Serial.println(F(" Enabling DMP... ")); // turn on the DMP, now that it's ready
  150. mpu.setDMPEnabled(true);
  151.  
  152. Serial.println(F(" Enabling interrupt detection (Arduino external interrupt 0)... ")); // Enable Arduino interrupt detection
  153. attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
  154. mpuIntStatus = mpu.getIntStatus();
  155.  
  156. Serial.println(F(" DMP ready! Waiting for first interrupt... ")); // Set our DMP Ready flag so the main loop() function knows it's okay to use it
  157. dmpReady = true;
  158.  
  159. packetSize = mpu.dmpGetFIFOPacketSize(); // get expected DMP packet size for later comparison
  160. }
  161. else
  162. {
  163. // ERROR!
  164. // 1 = initial memory load failed
  165. // 2 = DMP configuration updates failed
  166. // (if it's going to break, usually the code will be 1)
  167. Serial.print(F(" DMP Initialization failed (code : "));
  168. Serial.print(devStatus);
  169. Serial.println(F(")"));
  170. }
  171.  
  172. pinMode(LED_PIN, OUTPUT); // configure LED for output
  173. }
  174.  
  175. // ================================================================
  176. // === MAIN PROGRAM LOOP ===
  177. // ================================================================
  178.  
  179. void loop()
  180. {
  181. if (!dmpReady) // if programming failed, don't try to do anything
  182. return;
  183.  
  184. while (!mpuInterrupt && fifoCount < packetSize) // wait for MPU interrupt or extra packet(s) available
  185. {
  186. // other program behavior stuff here
  187. // if you are really paranoid you can frequently test in between other
  188. // stuff to see if mpuInterrupt is true, and if so, "break;" from the
  189. // while() loop to immediately process the MPU data
  190. }
  191.  
  192. mpuInterrupt = false; // reset interrupt flag and get INT_STATUS byte
  193. mpuIntStatus = mpu.getIntStatus();
  194.  
  195. fifoCount = mpu.getFIFOCount(); // get current FIFO count
  196.  
  197. if ((mpuIntStatus & 0x10) || fifoCount == 1024) // Check for overflow (this should never happen unless our code is too inefficient)
  198. {
  199. mpu.resetFIFO(); // reset so we can continue cleanly
  200. Serial.println(F("FIFO overflow!"));
  201. }
  202. else if (mpuIntStatus & 0x02) // Otherwise, check for DMP data ready interrupt (this should happen frequently)
  203. {
  204. while (fifoCount < packetSize) // Wait for correct available data length, should be a VERY short wait
  205. fifoCount = mpu.getFIFOCount();
  206.  
  207. mpu.getFIFOBytes(fifoBuffer, packetSize); // Read a packet from FIFO
  208.  
  209. fifoCount -= packetSize; // Track FIFO count here in case there is > 1 packet available (this lets us immediately read more without waiting for an interrupt)
  210.  
  211. #ifdef OUTPUT_READABLE_QUATERNION // Display quaternion values in easy matrix form: w x y z
  212. mpu.dmpGetQuaternion(&q, fifoBuffer);
  213. Serial.print("Quat : \t");
  214. Serial.print(q.w);
  215. Serial.print("\t");
  216. Serial.print(q.x);
  217. Serial.print("\t");
  218. Serial.print(q.y);
  219. Serial.print("\t");
  220. Serial.println(q.z);
  221. #endif
  222.  
  223. #ifdef OUTPUT_READABLE_EULER // Display Euler angles in degrees
  224. mpu.dmpGetQuaternion(&q, fifoBuffer);
  225. mpu.dmpGetEuler(euler, &q);
  226. Serial.print("Euler : \t");
  227. Serial.print(euler[0] * 180/M_PI);
  228. Serial.print("\t");
  229. Serial.print(euler[1] * 180/M_PI);
  230. Serial.print("\t");
  231. Serial.println(euler[2] * 180/M_PI);
  232. #endif
  233.  
  234. #ifdef OUTPUT_READABLE_YAWPITCHROLL // Display Euler angles in degrees
  235. mpu.dmpGetQuaternion(&q, fifoBuffer);
  236. mpu.dmpGetGravity(&gravity, &q);
  237. mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
  238. Serial.print("YPR : \t");
  239. Serial.print(ypr[0] * 180/M_PI);
  240. Serial.print("\t");
  241. Serial.print(ypr[1] * 180/M_PI);
  242. Serial.print("\t");
  243. Serial.println(ypr[2] * 180/M_PI);
  244. #endif
  245.  
  246. #ifdef OUTPUT_READABLE_REALACCEL // Display Real Acceleration, Adjusted to Remove Gravity
  247. mpu.dmpGetQuaternion(&q, fifoBuffer);
  248. mpu.dmpGetAccel(&aa, fifoBuffer);
  249. mpu.dmpGetGravity(&gravity, &q);
  250. mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
  251. Serial.print("areal\t");
  252. Serial.print(aaReal.x);
  253. Serial.print("\t");
  254. Serial.print(aaReal.y);
  255. Serial.print("\t");
  256. Serial.println(aaReal.z);
  257. #endif
  258.  
  259. #ifdef OUTPUT_READABLE_WORLDACCEL // Display Initial World-Frame Acceleration, Adjusted to Remove Gravity and Rotated based on known Orientation from Quaternion
  260. mpu.dmpGetQuaternion(&q, fifoBuffer);
  261. mpu.dmpGetAccel(&aa, fifoBuffer);
  262. mpu.dmpGetGravity(&gravity, &q);
  263. mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
  264. mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
  265. Serial.print("aworld\t");
  266. Serial.print(aaWorld.x);
  267. Serial.print("\t");
  268. Serial.print(aaWorld.y);
  269. Serial.print("\t");
  270. Serial.println(aaWorld.z);
  271. #endif
  272.  
  273. #ifdef OUTPUT_TEAPOT // Display Quaternion values in InvenSense Teapot demo format:
  274. teapotPacket[2] = fifoBuffer[0];
  275. teapotPacket[3] = fifoBuffer[1];
  276. teapotPacket[4] = fifoBuffer[4];
  277. teapotPacket[5] = fifoBuffer[5];
  278. teapotPacket[6] = fifoBuffer[8];
  279. teapotPacket[7] = fifoBuffer[9];
  280. teapotPacket[8] = fifoBuffer[12];
  281. teapotPacket[9] = fifoBuffer[13];
  282. Serial.write(teapotPacket, 14);
  283. teapotPacket[11]++; // PacketCount, Loops at 0xFF on purpose
  284. #endif
  285.  
  286. blinkState = !blinkState; // Blink LED to Indicate Activity
  287. digitalWrite(LED_PIN, blinkState);
  288. }
  289. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement