使いやすいように。
Dependencies: ArduinoSerial I2Cdev
Fork of MPU6050 by
MPU6050_6Axis_MotionApps20.h
00001 #ifndef _MPU6050_6AXIS_MOTIONAPPS20_H_ 00002 #define _MPU6050_6AXIS_MOTIONAPPS20_H_ 00003 00004 #include "I2Cdev.h" 00005 #include "helper_3dmath.h" 00006 00007 // MotionApps 2.0 DMP implementation, built using the MPU-6050EVB evaluation board 00008 #define MPU6050_INCLUDE_DMP_MOTIONAPPS20 00009 00010 #include "MPU6050.h" 00011 00012 // Tom Carpenter's conditional PROGMEM code 00013 // http://forum.arduino.cc/index.php?topic=129407.0 00014 #ifdef __AVR__ 00015 #include <avr/pgmspace.h> 00016 #else 00017 // Teensy 3.0 library conditional PROGMEM code from Paul Stoffregen 00018 #ifndef __PGMSPACE_H_ 00019 #define __PGMSPACE_H_ 1 00020 #include <inttypes.h> 00021 00022 #define PROGMEM 00023 #define PGM_P const char * 00024 #define PSTR(str) (str) 00025 #define F(x) x 00026 00027 typedef void prog_void; 00028 typedef char prog_char; 00029 typedef unsigned char prog_uchar; 00030 typedef int8_t prog_int8_t; 00031 typedef uint8_t prog_uint8_t; 00032 typedef int16_t prog_int16_t; 00033 typedef uint16_t prog_uint16_t; 00034 typedef int32_t prog_int32_t; 00035 typedef uint32_t prog_uint32_t; 00036 00037 #define strcpy_P(dest, src) strcpy((dest), (src)) 00038 #define strcat_P(dest, src) strcat((dest), (src)) 00039 #define strcmp_P(a, b) strcmp((a), (b)) 00040 00041 #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 00042 #define pgm_read_word(addr) (*(const unsigned short *)(addr)) 00043 #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) 00044 #define pgm_read_float(addr) (*(const float *)(addr)) 00045 00046 #define pgm_read_byte_near(addr) pgm_read_byte(addr) 00047 #define pgm_read_word_near(addr) pgm_read_word(addr) 00048 #define pgm_read_dword_near(addr) pgm_read_dword(addr) 00049 #define pgm_read_float_near(addr) pgm_read_float(addr) 00050 #define pgm_read_byte_far(addr) pgm_read_byte(addr) 00051 #define pgm_read_word_far(addr) pgm_read_word(addr) 00052 #define pgm_read_dword_far(addr) pgm_read_dword(addr) 00053 #define pgm_read_float_far(addr) pgm_read_float(addr) 00054 #endif 00055 #endif 00056 00057 /* Source is from the InvenSense MotionApps v2 demo code. Original source is 00058 * unavailable, unless you happen to be amazing as decompiling binary by 00059 * hand (in which case, please contact me, and I'm totally serious). 00060 * 00061 * Also, I'd like to offer many, many thanks to Noah Zerkin for all of the 00062 * DMP reverse-engineering he did to help make this bit of wizardry 00063 * possible. 00064 */ 00065 00066 // NOTE! Enabling DEBUG adds about 3.3kB to the flash program size. 00067 // Debug output is now working even on ATMega328P MCUs (e.g. Arduino Uno) 00068 // after moving string constants to flash memory storage using the F() 00069 // compiler macro (Arduino IDE 1.0+ required). 00070 00071 // #define DEBUG 00072 #ifdef DEBUG 00073 #include "ArduinoSerial.h" 00074 ArduinoSerial arduinoSerial; 00075 #define DEBUG_PRINT(x) arduinoSerial.print(x) 00076 #define DEBUG_PRINTF(x, y) arduinoSerial.print(x, y) 00077 #define DEBUG_PRINTLN(x) arduinoSerial.println(x) 00078 #define DEBUG_PRINTLNF(x, y) arduinoSerial.println(x, y) 00079 #else 00080 #define DEBUG_PRINT(x) 00081 #define DEBUG_PRINTF(x, y) 00082 #define DEBUG_PRINTLN(x) 00083 #define DEBUG_PRINTLNF(x, y) 00084 #endif 00085 00086 #define MPU6050_DMP_CODE_SIZE 1929 // dmpMemory[] 00087 #define MPU6050_DMP_CONFIG_SIZE 192 // dmpConfig[] 00088 #define MPU6050_DMP_UPDATES_SIZE 47 // dmpUpdates[] 00089 00090 /* ================================================================================================ * 00091 | Default MotionApps v2.0 42-byte FIFO packet structure: | 00092 | | 00093 | [QUAT W][ ][QUAT X][ ][QUAT Y][ ][QUAT Z][ ][GYRO X][ ][GYRO Y][ ] | 00094 | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 00095 | | 00096 | [GYRO Z][ ][ACC X ][ ][ACC Y ][ ][ACC Z ][ ][ ] | 00097 | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 00098 * ================================================================================================ */ 00099 00100 // this block of memory gets written to the MPU on start-up, and it seems 00101 // to be volatile memory, so it has to be done each time (it only takes ~1 00102 // second though) 00103 const unsigned char dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = { 00104 // bank 0, 256 bytes 00105 0xFB, 0x00, 0x00, 0x3E, 0x00, 0x0B, 0x00, 0x36, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 00106 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0xFA, 0x80, 0x00, 0x0B, 0x12, 0x82, 0x00, 0x01, 00107 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00108 0x00, 0x28, 0x00, 0x00, 0xFF, 0xFF, 0x45, 0x81, 0xFF, 0xFF, 0xFA, 0x72, 0x00, 0x00, 0x00, 0x00, 00109 0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7F, 0xFF, 0xFF, 0xFE, 0x80, 0x01, 00110 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00111 0x00, 0x3E, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xCA, 0xE3, 0x09, 0x3E, 0x80, 0x00, 0x00, 00112 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 00113 0x41, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x2A, 0x00, 0x00, 0x16, 0x55, 0x00, 0x00, 0x21, 0x82, 00114 0xFD, 0x87, 0x26, 0x50, 0xFD, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x05, 0x80, 0x00, 00115 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 00116 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x6F, 0x00, 0x02, 0x65, 0x32, 0x00, 0x00, 0x5E, 0xC0, 00117 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00118 0xFB, 0x8C, 0x6F, 0x5D, 0xFD, 0x5D, 0x08, 0xD9, 0x00, 0x7C, 0x73, 0x3B, 0x00, 0x6C, 0x12, 0xCC, 00119 0x32, 0x00, 0x13, 0x9D, 0x32, 0x00, 0xD0, 0xD6, 0x32, 0x00, 0x08, 0x00, 0x40, 0x00, 0x01, 0xF4, 00120 0xFF, 0xE6, 0x80, 0x79, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xD6, 0x00, 0x00, 0x27, 0x10, 00121 00122 // bank 1, 256 bytes 00123 0xFB, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00124 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 00125 0x00, 0x00, 0xFA, 0x36, 0xFF, 0xBC, 0x30, 0x8E, 0x00, 0x05, 0xFB, 0xF0, 0xFF, 0xD9, 0x5B, 0xC8, 00126 0xFF, 0xD0, 0x9A, 0xBE, 0x00, 0x00, 0x10, 0xA9, 0xFF, 0xF4, 0x1E, 0xB2, 0x00, 0xCE, 0xBB, 0xF7, 00127 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x0C, 00128 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xCF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 00129 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, 00130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00133 0x00, 0x00, 0x00, 0x00, 0x03, 0x3F, 0x68, 0xB6, 0x79, 0x35, 0x28, 0xBC, 0xC6, 0x7E, 0xD1, 0x6C, 00134 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x6A, 0x00, 0x00, 0x00, 0x00, 00135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x30, 00136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00138 0x00, 0x00, 0x25, 0x4D, 0x00, 0x2F, 0x70, 0x6D, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x0C, 0x02, 0xD0, 00139 00140 // bank 2, 256 bytes 00141 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00142 0x00, 0x00, 0x01, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 00143 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xFF, 0xEF, 0x00, 0x00, 00144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00145 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00146 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00147 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00150 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 00153 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00157 00158 // bank 3, 256 bytes 00159 0xD8, 0xDC, 0xBA, 0xA2, 0xF1, 0xDE, 0xB2, 0xB8, 0xB4, 0xA8, 0x81, 0x91, 0xF7, 0x4A, 0x90, 0x7F, 00160 0x91, 0x6A, 0xF3, 0xF9, 0xDB, 0xA8, 0xF9, 0xB0, 0xBA, 0xA0, 0x80, 0xF2, 0xCE, 0x81, 0xF3, 0xC2, 00161 0xF1, 0xC1, 0xF2, 0xC3, 0xF3, 0xCC, 0xA2, 0xB2, 0x80, 0xF1, 0xC6, 0xD8, 0x80, 0xBA, 0xA7, 0xDF, 00162 0xDF, 0xDF, 0xF2, 0xA7, 0xC3, 0xCB, 0xC5, 0xB6, 0xF0, 0x87, 0xA2, 0x94, 0x24, 0x48, 0x70, 0x3C, 00163 0x95, 0x40, 0x68, 0x34, 0x58, 0x9B, 0x78, 0xA2, 0xF1, 0x83, 0x92, 0x2D, 0x55, 0x7D, 0xD8, 0xB1, 00164 0xB4, 0xB8, 0xA1, 0xD0, 0x91, 0x80, 0xF2, 0x70, 0xF3, 0x70, 0xF2, 0x7C, 0x80, 0xA8, 0xF1, 0x01, 00165 0xB0, 0x98, 0x87, 0xD9, 0x43, 0xD8, 0x86, 0xC9, 0x88, 0xBA, 0xA1, 0xF2, 0x0E, 0xB8, 0x97, 0x80, 00166 0xF1, 0xA9, 0xDF, 0xDF, 0xDF, 0xAA, 0xDF, 0xDF, 0xDF, 0xF2, 0xAA, 0xC5, 0xCD, 0xC7, 0xA9, 0x0C, 00167 0xC9, 0x2C, 0x97, 0x97, 0x97, 0x97, 0xF1, 0xA9, 0x89, 0x26, 0x46, 0x66, 0xB0, 0xB4, 0xBA, 0x80, 00168 0xAC, 0xDE, 0xF2, 0xCA, 0xF1, 0xB2, 0x8C, 0x02, 0xA9, 0xB6, 0x98, 0x00, 0x89, 0x0E, 0x16, 0x1E, 00169 0xB8, 0xA9, 0xB4, 0x99, 0x2C, 0x54, 0x7C, 0xB0, 0x8A, 0xA8, 0x96, 0x36, 0x56, 0x76, 0xF1, 0xB9, 00170 0xAF, 0xB4, 0xB0, 0x83, 0xC0, 0xB8, 0xA8, 0x97, 0x11, 0xB1, 0x8F, 0x98, 0xB9, 0xAF, 0xF0, 0x24, 00171 0x08, 0x44, 0x10, 0x64, 0x18, 0xF1, 0xA3, 0x29, 0x55, 0x7D, 0xAF, 0x83, 0xB5, 0x93, 0xAF, 0xF0, 00172 0x00, 0x28, 0x50, 0xF1, 0xA3, 0x86, 0x9F, 0x61, 0xA6, 0xDA, 0xDE, 0xDF, 0xD9, 0xFA, 0xA3, 0x86, 00173 0x96, 0xDB, 0x31, 0xA6, 0xD9, 0xF8, 0xDF, 0xBA, 0xA6, 0x8F, 0xC2, 0xC5, 0xC7, 0xB2, 0x8C, 0xC1, 00174 0xB8, 0xA2, 0xDF, 0xDF, 0xDF, 0xA3, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1, 0xB8, 0xA8, 0xB2, 0x86, 00175 00176 // bank 4, 256 bytes 00177 0xB4, 0x98, 0x0D, 0x35, 0x5D, 0xB8, 0xAA, 0x98, 0xB0, 0x87, 0x2D, 0x35, 0x3D, 0xB2, 0xB6, 0xBA, 00178 0xAF, 0x8C, 0x96, 0x19, 0x8F, 0x9F, 0xA7, 0x0E, 0x16, 0x1E, 0xB4, 0x9A, 0xB8, 0xAA, 0x87, 0x2C, 00179 0x54, 0x7C, 0xB9, 0xA3, 0xDE, 0xDF, 0xDF, 0xA3, 0xB1, 0x80, 0xF2, 0xC4, 0xCD, 0xC9, 0xF1, 0xB8, 00180 0xA9, 0xB4, 0x99, 0x83, 0x0D, 0x35, 0x5D, 0x89, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0xB5, 0x93, 0xA3, 00181 0x0E, 0x16, 0x1E, 0xA9, 0x2C, 0x54, 0x7C, 0xB8, 0xB4, 0xB0, 0xF1, 0x97, 0x83, 0xA8, 0x11, 0x84, 00182 0xA5, 0x09, 0x98, 0xA3, 0x83, 0xF0, 0xDA, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xD8, 0xF1, 0xA5, 00183 0x29, 0x55, 0x7D, 0xA5, 0x85, 0x95, 0x02, 0x1A, 0x2E, 0x3A, 0x56, 0x5A, 0x40, 0x48, 0xF9, 0xF3, 00184 0xA3, 0xD9, 0xF8, 0xF0, 0x98, 0x83, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0x97, 0x82, 0xA8, 0xF1, 00185 0x11, 0xF0, 0x98, 0xA2, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xDA, 0xF3, 0xDE, 0xD8, 0x83, 0xA5, 00186 0x94, 0x01, 0xD9, 0xA3, 0x02, 0xF1, 0xA2, 0xC3, 0xC5, 0xC7, 0xD8, 0xF1, 0x84, 0x92, 0xA2, 0x4D, 00187 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, 00188 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0x93, 0xA3, 0x4D, 00189 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, 00190 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0xA8, 0x8A, 0x9A, 00191 0xF0, 0x28, 0x50, 0x78, 0x9E, 0xF3, 0x88, 0x18, 0xF1, 0x9F, 0x1D, 0x98, 0xA8, 0xD9, 0x08, 0xD8, 00192 0xC8, 0x9F, 0x12, 0x9E, 0xF3, 0x15, 0xA8, 0xDA, 0x12, 0x10, 0xD8, 0xF1, 0xAF, 0xC8, 0x97, 0x87, 00193 00194 // bank 5, 256 bytes 00195 0x34, 0xB5, 0xB9, 0x94, 0xA4, 0x21, 0xF3, 0xD9, 0x22, 0xD8, 0xF2, 0x2D, 0xF3, 0xD9, 0x2A, 0xD8, 00196 0xF2, 0x35, 0xF3, 0xD9, 0x32, 0xD8, 0x81, 0xA4, 0x60, 0x60, 0x61, 0xD9, 0x61, 0xD8, 0x6C, 0x68, 00197 0x69, 0xD9, 0x69, 0xD8, 0x74, 0x70, 0x71, 0xD9, 0x71, 0xD8, 0xB1, 0xA3, 0x84, 0x19, 0x3D, 0x5D, 00198 0xA3, 0x83, 0x1A, 0x3E, 0x5E, 0x93, 0x10, 0x30, 0x81, 0x10, 0x11, 0xB8, 0xB0, 0xAF, 0x8F, 0x94, 00199 0xF2, 0xDA, 0x3E, 0xD8, 0xB4, 0x9A, 0xA8, 0x87, 0x29, 0xDA, 0xF8, 0xD8, 0x87, 0x9A, 0x35, 0xDA, 00200 0xF8, 0xD8, 0x87, 0x9A, 0x3D, 0xDA, 0xF8, 0xD8, 0xB1, 0xB9, 0xA4, 0x98, 0x85, 0x02, 0x2E, 0x56, 00201 0xA5, 0x81, 0x00, 0x0C, 0x14, 0xA3, 0x97, 0xB0, 0x8A, 0xF1, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, 00202 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x84, 0x0D, 0xDA, 0x0E, 0xD8, 0xA3, 0x29, 0x83, 0xDA, 00203 0x2C, 0x0E, 0xD8, 0xA3, 0x84, 0x49, 0x83, 0xDA, 0x2C, 0x4C, 0x0E, 0xD8, 0xB8, 0xB0, 0xA8, 0x8A, 00204 0x9A, 0xF5, 0x20, 0xAA, 0xDA, 0xDF, 0xD8, 0xA8, 0x40, 0xAA, 0xD0, 0xDA, 0xDE, 0xD8, 0xA8, 0x60, 00205 0xAA, 0xDA, 0xD0, 0xDF, 0xD8, 0xF1, 0x97, 0x86, 0xA8, 0x31, 0x9B, 0x06, 0x99, 0x07, 0xAB, 0x97, 00206 0x28, 0x88, 0x9B, 0xF0, 0x0C, 0x20, 0x14, 0x40, 0xB8, 0xB0, 0xB4, 0xA8, 0x8C, 0x9C, 0xF0, 0x04, 00207 0x28, 0x51, 0x79, 0x1D, 0x30, 0x14, 0x38, 0xB2, 0x82, 0xAB, 0xD0, 0x98, 0x2C, 0x50, 0x50, 0x78, 00208 0x78, 0x9B, 0xF1, 0x1A, 0xB0, 0xF0, 0x8A, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x8B, 0x29, 0x51, 0x79, 00209 0x8A, 0x24, 0x70, 0x59, 0x8B, 0x20, 0x58, 0x71, 0x8A, 0x44, 0x69, 0x38, 0x8B, 0x39, 0x40, 0x68, 00210 0x8A, 0x64, 0x48, 0x31, 0x8B, 0x30, 0x49, 0x60, 0xA5, 0x88, 0x20, 0x09, 0x71, 0x58, 0x44, 0x68, 00211 00212 // bank 6, 256 bytes 00213 0x11, 0x39, 0x64, 0x49, 0x30, 0x19, 0xF1, 0xAC, 0x00, 0x2C, 0x54, 0x7C, 0xF0, 0x8C, 0xA8, 0x04, 00214 0x28, 0x50, 0x78, 0xF1, 0x88, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xAC, 0x8C, 0x02, 0x26, 0x46, 0x66, 00215 0xF0, 0x89, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 00216 0xA9, 0x88, 0x09, 0x20, 0x59, 0x70, 0xAB, 0x11, 0x38, 0x40, 0x69, 0xA8, 0x19, 0x31, 0x48, 0x60, 00217 0x8C, 0xA8, 0x3C, 0x41, 0x5C, 0x20, 0x7C, 0x00, 0xF1, 0x87, 0x98, 0x19, 0x86, 0xA8, 0x6E, 0x76, 00218 0x7E, 0xA9, 0x99, 0x88, 0x2D, 0x55, 0x7D, 0x9E, 0xB9, 0xA3, 0x8A, 0x22, 0x8A, 0x6E, 0x8A, 0x56, 00219 0x8A, 0x5E, 0x9F, 0xB1, 0x83, 0x06, 0x26, 0x46, 0x66, 0x0E, 0x2E, 0x4E, 0x6E, 0x9D, 0xB8, 0xAD, 00220 0x00, 0x2C, 0x54, 0x7C, 0xF2, 0xB1, 0x8C, 0xB4, 0x99, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0x81, 0x91, 00221 0xAC, 0x38, 0xAD, 0x3A, 0xB5, 0x83, 0x91, 0xAC, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, 0x48, 0xD8, 00222 0x6D, 0xD9, 0x68, 0xD8, 0x8C, 0x9D, 0xAE, 0x29, 0xD9, 0x04, 0xAE, 0xD8, 0x51, 0xD9, 0x04, 0xAE, 00223 0xD8, 0x79, 0xD9, 0x04, 0xD8, 0x81, 0xF3, 0x9D, 0xAD, 0x00, 0x8D, 0xAE, 0x19, 0x81, 0xAD, 0xD9, 00224 0x01, 0xD8, 0xF2, 0xAE, 0xDA, 0x26, 0xD8, 0x8E, 0x91, 0x29, 0x83, 0xA7, 0xD9, 0xAD, 0xAD, 0xAD, 00225 0xAD, 0xF3, 0x2A, 0xD8, 0xD8, 0xF1, 0xB0, 0xAC, 0x89, 0x91, 0x3E, 0x5E, 0x76, 0xF3, 0xAC, 0x2E, 00226 0x2E, 0xF1, 0xB1, 0x8C, 0x5A, 0x9C, 0xAC, 0x2C, 0x28, 0x28, 0x28, 0x9C, 0xAC, 0x30, 0x18, 0xA8, 00227 0x98, 0x81, 0x28, 0x34, 0x3C, 0x97, 0x24, 0xA7, 0x28, 0x34, 0x3C, 0x9C, 0x24, 0xF2, 0xB0, 0x89, 00228 0xAC, 0x91, 0x2C, 0x4C, 0x6C, 0x8A, 0x9B, 0x2D, 0xD9, 0xD8, 0xD8, 0x51, 0xD9, 0xD8, 0xD8, 0x79, 00229 00230 // bank 7, 138 bytes (remainder) 00231 0xD9, 0xD8, 0xD8, 0xF1, 0x9E, 0x88, 0xA3, 0x31, 0xDA, 0xD8, 0xD8, 0x91, 0x2D, 0xD9, 0x28, 0xD8, 00232 0x4D, 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x83, 0x93, 0x35, 0x3D, 0x80, 0x25, 0xDA, 00233 0xD8, 0xD8, 0x85, 0x69, 0xDA, 0xD8, 0xD8, 0xB4, 0x93, 0x81, 0xA3, 0x28, 0x34, 0x3C, 0xF3, 0xAB, 00234 0x8B, 0xF8, 0xA3, 0x91, 0xB6, 0x09, 0xB4, 0xD9, 0xAB, 0xDE, 0xFA, 0xB0, 0x87, 0x9C, 0xB9, 0xA3, 00235 0xDD, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x95, 0xF1, 0xA3, 0xA3, 0xA3, 0x9D, 0xF1, 0xA3, 0xA3, 0xA3, 00236 0xA3, 0xF2, 0xA3, 0xB4, 0x90, 0x80, 0xF2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 00237 0xA3, 0xB2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB0, 0x87, 0xB5, 0x99, 0xF1, 0xA3, 0xA3, 0xA3, 00238 0x98, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x97, 0xA3, 0xA3, 0xA3, 0xA3, 0xF3, 0x9B, 0xA3, 0xA3, 0xDC, 00239 0xB9, 0xA7, 0xF1, 0x26, 0x26, 0x26, 0xD8, 0xD8, 0xFF 00240 }; 00241 00242 // thanks to Noah Zerkin for piecing this stuff together! 00243 const unsigned char dmpConfig[MPU6050_DMP_CONFIG_SIZE] PROGMEM = { 00244 // BANK OFFSET LENGTH [DATA] 00245 0x03, 0x7B, 0x03, 0x4C, 0xCD, 0x6C, // FCFG_1 inv_set_gyro_calibration 00246 0x03, 0xAB, 0x03, 0x36, 0x56, 0x76, // FCFG_3 inv_set_gyro_calibration 00247 0x00, 0x68, 0x04, 0x02, 0xCB, 0x47, 0xA2, // D_0_104 inv_set_gyro_calibration 00248 0x02, 0x18, 0x04, 0x00, 0x05, 0x8B, 0xC1, // D_0_24 inv_set_gyro_calibration 00249 0x01, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, // D_1_152 inv_set_accel_calibration 00250 0x03, 0x7F, 0x06, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97, // FCFG_2 inv_set_accel_calibration 00251 0x03, 0x89, 0x03, 0x26, 0x46, 0x66, // FCFG_7 inv_set_accel_calibration 00252 0x00, 0x6C, 0x02, 0x20, 0x00, // D_0_108 inv_set_accel_calibration 00253 0x02, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_00 inv_set_compass_calibration 00254 0x02, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_01 00255 0x02, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_02 00256 0x02, 0x4C, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_10 00257 0x02, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_11 00258 0x02, 0x54, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_12 00259 0x02, 0x58, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_20 00260 0x02, 0x5C, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_21 00261 0x02, 0xBC, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_22 00262 0x01, 0xEC, 0x04, 0x00, 0x00, 0x40, 0x00, // D_1_236 inv_apply_endian_accel 00263 0x03, 0x7F, 0x06, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97, // FCFG_2 inv_set_mpu_sensors 00264 0x04, 0x02, 0x03, 0x0D, 0x35, 0x5D, // CFG_MOTION_BIAS inv_turn_on_bias_from_no_motion 00265 0x04, 0x09, 0x04, 0x87, 0x2D, 0x35, 0x3D, // FCFG_5 inv_set_bias_update 00266 0x00, 0xA3, 0x01, 0x00, // D_0_163 inv_set_dead_zone 00267 // SPECIAL 0x01 = enable interrupts 00268 0x00, 0x00, 0x00, 0x01, // SET INT_ENABLE at i=22, SPECIAL INSTRUCTION 00269 0x07, 0x86, 0x01, 0xFE, // CFG_6 inv_set_fifo_interupt 00270 0x07, 0x41, 0x05, 0xF1, 0x20, 0x28, 0x30, 0x38, // CFG_8 inv_send_quaternion 00271 0x07, 0x7E, 0x01, 0x30, // CFG_16 inv_set_footer 00272 0x07, 0x46, 0x01, 0x9A, // CFG_GYRO_SOURCE inv_send_gyro 00273 0x07, 0x47, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_9 inv_send_gyro -> inv_construct3_fifo 00274 0x07, 0x6C, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_12 inv_send_accel -> inv_construct3_fifo 00275 0x02, 0x16, 0x02, 0x00, 0x01 // D_0_22 inv_set_fifo_rate 00276 00277 // This very last 0x01 WAS a 0x09, which drops the FIFO rate down to 20 Hz. 0x07 is 25 Hz, 00278 // 0x01 is 100Hz. Going faster than 100Hz (0x00=200Hz) tends to result in very noisy data. 00279 // DMP output frequency is calculated easily using this equation: (200Hz / (1 + value)) 00280 00281 // It is important to make sure the host processor can keep up with reading and processing 00282 // the FIFO output at the desired rate. Handling FIFO overflow cleanly is also a good idea. 00283 }; 00284 00285 const unsigned char dmpUpdates[MPU6050_DMP_UPDATES_SIZE] PROGMEM = { 00286 0x01, 0xB2, 0x02, 0xFF, 0xFF, 00287 0x01, 0x90, 0x04, 0x09, 0x23, 0xA1, 0x35, 00288 0x01, 0x6A, 0x02, 0x06, 0x00, 00289 0x01, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00290 0x00, 0x60, 0x04, 0x40, 0x00, 0x00, 0x00, 00291 0x01, 0x62, 0x02, 0x00, 0x00, 00292 0x00, 0x60, 0x04, 0x00, 0x40, 0x00, 0x00 00293 }; 00294 00295 uint8_t MPU6050::dmpInitialize() { 00296 // reset device 00297 DEBUG_PRINTLN(F("\n\nResetting MPU6050...")); 00298 reset(); 00299 wait_ms(30); // wait after reset 00300 00301 // enable sleep mode and wake cycle 00302 /*Serial.println(F("Enabling sleep mode...")); 00303 setSleepEnabled(true); 00304 Serial.println(F("Enabling wake cycle...")); 00305 setWakeCycleEnabled(true);*/ 00306 00307 // disable sleep mode 00308 DEBUG_PRINTLN(F("Disabling sleep mode...")); 00309 setSleepEnabled(false); 00310 00311 // get MPU hardware revision 00312 DEBUG_PRINTLN(F("Selecting user bank 16...")); 00313 setMemoryBank(0x10, true, true); 00314 DEBUG_PRINTLN(F("Selecting memory byte 6...")); 00315 setMemoryStartAddress(0x06); 00316 DEBUG_PRINTLN(F("Checking hardware revision...")); 00317 DEBUG_PRINT(F("Revision @ user[16][6] = ")); 00318 DEBUG_PRINTLNF(readMemoryByte(), HEX); 00319 DEBUG_PRINTLN(F("Resetting memory bank selection to 0...")); 00320 setMemoryBank(0, false, false); 00321 00322 // check OTP bank valid 00323 DEBUG_PRINTLN(F("Reading OTP bank valid flag...")); 00324 DEBUG_PRINT(F("OTP bank is ")); 00325 DEBUG_PRINTLN(getOTPBankValid() ? F("valid!") : F("invalid!")); 00326 00327 // get X/Y/Z gyro offsets 00328 DEBUG_PRINTLN(F("Reading gyro offset TC values...")); 00329 int8_t xgOffsetTC = getXGyroOffsetTC(); 00330 int8_t ygOffsetTC = getYGyroOffsetTC(); 00331 int8_t zgOffsetTC = getZGyroOffsetTC(); 00332 DEBUG_PRINT(F("X gyro offset = ")); 00333 DEBUG_PRINTLN(xgOffsetTC); 00334 DEBUG_PRINT(F("Y gyro offset = ")); 00335 DEBUG_PRINTLN(ygOffsetTC); 00336 DEBUG_PRINT(F("Z gyro offset = ")); 00337 DEBUG_PRINTLN(zgOffsetTC); 00338 00339 // setup weird slave stuff (?) 00340 DEBUG_PRINTLN(F("Setting slave 0 address to 0x7F...")); 00341 setSlaveAddress(0, 0x7F); 00342 DEBUG_PRINTLN(F("Disabling I2C Master mode...")); 00343 setI2CMasterModeEnabled(false); 00344 DEBUG_PRINTLN(F("Setting slave 0 address to 0x68 (self)...")); 00345 setSlaveAddress(0, 0x68); 00346 DEBUG_PRINTLN(F("Resetting I2C Master control...")); 00347 resetI2CMaster(); 00348 wait_ms(20); 00349 00350 // load DMP code into memory banks 00351 DEBUG_PRINT(F("Writing DMP code to MPU memory banks (")); 00352 DEBUG_PRINT(MPU6050_DMP_CODE_SIZE); 00353 DEBUG_PRINTLN(F(" bytes)")); 00354 if (writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) { 00355 DEBUG_PRINTLN(F("Success! DMP code written and verified.")); 00356 00357 // write DMP configuration 00358 DEBUG_PRINT(F("Writing DMP configuration to MPU memory banks (")); 00359 DEBUG_PRINT(MPU6050_DMP_CONFIG_SIZE); 00360 DEBUG_PRINTLN(F(" bytes in config def)")); 00361 if (writeProgDMPConfigurationSet(dmpConfig, MPU6050_DMP_CONFIG_SIZE)) { 00362 DEBUG_PRINTLN(F("Success! DMP configuration written and verified.")); 00363 00364 DEBUG_PRINTLN(F("Setting clock source to Z Gyro...")); 00365 setClockSource(MPU6050_CLOCK_PLL_ZGYRO); 00366 00367 DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled...")); 00368 setIntEnabled(0x12); 00369 00370 DEBUG_PRINTLN(F("Setting sample rate to 200Hz...")); 00371 setRate(4); // 1khz / (1 + 4) = 200 Hz 00372 00373 DEBUG_PRINTLN(F("Setting external frame sync to TEMP_OUT_L[0]...")); 00374 setExternalFrameSync(MPU6050_EXT_SYNC_TEMP_OUT_L); 00375 00376 DEBUG_PRINTLN(F("Setting DLPF bandwidth to 42Hz...")); 00377 setDLPFMode(MPU6050_DLPF_BW_42); 00378 00379 DEBUG_PRINTLN(F("Setting gyro sensitivity to +/- 2000 deg/sec...")); 00380 setFullScaleGyroRange(MPU6050_GYRO_FS_2000); 00381 00382 DEBUG_PRINTLN(F("Setting DMP configuration bytes (function unknown)...")); 00383 setDMPConfig1(0x03); 00384 setDMPConfig2(0x00); 00385 00386 DEBUG_PRINTLN(F("Clearing OTP Bank flag...")); 00387 setOTPBankValid(false); 00388 00389 DEBUG_PRINTLN(F("Setting X/Y/Z gyro offset TCs to previous values...")); 00390 setXGyroOffsetTC(xgOffsetTC); 00391 setYGyroOffsetTC(ygOffsetTC); 00392 setZGyroOffsetTC(zgOffsetTC); 00393 00394 //DEBUG_PRINTLN(F("Setting X/Y/Z gyro user offsets to zero...")); 00395 //setXGyroOffset(0); 00396 //setYGyroOffset(0); 00397 //setZGyroOffset(0); 00398 00399 DEBUG_PRINTLN(F("Writing final memory update 1/7 (function unknown)...")); 00400 uint8_t dmpUpdate[16], j; 00401 uint16_t pos = 0; 00402 for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); 00403 writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); 00404 00405 DEBUG_PRINTLN(F("Writing final memory update 2/7 (function unknown)...")); 00406 for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); 00407 writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); 00408 00409 DEBUG_PRINTLN(F("Resetting FIFO...")); 00410 resetFIFO(); 00411 00412 DEBUG_PRINTLN(F("Reading FIFO count...")); 00413 uint16_t fifoCount = getFIFOCount(); 00414 uint8_t fifoBuffer[128]; 00415 00416 DEBUG_PRINT(F("Current FIFO count=")); 00417 DEBUG_PRINTLN(fifoCount); 00418 getFIFOBytes(fifoBuffer, fifoCount); 00419 00420 DEBUG_PRINTLN(F("Setting motion detection threshold to 2...")); 00421 setMotionDetectionThreshold(2); 00422 00423 DEBUG_PRINTLN(F("Setting zero-motion detection threshold to 156...")); 00424 setZeroMotionDetectionThreshold(156); 00425 00426 DEBUG_PRINTLN(F("Setting motion detection duration to 80...")); 00427 setMotionDetectionDuration(80); 00428 00429 DEBUG_PRINTLN(F("Setting zero-motion detection duration to 0...")); 00430 setZeroMotionDetectionDuration(0); 00431 00432 DEBUG_PRINTLN(F("Resetting FIFO...")); 00433 resetFIFO(); 00434 00435 DEBUG_PRINTLN(F("Enabling FIFO...")); 00436 setFIFOEnabled(true); 00437 00438 DEBUG_PRINTLN(F("Enabling DMP...")); 00439 setDMPEnabled(true); 00440 00441 DEBUG_PRINTLN(F("Resetting DMP...")); 00442 resetDMP(); 00443 00444 DEBUG_PRINTLN(F("Writing final memory update 3/7 (function unknown)...")); 00445 for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); 00446 writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); 00447 00448 DEBUG_PRINTLN(F("Writing final memory update 4/7 (function unknown)...")); 00449 for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); 00450 writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); 00451 00452 DEBUG_PRINTLN(F("Writing final memory update 5/7 (function unknown)...")); 00453 for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); 00454 writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); 00455 00456 DEBUG_PRINTLN(F("Waiting for FIFO count > 2...")); 00457 while ((fifoCount = getFIFOCount()) < 3); 00458 00459 DEBUG_PRINT(F("Current FIFO count=")); 00460 DEBUG_PRINTLN(fifoCount); 00461 DEBUG_PRINTLN(F("Reading FIFO data...")); 00462 getFIFOBytes(fifoBuffer, fifoCount); 00463 00464 DEBUG_PRINTLN(F("Reading interrupt status...")); 00465 00466 DEBUG_PRINT(F("Current interrupt status=")); 00467 DEBUG_PRINTLNF(getIntStatus(), HEX); 00468 00469 DEBUG_PRINTLN(F("Reading final memory update 6/7 (function unknown)...")); 00470 for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); 00471 readMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); 00472 00473 DEBUG_PRINTLN(F("Waiting for FIFO count > 2...")); 00474 while ((fifoCount = getFIFOCount()) < 3); 00475 00476 DEBUG_PRINT(F("Current FIFO count=")); 00477 DEBUG_PRINTLN(fifoCount); 00478 00479 DEBUG_PRINTLN(F("Reading FIFO data...")); 00480 getFIFOBytes(fifoBuffer, fifoCount); 00481 00482 DEBUG_PRINTLN(F("Reading interrupt status...")); 00483 00484 DEBUG_PRINT(F("Current interrupt status=")); 00485 DEBUG_PRINTLNF(getIntStatus(), HEX); 00486 00487 DEBUG_PRINTLN(F("Writing final memory update 7/7 (function unknown)...")); 00488 for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); 00489 writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); 00490 00491 DEBUG_PRINTLN(F("DMP is good to go! Finally.")); 00492 00493 DEBUG_PRINTLN(F("Disabling DMP (you turn it on later)...")); 00494 setDMPEnabled(false); 00495 00496 DEBUG_PRINTLN(F("Setting up internal 42-byte (default) DMP packet buffer...")); 00497 dmpPacketSize = 42; 00498 /*if ((dmpPacketBuffer = (uint8_t *)malloc(42)) == 0) { 00499 return 3; // TODO: proper error code for no memory 00500 }*/ 00501 00502 DEBUG_PRINTLN(F("Resetting FIFO and clearing INT status one last time...")); 00503 resetFIFO(); 00504 getIntStatus(); 00505 } else { 00506 DEBUG_PRINTLN(F("ERROR! DMP configuration verification failed.")); 00507 return 2; // configuration block loading failed 00508 } 00509 } else { 00510 DEBUG_PRINTLN(F("ERROR! DMP code verification failed.")); 00511 return 1; // main binary block loading failed 00512 } 00513 return 0; // success 00514 } 00515 00516 bool MPU6050::dmpPacketAvailable() { 00517 return getFIFOCount() >= dmpGetFIFOPacketSize(); 00518 } 00519 00520 // uint8_t MPU6050::dmpSetFIFORate(uint8_t fifoRate); 00521 // uint8_t MPU6050::dmpGetFIFORate(); 00522 // uint8_t MPU6050::dmpGetSampleStepSizeMS(); 00523 // uint8_t MPU6050::dmpGetSampleFrequency(); 00524 // int32_t MPU6050::dmpDecodeTemperature(int8_t tempReg); 00525 00526 //uint8_t MPU6050::dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); 00527 //uint8_t MPU6050::dmpUnregisterFIFORateProcess(inv_obj_func func); 00528 //uint8_t MPU6050::dmpRunFIFORateProcesses(); 00529 00530 // uint8_t MPU6050::dmpSendQuaternion(uint_fast16_t accuracy); 00531 // uint8_t MPU6050::dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); 00532 // uint8_t MPU6050::dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); 00533 // uint8_t MPU6050::dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); 00534 // uint8_t MPU6050::dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); 00535 // uint8_t MPU6050::dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); 00536 // uint8_t MPU6050::dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); 00537 // uint8_t MPU6050::dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); 00538 // uint8_t MPU6050::dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); 00539 // uint8_t MPU6050::dmpSendPacketNumber(uint_fast16_t accuracy); 00540 // uint8_t MPU6050::dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); 00541 // uint8_t MPU6050::dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); 00542 00543 uint8_t MPU6050::dmpGetAccel(int32_t *data, const uint8_t* packet) { 00544 // TODO: accommodate different arrangements of sent data (ONLY default supported now) 00545 if (packet == 0) packet = dmpPacketBuffer; 00546 data[0] = (((uint32_t)packet[28] << 24) | ((uint32_t)packet[29] << 16) | ((uint32_t)packet[30] << 8) | packet[31]); 00547 data[1] = (((uint32_t)packet[32] << 24) | ((uint32_t)packet[33] << 16) | ((uint32_t)packet[34] << 8) | packet[35]); 00548 data[2] = (((uint32_t)packet[36] << 24) | ((uint32_t)packet[37] << 16) | ((uint32_t)packet[38] << 8) | packet[39]); 00549 return 0; 00550 } 00551 uint8_t MPU6050::dmpGetAccel(int16_t *data, const uint8_t* packet) { 00552 // TODO: accommodate different arrangements of sent data (ONLY default supported now) 00553 if (packet == 0) packet = dmpPacketBuffer; 00554 data[0] = (packet[28] << 8) | packet[29]; 00555 data[1] = (packet[32] << 8) | packet[33]; 00556 data[2] = (packet[36] << 8) | packet[37]; 00557 return 0; 00558 } 00559 uint8_t MPU6050::dmpGetAccel(VectorInt16 *v, const uint8_t* packet) { 00560 // TODO: accommodate different arrangements of sent data (ONLY default supported now) 00561 if (packet == 0) packet = dmpPacketBuffer; 00562 v -> x = (packet[28] << 8) | packet[29]; 00563 v -> y = (packet[32] << 8) | packet[33]; 00564 v -> z = (packet[36] << 8) | packet[37]; 00565 return 0; 00566 } 00567 uint8_t MPU6050::dmpGetQuaternion(int32_t *data, const uint8_t* packet) { 00568 // TODO: accommodate different arrangements of sent data (ONLY default supported now) 00569 if (packet == 0) packet = dmpPacketBuffer; 00570 data[0] = (((uint32_t)packet[0] << 24) | ((uint32_t)packet[1] << 16) | ((uint32_t)packet[2] << 8) | packet[3]); 00571 data[1] = (((uint32_t)packet[4] << 24) | ((uint32_t)packet[5] << 16) | ((uint32_t)packet[6] << 8) | packet[7]); 00572 data[2] = (((uint32_t)packet[8] << 24) | ((uint32_t)packet[9] << 16) | ((uint32_t)packet[10] << 8) | packet[11]); 00573 data[3] = (((uint32_t)packet[12] << 24) | ((uint32_t)packet[13] << 16) | ((uint32_t)packet[14] << 8) | packet[15]); 00574 return 0; 00575 } 00576 uint8_t MPU6050::dmpGetQuaternion(int16_t *data, const uint8_t* packet) { 00577 // TODO: accommodate different arrangements of sent data (ONLY default supported now) 00578 if (packet == 0) packet = dmpPacketBuffer; 00579 data[0] = ((packet[0] << 8) | packet[1]); 00580 data[1] = ((packet[4] << 8) | packet[5]); 00581 data[2] = ((packet[8] << 8) | packet[9]); 00582 data[3] = ((packet[12] << 8) | packet[13]); 00583 return 0; 00584 } 00585 uint8_t MPU6050::dmpGetQuaternion(Quaternion *q, const uint8_t* packet) { 00586 // TODO: accommodate different arrangements of sent data (ONLY default supported now) 00587 int16_t qI[4]; 00588 uint8_t status = dmpGetQuaternion(qI, packet); 00589 if (status == 0) { 00590 q -> w = (float)qI[0] / 16384.0f; 00591 q -> x = (float)qI[1] / 16384.0f; 00592 q -> y = (float)qI[2] / 16384.0f; 00593 q -> z = (float)qI[3] / 16384.0f; 00594 return 0; 00595 } 00596 return status; // int16 return value, indicates error if this line is reached 00597 } 00598 // uint8_t MPU6050::dmpGet6AxisQuaternion(long *data, const uint8_t* packet); 00599 // uint8_t MPU6050::dmpGetRelativeQuaternion(long *data, const uint8_t* packet); 00600 uint8_t MPU6050::dmpGetGyro(int32_t *data, const uint8_t* packet) { 00601 // TODO: accommodate different arrangements of sent data (ONLY default supported now) 00602 if (packet == 0) packet = dmpPacketBuffer; 00603 data[0] = (((uint32_t)packet[16] << 24) | ((uint32_t)packet[17] << 16) | ((uint32_t)packet[18] << 8) | packet[19]); 00604 data[1] = (((uint32_t)packet[20] << 24) | ((uint32_t)packet[21] << 16) | ((uint32_t)packet[22] << 8) | packet[23]); 00605 data[2] = (((uint32_t)packet[24] << 24) | ((uint32_t)packet[25] << 16) | ((uint32_t)packet[26] << 8) | packet[27]); 00606 return 0; 00607 } 00608 uint8_t MPU6050::dmpGetGyro(int16_t *data, const uint8_t* packet) { 00609 // TODO: accommodate different arrangements of sent data (ONLY default supported now) 00610 if (packet == 0) packet = dmpPacketBuffer; 00611 data[0] = (packet[16] << 8) | packet[17]; 00612 data[1] = (packet[20] << 8) | packet[21]; 00613 data[2] = (packet[24] << 8) | packet[25]; 00614 return 0; 00615 } 00616 uint8_t MPU6050::dmpGetGyro(VectorInt16 *v, const uint8_t* packet) { 00617 // TODO: accommodate different arrangements of sent data (ONLY default supported now) 00618 if (packet == 0) packet = dmpPacketBuffer; 00619 v -> x = (packet[16] << 8) | packet[17]; 00620 v -> y = (packet[20] << 8) | packet[21]; 00621 v -> z = (packet[24] << 8) | packet[25]; 00622 return 0; 00623 } 00624 // uint8_t MPU6050::dmpSetLinearAccelFilterCoefficient(float coef); 00625 // uint8_t MPU6050::dmpGetLinearAccel(long *data, const uint8_t* packet); 00626 uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) { 00627 // get rid of the gravity component (+1g = +8192 in standard DMP FIFO packet, sensitivity is 2g) 00628 v -> x = vRaw -> x - gravity -> x*8192; 00629 v -> y = vRaw -> y - gravity -> y*8192; 00630 v -> z = vRaw -> z - gravity -> z*8192; 00631 return 0; 00632 } 00633 // uint8_t MPU6050::dmpGetLinearAccelInWorld(long *data, const uint8_t* packet); 00634 uint8_t MPU6050::dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q) { 00635 // rotate measured 3D acceleration vector into original state 00636 // frame of reference based on orientation quaternion 00637 memcpy(v, vReal, sizeof(VectorInt16)); 00638 v -> rotate(q); 00639 return 0; 00640 } 00641 // uint8_t MPU6050::dmpGetGyroAndAccelSensor(long *data, const uint8_t* packet); 00642 // uint8_t MPU6050::dmpGetGyroSensor(long *data, const uint8_t* packet); 00643 // uint8_t MPU6050::dmpGetControlData(long *data, const uint8_t* packet); 00644 // uint8_t MPU6050::dmpGetTemperature(long *data, const uint8_t* packet); 00645 // uint8_t MPU6050::dmpGetGravity(long *data, const uint8_t* packet); 00646 uint8_t MPU6050::dmpGetGravity(VectorFloat *v, Quaternion *q) { 00647 v -> x = 2 * (q -> x*q -> z - q -> w*q -> y); 00648 v -> y = 2 * (q -> w*q -> x + q -> y*q -> z); 00649 v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z; 00650 return 0; 00651 } 00652 // uint8_t MPU6050::dmpGetUnquantizedAccel(long *data, const uint8_t* packet); 00653 // uint8_t MPU6050::dmpGetQuantizedAccel(long *data, const uint8_t* packet); 00654 // uint8_t MPU6050::dmpGetExternalSensorData(long *data, int size, const uint8_t* packet); 00655 // uint8_t MPU6050::dmpGetEIS(long *data, const uint8_t* packet); 00656 00657 uint8_t MPU6050::dmpGetEuler(float *data, Quaternion *q) { 00658 data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); // psi 00659 data[1] = -asin(2*q -> x*q -> z + 2*q -> w*q -> y); // theta 00660 data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1); // phi 00661 return 0; 00662 } 00663 uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { 00664 // yaw: (about Z axis) 00665 data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); 00666 // pitch: (nose up/down, about Y axis) 00667 data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); 00668 // roll: (tilt left/right, about X axis) 00669 data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z)); 00670 return 0; 00671 } 00672 00673 // uint8_t MPU6050::dmpGetAccelFloat(float *data, const uint8_t* packet); 00674 // uint8_t MPU6050::dmpGetQuaternionFloat(float *data, const uint8_t* packet); 00675 00676 uint8_t MPU6050::dmpProcessFIFOPacket(const unsigned char *dmpData) { 00677 /*for (uint8_t k = 0; k < dmpPacketSize; k++) { 00678 if (dmpData[k] < 0x10) Serial.print("0"); 00679 Serial.print(dmpData[k], HEX); 00680 Serial.print(" "); 00681 } 00682 Serial.print("\n");*/ 00683 //Serial.println((uint16_t)dmpPacketBuffer); 00684 return 0; 00685 } 00686 uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed) { 00687 uint8_t status; 00688 uint8_t buf[dmpPacketSize]; 00689 for (uint8_t i = 0; i < numPackets; i++) { 00690 // read packet from FIFO 00691 getFIFOBytes(buf, dmpPacketSize); 00692 00693 // process packet 00694 if ((status = dmpProcessFIFOPacket(buf)) > 0) return status; 00695 00696 // increment external process count variable, if supplied 00697 if (processed != 0) (*processed)++; 00698 } 00699 return 0; 00700 } 00701 00702 // uint8_t MPU6050::dmpSetFIFOProcessedCallback(void (*func) (void)); 00703 00704 // uint8_t MPU6050::dmpInitFIFOParam(); 00705 // uint8_t MPU6050::dmpCloseFIFO(); 00706 // uint8_t MPU6050::dmpSetGyroDataSource(uint_fast8_t source); 00707 // uint8_t MPU6050::dmpDecodeQuantizedAccel(); 00708 // uint32_t MPU6050::dmpGetGyroSumOfSquare(); 00709 // uint32_t MPU6050::dmpGetAccelSumOfSquare(); 00710 // void MPU6050::dmpOverrideQuaternion(long *q); 00711 uint16_t MPU6050::dmpGetFIFOPacketSize() { 00712 return dmpPacketSize; 00713 } 00714 00715 #endif /* _MPU6050_6AXIS_MOTIONAPPS20_H_ */
Generated on Wed Jul 13 2022 10:26:09 by
