Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MPU9255.cpp
00001 #include"MPU9255.h" 00002 00003 //----------------- 00004 //private functions 00005 //----------------- 00006 00007 void MPU9255::writeByte(uint8_t address, uint8_t subAddress, uint8_t data) 00008 { 00009 char data_write[2]; 00010 data_write[0] = subAddress; 00011 data_write[1] = data; 00012 i2c.write(address, data_write, 2, 0); 00013 } 00014 00015 char MPU9255::readByte(uint8_t address, uint8_t subAddress) 00016 { 00017 char data[1]; // `data` will store the register data 00018 char data_write[1]; 00019 data_write[0] = subAddress; 00020 i2c.write(address, data_write, 1, 1); // no stop 00021 i2c.read(address, data, 1, 0); 00022 return data[0]; 00023 } 00024 00025 void MPU9255::readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest) 00026 { 00027 char data[14]; 00028 char data_write[1]; 00029 data_write[0] = subAddress; 00030 i2c.write(address, data_write, 1, 1); // no stop 00031 i2c.read(address, data, count, 0); 00032 for(int ii = 0; ii < count; ii++) 00033 { 00034 dest[ii] = data[ii]; 00035 } 00036 } 00037 00038 00039 //---------------- 00040 //public functions 00041 //---------------- 00042 00043 MPU9255::MPU9255(PinName sda, PinName scl, RawSerial* serial_p) 00044 : i2c_p(new I2C(sda,scl)), i2c(*i2c_p), pc_p(serial_p) 00045 { 00046 i2c.frequency(40000); 00047 } 00048 00049 MPU9255::~MPU9255() {} 00050 00051 uint8_t MPU9255::whoami_mpu9255() 00052 { 00053 uint8_t a = readByte(MPU9255_ADDRESS, WHO_AM_I_MPU9255); 00054 return a; 00055 } 00056 00057 void MPU9255::reset_mpu9255() 00058 { 00059 writeByte(MPU9255_ADDRESS, PWR_MGMT_1, 0x80); 00060 wait_ms(10); 00061 } 00062 00063 void MPU9255::selftest_mpu9255(float * destination) // Should return percent deviation from factory trim values, +/- 14 or less deviation is a pass 00064 { 00065 uint8_t rawData[6] = {0, 0, 0, 0, 0, 0}; 00066 uint8_t selfTest[6]; 00067 int32_t gAvg[3] = {0}, aAvg[3] = {0}, aSTAvg[3] = {0}, gSTAvg[3] = {0}; 00068 float factoryTrim[6]; 00069 uint8_t FS = 0; 00070 00071 writeByte(MPU9255_ADDRESS, SMPLRT_DIV, 0x00); // Set gyro sample rate to 1 kHz 00072 writeByte(MPU9255_ADDRESS, CONFIG, 0x02); // Set gyro sample rate to 1 kHz and DLPF to 92 Hz 00073 writeByte(MPU9255_ADDRESS, GYRO_CONFIG, 1<<FS); // Set full scale range for the gyro to 250 dps 00074 writeByte(MPU9255_ADDRESS, ACCEL_CONFIG2, 0x02); // Set accelerometer rate to 1 kHz and bandwidth to 92 Hz 00075 writeByte(MPU9255_ADDRESS, ACCEL_CONFIG, 1<<FS); // Set full scale range for the accelerometer to 2 g 00076 00077 for( int ii = 0; ii < 200; ii++) // get average current values of gyro and acclerometer 00078 { 00079 readBytes(MPU9255_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]); // Read the six raw data registers into data array 00080 aAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value 00081 aAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ; 00082 aAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ; 00083 00084 readBytes(MPU9255_ADDRESS, GYRO_XOUT_H, 6, &rawData[0]); // Read the six raw data registers sequentially into data array 00085 gAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value 00086 gAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ; 00087 gAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ; 00088 } 00089 00090 for (int ii =0; ii < 3; ii++) // Get average of 200 values and store as average current readings 00091 { 00092 aAvg[ii] /= 200; 00093 gAvg[ii] /= 200; 00094 } 00095 00096 // Configure the accelerometer for self-test 00097 writeByte(MPU9255_ADDRESS, ACCEL_CONFIG, 0xE0); // Enable self test on all three axes and set accelerometer range to +/- 2 g 00098 writeByte(MPU9255_ADDRESS, GYRO_CONFIG, 0xE0); // Enable self test on all three axes and set gyro range to +/- 250 degrees/s 00099 wait_ms(25); // Delay a while to let the device stabilize 00100 00101 for( int ii = 0; ii < 200; ii++) // get average self-test values of gyro and acclerometer 00102 { 00103 readBytes(MPU9255_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]); // Read the six raw data registers into data array 00104 aSTAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value 00105 aSTAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ; 00106 aSTAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ; 00107 00108 readBytes(MPU9255_ADDRESS, GYRO_XOUT_H, 6, &rawData[0]); // Read the six raw data registers sequentially into data array 00109 gSTAvg[0] += (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ; // Turn the MSB and LSB into a signed 16-bit value 00110 gSTAvg[1] += (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ; 00111 gSTAvg[2] += (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ; 00112 } 00113 00114 for (int ii =0; ii < 3; ii++) // Get average of 200 values and store as average self-test readings 00115 { 00116 aSTAvg[ii] /= 200; 00117 gSTAvg[ii] /= 200; 00118 } 00119 00120 // Configure the gyro and accelerometer for normal operation 00121 writeByte(MPU9255_ADDRESS, ACCEL_CONFIG, 0x00); 00122 writeByte(MPU9255_ADDRESS, GYRO_CONFIG, 0x00); 00123 wait_ms(25); // Delay a while to let the device stabilize 00124 00125 // Retrieve accelerometer and gyro factory Self-Test Code from USR_Reg 00126 selfTest[0] = readByte(MPU9255_ADDRESS, SELF_TEST_X_ACCEL); // X-axis accel self-test results 00127 selfTest[1] = readByte(MPU9255_ADDRESS, SELF_TEST_Y_ACCEL); // Y-axis accel self-test results 00128 selfTest[2] = readByte(MPU9255_ADDRESS, SELF_TEST_Z_ACCEL); // Z-axis accel self-test results 00129 selfTest[3] = readByte(MPU9255_ADDRESS, SELF_TEST_X_GYRO); // X-axis gyro self-test results 00130 selfTest[4] = readByte(MPU9255_ADDRESS, SELF_TEST_Y_GYRO); // Y-axis gyro self-test results 00131 selfTest[5] = readByte(MPU9255_ADDRESS, SELF_TEST_Z_GYRO); // Z-axis gyro self-test results 00132 00133 // Retrieve factory self-test value from self-test code reads 00134 factoryTrim[0] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[0] - 1.0) )); // FT[Xa] factory trim calculation 00135 factoryTrim[1] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[1] - 1.0) )); // FT[Ya] factory trim calculation 00136 factoryTrim[2] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[2] - 1.0) )); // FT[Za] factory trim calculation 00137 factoryTrim[3] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[3] - 1.0) )); // FT[Xg] factory trim calculation 00138 factoryTrim[4] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[4] - 1.0) )); // FT[Yg] factory trim calculation 00139 factoryTrim[5] = (float)(2620/1<<FS)*(pow( 1.01 , ((float)selfTest[5] - 1.0) )); // FT[Zg] factory trim calculation 00140 00141 // Report results as a ratio of (STR - FT)/FT; the change from Factory Trim of the Self-Test Response 00142 // To get percent, must multiply by 100 00143 for (int i = 0; i < 3; i++) 00144 { 00145 destination[i] = 100.0f*((float)(aSTAvg[i] - aAvg[i]))/factoryTrim[i] - 100.0f; // Report percent differences 00146 destination[i+3] = 100.0f*((float)(gSTAvg[i] - gAvg[i]))/factoryTrim[i+3] - 100.0f; // Report percent differences 00147 } 00148 00149 } 00150 00151 float MPU9255::getMres(uint8_t Mscale) 00152 { 00153 float _mRes; 00154 switch (Mscale) 00155 { 00156 // Possible magnetometer scales (and their register bit settings) are: 00157 // 14 bit resolution (0) and 16 bit resolution (1) 00158 case MFS_14BITS: 00159 _mRes = 10.*4912./8190.; // Proper scale to return milliGauss 00160 return _mRes; 00161 //break; 00162 case MFS_16BITS: 00163 _mRes = 10.*4912./32760.0; // Proper scale to return milliGauss (4912/32760=0.15) 00164 return _mRes; // convert 'μT' to 'mG' 00165 //break; 00166 } 00167 } 00168 00169 float MPU9255::getGres(uint8_t Gscale) 00170 { 00171 float _gRes; 00172 switch (Gscale) 00173 { 00174 // Possible gyro scales (and their register bit settings) are: 00175 // 250 DPS (00), 500 DPS (01), 1000 DPS (10), and 2000 DPS (11). 00176 case GFS_250DPS: 00177 _gRes = 250.0/32768.0; 00178 return _gRes; 00179 //break; 00180 case GFS_500DPS: 00181 _gRes = 500.0/32768.0; 00182 return _gRes; 00183 //break; 00184 case GFS_1000DPS: 00185 _gRes = 1000.0/32768.0; 00186 return _gRes; 00187 //break; 00188 case GFS_2000DPS: 00189 _gRes = 2000.0/32768.0; 00190 return _gRes; 00191 //break; 00192 } 00193 } 00194 00195 float MPU9255::getAres(uint8_t Ascale) 00196 { 00197 float _aRes; 00198 switch (Ascale) 00199 { 00200 // Possible accelerometer scales (and their register bit settings) are: 00201 // 2 Gs (00), 4 Gs (01), 8 Gs (10), and 16 Gs (11). 00202 // Here's a bit of an algorith to calculate DPS/(ADC tick) based on that 2-bit value: 00203 case AFS_2G: 00204 _aRes = 2.0f/32768.0f; 00205 return _aRes; 00206 //break; 00207 case AFS_4G: 00208 _aRes = 4.0f/32768.0f; 00209 return _aRes; 00210 //break; 00211 case AFS_8G: 00212 _aRes = 8.0f/32768.0f; 00213 return _aRes; 00214 //break; 00215 case AFS_16G: 00216 _aRes = 16.0f/32768.0f; 00217 return _aRes; 00218 //break; 00219 } 00220 } 00221 00222 void MPU9255::calibrate_mpu9255(float * dest1, float * dest2) 00223 { 00224 uint8_t data[12]; // data array to hold accelerometer and gyro x, y, z, data 00225 uint16_t ii, packet_count, fifo_count; 00226 int32_t gyro_bias[3] = {0, 0, 0}, accel_bias[3] = {0, 0, 0}; 00227 00228 // reset device 00229 writeByte(MPU9255_ADDRESS, PWR_MGMT_1, 0x80); // Write a one to bit 7 reset bit; toggle reset device 00230 wait_ms(100); 00231 00232 // get stable time source; Auto select clock source to be PLL gyroscope reference if ready 00233 // else use the internal oscillator, bits 2:0 = 001 00234 writeByte(MPU9255_ADDRESS, PWR_MGMT_1, 0x01); 00235 writeByte(MPU9255_ADDRESS, PWR_MGMT_2, 0x00); 00236 wait_ms(200); 00237 00238 // Configure device for bias calculation 00239 writeByte(MPU9255_ADDRESS, INT_ENABLE, 0x00); // Disable all interrupts 00240 writeByte(MPU9255_ADDRESS, FIFO_EN, 0x00); // Disable FIFO 00241 writeByte(MPU9255_ADDRESS, PWR_MGMT_1, 0x00); // Turn on internal clock source 00242 writeByte(MPU9255_ADDRESS, I2C_MST_CTRL, 0x00); // Disable I2C master 00243 writeByte(MPU9255_ADDRESS, USER_CTRL, 0x00); // Disable FIFO and I2C master modes 00244 writeByte(MPU9255_ADDRESS, USER_CTRL, 0x0C); // Reset FIFO and DMP 00245 wait_ms(15); 00246 00247 // Configure MPU6050 gyro and accelerometer for bias calculation 00248 writeByte(MPU9255_ADDRESS, CONFIG, 0x01); // Set low-pass filter to 188 Hz 00249 writeByte(MPU9255_ADDRESS, SMPLRT_DIV, 0x00); // Set sample rate to 1 kHz 00250 writeByte(MPU9255_ADDRESS, GYRO_CONFIG, 0x00); // Set gyro full-scale to 250 degrees per second, maximum sensitivity 00251 writeByte(MPU9255_ADDRESS, ACCEL_CONFIG, 0x00); // Set accelerometer full-scale to 2 g, maximum sensitivity 00252 00253 uint16_t gyrosensitivity = 131; // = 131 LSB/degrees/sec 00254 uint16_t accelsensitivity = 16384; // = 16384 LSB/g 00255 00256 // Configure FIFO to capture accelerometer and gyro data for bias calculation 00257 writeByte(MPU9255_ADDRESS, USER_CTRL, 0x40); // Enable FIFO 00258 writeByte(MPU9255_ADDRESS, FIFO_EN, 0x78); // Enable gyro and accelerometer sensors for FIFO (max size 512 bytes in MPU-9150) 00259 wait_ms(40); // accumulate 40 samples in 40 milliseconds = 480 bytes 00260 00261 // At end of sample accumulation, turn off FIFO sensor read 00262 writeByte(MPU9255_ADDRESS, FIFO_EN, 0x00); // Disable gyro and accelerometer sensors for FIFO 00263 readBytes(MPU9255_ADDRESS, FIFO_COUNTH, 2, &data[0]); // read FIFO sample count 00264 fifo_count = ((uint16_t)data[0] << 8) | data[1]; 00265 packet_count = fifo_count/12;// How many sets of full gyro and accelerometer data for averaging 00266 00267 for (ii = 0; ii < packet_count; ii++) 00268 { 00269 int16_t accel_temp[3] = {0, 0, 0}, gyro_temp[3] = {0, 0, 0}; 00270 readBytes(MPU9255_ADDRESS, FIFO_R_W, 12, &data[0]); // read data for averaging 00271 accel_temp[0] = (int16_t) (((int16_t)data[0] << 8) | data[1] ) ; // Form signed 16-bit integer for each sample in FIFO 00272 accel_temp[1] = (int16_t) (((int16_t)data[2] << 8) | data[3] ) ; 00273 accel_temp[2] = (int16_t) (((int16_t)data[4] << 8) | data[5] ) ; 00274 gyro_temp[0] = (int16_t) (((int16_t)data[6] << 8) | data[7] ) ; 00275 gyro_temp[1] = (int16_t) (((int16_t)data[8] << 8) | data[9] ) ; 00276 gyro_temp[2] = (int16_t) (((int16_t)data[10] << 8) | data[11]) ; 00277 00278 accel_bias[0] += (int32_t) accel_temp[0]; // Sum individual signed 16-bit biases to get accumulated signed 32-bit biases 00279 accel_bias[1] += (int32_t) accel_temp[1]; 00280 accel_bias[2] += (int32_t) accel_temp[2]; 00281 gyro_bias[0] += (int32_t) gyro_temp[0]; 00282 gyro_bias[1] += (int32_t) gyro_temp[1]; 00283 gyro_bias[2] += (int32_t) gyro_temp[2]; 00284 00285 } 00286 00287 accel_bias[0] /= (int32_t) packet_count; // Normalize sums to get average count biases 00288 accel_bias[1] /= (int32_t) packet_count; 00289 accel_bias[2] /= (int32_t) packet_count; 00290 gyro_bias[0] /= (int32_t) packet_count; 00291 gyro_bias[1] /= (int32_t) packet_count; 00292 gyro_bias[2] /= (int32_t) packet_count; 00293 00294 if(accel_bias[2] > 0L) {accel_bias[2] -= (int32_t) accelsensitivity;} // Remove gravity from the z-axis accelerometer bias calculation 00295 else {accel_bias[2] += (int32_t) accelsensitivity;} 00296 00297 // Construct the gyro biases for push to the hardware gyro bias registers, which are reset to zero upon device startup 00298 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 00299 data[1] = (-gyro_bias[0]/4) & 0xFF; // Biases are additive, so change sign on calculated average gyro biases 00300 data[2] = (-gyro_bias[1]/4 >> 8) & 0xFF; 00301 data[3] = (-gyro_bias[1]/4) & 0xFF; 00302 data[4] = (-gyro_bias[2]/4 >> 8) & 0xFF; 00303 data[5] = (-gyro_bias[2]/4) & 0xFF; 00304 00305 // Push gyro biases to hardware registers 00306 writeByte(MPU9255_ADDRESS, XG_OFFSET_H, data[0]); 00307 writeByte(MPU9255_ADDRESS, XG_OFFSET_L, data[1]); 00308 writeByte(MPU9255_ADDRESS, YG_OFFSET_H, data[2]); 00309 writeByte(MPU9255_ADDRESS, YG_OFFSET_L, data[3]); 00310 writeByte(MPU9255_ADDRESS, ZG_OFFSET_H, data[4]); 00311 writeByte(MPU9255_ADDRESS, ZG_OFFSET_L, data[5]); 00312 00313 // Output scaled gyro biases for display in the main program 00314 dest1[0] = (float) gyro_bias[0]/(float) gyrosensitivity; 00315 dest1[1] = (float) gyro_bias[1]/(float) gyrosensitivity; 00316 dest1[2] = (float) gyro_bias[2]/(float) gyrosensitivity; 00317 00318 // Construct the accelerometer biases for push to the hardware accelerometer bias registers. These registers contain 00319 // factory trim values which must be added to the calculated accelerometer biases; on boot up these registers will hold 00320 // non-zero values. In addition, bit 0 of the lower byte must be preserved since it is used for temperature 00321 // compensation calculations. Accelerometer bias registers expect bias input as 2048 LSB per g, so that 00322 // the accelerometer biases calculated above must be divided by 8. 00323 00324 int32_t accel_bias_reg[3] = {0, 0, 0}; // A place to hold the factory accelerometer trim biases 00325 readBytes(MPU9255_ADDRESS, XA_OFFSET_H, 2, &data[0]); // Read factory accelerometer trim values 00326 accel_bias_reg[0] = (int32_t) (((int16_t)data[0] << 8) | data[1]); 00327 readBytes(MPU9255_ADDRESS, YA_OFFSET_H, 2, &data[0]); 00328 accel_bias_reg[1] = (int32_t) (((int16_t)data[0] << 8) | data[1]); 00329 readBytes(MPU9255_ADDRESS, ZA_OFFSET_H, 2, &data[0]); 00330 accel_bias_reg[2] = (int32_t) (((int16_t)data[0] << 8) | data[1]); 00331 00332 uint32_t mask = 1uL; // Define mask for temperature compensation bit 0 of lower byte of accelerometer bias registers 00333 uint8_t mask_bit[3] = {0, 0, 0}; // Define array to hold mask bit for each accelerometer bias axis 00334 00335 for(ii = 0; ii < 3; ii++) 00336 { 00337 if((accel_bias_reg[ii] & mask)) mask_bit[ii] = 0x01; // If temperature compensation bit is set, record that fact in mask_bit 00338 } 00339 00340 // Construct total accelerometer bias, including calculated average accelerometer bias from above 00341 accel_bias_reg[0] -= (accel_bias[0]/8); // Subtract calculated averaged accelerometer bias scaled to 2048 LSB/g (16 g full scale) 00342 accel_bias_reg[1] -= (accel_bias[1]/8); 00343 accel_bias_reg[2] -= (accel_bias[2]/8); 00344 00345 data[0] = (accel_bias_reg[0] >> 8) & 0xFF; 00346 data[1] = (accel_bias_reg[0]) & 0xFF; 00347 data[1] = data[1] | mask_bit[0]; // preserve temperature compensation bit when writing back to accelerometer bias registers 00348 data[2] = (accel_bias_reg[1] >> 8) & 0xFF; 00349 data[3] = (accel_bias_reg[1]) & 0xFF; 00350 data[3] = data[3] | mask_bit[1]; // preserve temperature compensation bit when writing back to accelerometer bias registers 00351 data[4] = (accel_bias_reg[2] >> 8) & 0xFF; 00352 data[5] = (accel_bias_reg[2]) & 0xFF; 00353 data[5] = data[5] | mask_bit[2]; // preserve temperature compensation bit when writing back to accelerometer bias registers 00354 00355 // Apparently this is not working for the acceleration biases in the MPU-9255 00356 // Are we handling the temperature correction bit properly? 00357 // Push accelerometer biases to hardware registers 00358 // writeByte(MPU9255_ADDRESS, XA_OFFSET_H, data[0]); 00359 // writeByte(MPU9255_ADDRESS, XA_OFFSET_L, data[1]); 00360 // writeByte(MPU9255_ADDRESS, YA_OFFSET_H, data[2]); 00361 // writeByte(MPU9255_ADDRESS, YA_OFFSET_L, data[3]); 00362 // writeByte(MPU9255_ADDRESS, ZA_OFFSET_H, data[4]); 00363 // writeByte(MPU9255_ADDRESS, ZA_OFFSET_L, data[5]); 00364 00365 // Output scaled accelerometer biases for display in the main program 00366 dest2[0] = (float)accel_bias[0]/(float)accelsensitivity; 00367 dest2[1] = (float)accel_bias[1]/(float)accelsensitivity; 00368 dest2[2] = (float)accel_bias[2]/(float)accelsensitivity; 00369 } 00370 00371 void MPU9255::init_mpu9255(uint8_t Ascale, uint8_t Gscale, uint8_t sampleRate) 00372 { 00373 // wake up device 00374 writeByte(MPU9255_ADDRESS, PWR_MGMT_1, 0x00); // Clear sleep mode bit (6), enable all sensors 00375 wait_ms(100); // Wait for all registers to reset 00376 00377 // get stable time source 00378 writeByte(MPU9255_ADDRESS, PWR_MGMT_1, 0x01); // Auto select clock source to be PLL gyroscope reference if ready else 00379 wait_ms(200); 00380 00381 // Configure Gyro and Thermometer 00382 // Disable FSYNC and set thermometer and gyro bandwidth to 41 and 42 Hz, respectively; 00383 // minimum delay time for this setting is 5.9 ms, which means sensor fusion update rates cannot 00384 // be higher than 1 / 0.0059 = 170 Hz 00385 // DLPF_CFG = bits 2:0 = 011; this limits the sample rate to 1000 Hz for both 00386 // With the MPU9255, it is possible to get gyro sample rates of 32 kHz (!), 8 kHz, or 1 kHz 00387 writeByte(MPU9255_ADDRESS, CONFIG, 0x03); 00388 00389 // Set sample rate = gyroscope output rate/(1 + SMPLRT_DIV) 00390 writeByte(MPU9255_ADDRESS, SMPLRT_DIV, sampleRate); // Use a 200 Hz rate; a rate consistent with the filter update rate 00391 // determined inset in CONFIG above 00392 00393 // Set gyroscope full scale range 00394 // Range selects FS_SEL and AFS_SEL are 0 - 3, so 2-bit values are left-shifted into positions 4:3 00395 uint8_t c = readByte(MPU9255_ADDRESS, GYRO_CONFIG); // get current GYRO_CONFIG register value 00396 // c = c & ~0xE0; // Clear self-test bits [7:5] 00397 c = c & ~0x02; // Clear Fchoice bits [1:0] 00398 c = c & ~0x18; // Clear AFS bits [4:3] 00399 c = c | Gscale << 3; // Set full scale range for the gyro 00400 // c =| 0x00; // Set Fchoice for the gyro to 11 by writing its inverse to bits 1:0 of GYRO_CONFIG 00401 writeByte(MPU9255_ADDRESS, GYRO_CONFIG, c ); // Write new GYRO_CONFIG value to register 00402 00403 // Set accelerometer full-scale range configuration 00404 c = readByte(MPU9255_ADDRESS, ACCEL_CONFIG); // get current ACCEL_CONFIG register value 00405 // c = c & ~0xE0; // Clear self-test bits [7:5] 00406 c = c & ~0x18; // Clear AFS bits [4:3] 00407 c = c | Ascale << 3; // Set full scale range for the accelerometer 00408 writeByte(MPU9255_ADDRESS, ACCEL_CONFIG, c); // Write new ACCEL_CONFIG register value 00409 00410 // Set accelerometer sample rate configuration 00411 // It is possible to get a 4 kHz sample rate from the accelerometer by choosing 1 for 00412 // accel_fchoice_b bit [3]; in this case the bandwidth is 1.13 kHz 00413 c = readByte(MPU9255_ADDRESS, ACCEL_CONFIG2); // get current ACCEL_CONFIG2 register value 00414 c = c & ~0x0F; // Clear accel_fchoice_b (bit 3) and A_DLPFG (bits [2:0]) 00415 c = c | 0x03; // Set accelerometer rate to 1 kHz and bandwidth to 41 Hz 00416 writeByte(MPU9255_ADDRESS, ACCEL_CONFIG2, c); // Write new ACCEL_CONFIG2 register value 00417 00418 // The accelerometer, gyro, and thermometer are set to 1 kHz sample rates, 00419 // but all these rates are further reduced by a factor of 5 to 200 Hz because of the SMPLRT_DIV setting 00420 00421 // Configure Interrupts and Bypass Enable 00422 // Set interrupt pin active high, push-pull, hold interrupt pin level HIGH until interrupt cleared, 00423 // clear on read of INT_STATUS, and enable I2C_BYPASS_EN so additional chips 00424 // can join the I2C bus and all can be controlled by the Arduino as master 00425 writeByte(MPU9255_ADDRESS, INT_PIN_CFG, 0x10); // INT is 50 microsecond pulse and any read to clear 00426 writeByte(MPU9255_ADDRESS, INT_ENABLE, 0x01); // Enable data ready (bit 0) interrupt 00427 wait_ms(100); 00428 00429 writeByte(MPU9255_ADDRESS, USER_CTRL, 0x20); // Enable I2C Master mode 00430 writeByte(MPU9255_ADDRESS, I2C_MST_CTRL, 0x1D); // I2C configuration STOP after each transaction, master I2C bus at 400 KHz 00431 writeByte(MPU9255_ADDRESS, I2C_MST_DELAY_CTRL, 0x81); // Use blocking data retreival and enable delay for mag sample rate mismatch 00432 writeByte(MPU9255_ADDRESS, I2C_SLV4_CTRL, 0x01); // Delay mag data retrieval to once every other accel/gyro data sample 00433 } 00434 00435 00436 uint8_t MPU9255::get_AK8963CID() 00437 { 00438 writeByte(MPU9255_ADDRESS, USER_CTRL, 0x20); // Enable I2C Master mode 00439 writeByte(MPU9255_ADDRESS, I2C_MST_CTRL, 0x0D); // I2C configuration multi-master I2C 400KHz 00440 00441 writeByte(MPU9255_ADDRESS, I2C_SLV0_ADDR, AK8963_ADDRESS | 0x80); // Set the I2C slave address of AK8963 and set for read. 00442 writeByte(MPU9255_ADDRESS, I2C_SLV0_REG, WHO_AM_I_AK8963); // I2C slave 0 register address from where to begin data transfer 00443 writeByte(MPU9255_ADDRESS, I2C_SLV0_CTRL, 0x81); // Enable I2C and transfer 1 byte 00444 wait_ms(10); 00445 uint8_t c = readByte(MPU9255_ADDRESS, EXT_SENS_DATA_00); // Read the WHO_AM_I byte 00446 return c; 00447 } 00448 00449 void MPU9255::init_AK8963Slave(uint8_t Mscale, uint8_t Mmode, float * magCalibration) 00450 { 00451 // First extract the factory calibration for each magnetometer axis 00452 uint8_t rawData[3]; // x/y/z gyro calibration data stored here 00453 00454 writeByte(MPU9255_ADDRESS, I2C_SLV0_ADDR, AK8963_ADDRESS); // Set the I2C slave address of AK8963 and set for write. 00455 writeByte(MPU9255_ADDRESS, I2C_SLV0_REG, AK8963_CNTL2); // I2C slave 0 register address from where to begin data transfer 00456 writeByte(MPU9255_ADDRESS, I2C_SLV0_DO, 0x01); // Reset AK8963 00457 writeByte(MPU9255_ADDRESS, I2C_SLV0_CTRL, 0x81); // Enable I2C and write 1 byte 00458 wait_ms(50); 00459 writeByte(MPU9255_ADDRESS, I2C_SLV0_ADDR, AK8963_ADDRESS); // Set the I2C slave address of AK8963 and set for write. 00460 writeByte(MPU9255_ADDRESS, I2C_SLV0_REG, AK8963_CNTL); // I2C slave 0 register address from where to begin data transfer 00461 writeByte(MPU9255_ADDRESS, I2C_SLV0_DO, 0x00); // Power down magnetometer 00462 writeByte(MPU9255_ADDRESS, I2C_SLV0_CTRL, 0x81); // Enable I2C and write 1 byte 00463 wait_ms(50); 00464 writeByte(MPU9255_ADDRESS, I2C_SLV0_ADDR, AK8963_ADDRESS); // Set the I2C slave address of AK8963 and set for write. 00465 writeByte(MPU9255_ADDRESS, I2C_SLV0_REG, AK8963_CNTL); // I2C slave 0 register address from where to begin data transfer 00466 writeByte(MPU9255_ADDRESS, I2C_SLV0_DO, 0x0F); // Enter fuze mode 00467 writeByte(MPU9255_ADDRESS, I2C_SLV0_CTRL, 0x81); // Enable I2C and write 1 byte 00468 wait_ms(50); 00469 00470 writeByte(MPU9255_ADDRESS, I2C_SLV0_ADDR, AK8963_ADDRESS | 0x80); // Set the I2C slave address of AK8963 and set for read. 00471 writeByte(MPU9255_ADDRESS, I2C_SLV0_REG, AK8963_ASAX); // I2C slave 0 register address from where to begin data transfer 00472 writeByte(MPU9255_ADDRESS, I2C_SLV0_CTRL, 0x83); // Enable I2C and read 3 bytes 00473 wait_ms(50); 00474 readBytes(MPU9255_ADDRESS, EXT_SENS_DATA_00, 3, &rawData[0]); // Read the x-, y-, and z-axis calibration values 00475 magCalibration[0] = (float)(rawData[0] - 128)/256.0f + 1.0f; // Return x-axis sensitivity adjustment values, etc. 00476 magCalibration[1] = (float)(rawData[1] - 128)/256.0f + 1.0f; 00477 magCalibration[2] = (float)(rawData[2] - 128)/256.0f + 1.0f; 00478 /*_magCalibration[0] = magCalibration[0]; 00479 _magCalibration[1] = magCalibration[1]; 00480 _magCalibration[2] = magCalibration[2]; 00481 _Mmode = Mmode;*/ 00482 00483 writeByte(MPU9255_ADDRESS, I2C_SLV0_ADDR, AK8963_ADDRESS); // Set the I2C slave address of AK8963 and set for write. 00484 writeByte(MPU9255_ADDRESS, I2C_SLV0_REG, AK8963_CNTL); // I2C slave 0 register address from where to begin data transfer 00485 writeByte(MPU9255_ADDRESS, I2C_SLV0_DO, 0x00); // Power down magnetometer 00486 writeByte(MPU9255_ADDRESS, I2C_SLV0_CTRL, 0x81); // Enable I2C and transfer 1 byte 00487 wait_ms(50); 00488 00489 writeByte(MPU9255_ADDRESS, I2C_SLV0_ADDR, AK8963_ADDRESS); // Set the I2C slave address of AK8963 and set for write. 00490 writeByte(MPU9255_ADDRESS, I2C_SLV0_REG, AK8963_CNTL); // I2C slave 0 register address from where to begin data transfer 00491 // Configure the magnetometer for continuous read and highest resolution 00492 // set Mscale bit 4 to 1 (0) to enable 16 (14) bit resolution in CNTL register, 00493 // and enable continuous mode data acquisition Mmode (bits [3:0]), 0010 for 8 Hz and 0110 for 100 Hz sample rates 00494 writeByte(MPU9255_ADDRESS, I2C_SLV0_DO, Mscale << 4 | Mmode); // Set magnetometer data resolution and sample ODR 00495 writeByte(MPU9255_ADDRESS, I2C_SLV0_CTRL, 0x81); // Enable I2C and transfer 1 byte 00496 wait_ms(50); 00497 writeByte(MPU9255_ADDRESS, I2C_SLV0_ADDR, AK8963_ADDRESS | 0x80); // Set the I2C slave address of AK8963 and set for read. 00498 writeByte(MPU9255_ADDRESS, I2C_SLV0_REG, AK8963_CNTL); // I2C slave 0 register address from where to begin data transfer 00499 writeByte(MPU9255_ADDRESS, I2C_SLV0_CTRL, 0x81); // Enable I2C and transfer 1 byte 00500 wait_ms(50); 00501 } 00502 00503 void MPU9255::readMagData_mpu9255(int16_t * destination) 00504 { 00505 uint8_t rawData[7]; // x/y/z gyro register data, ST2 register stored here, must read ST2 at end of data acquisition 00506 // readBytes(AK8963_ADDRESS, AK8963_XOUT_L, 7, &rawData[0]); // Read the six raw data and ST2 registers sequentially into data array 00507 writeByte(MPU9255_ADDRESS, I2C_SLV0_ADDR, AK8963_ADDRESS | 0x80); // Set the I2C slave address of AK8963 and set for read. 00508 writeByte(MPU9255_ADDRESS, I2C_SLV0_REG, AK8963_XOUT_L); // I2C slave 0 register address from where to begin data transfer 00509 writeByte(MPU9255_ADDRESS, I2C_SLV0_CTRL, 0x87); // Enable I2C and read 7 bytes 00510 wait_ms(2); 00511 readBytes(MPU9255_ADDRESS, EXT_SENS_DATA_00, 7, &rawData[0]); // Read the x-, y-, and z-axis calibration values 00512 uint8_t c = rawData[6]; // End data read by reading ST2 register 00513 if(!(c & 0x08)) // Check if magnetic sensor overflow set, if not then report data 00514 { 00515 destination[0] = ((int16_t)rawData[1] << 8) | rawData[0] ; // Turn the MSB and LSB into a signed 16-bit value 00516 destination[1] = ((int16_t)rawData[3] << 8) | rawData[2] ; // Data stored as little Endian 00517 destination[2] = ((int16_t)rawData[5] << 8) | rawData[4] ; 00518 } 00519 } 00520 00521 void MPU9255::readaccgyrodata_mpu9255(int16_t * destination) 00522 { 00523 uint8_t rawData[14]; // x/y/z accel register data stored here 00524 readBytes(MPU9255_ADDRESS, ACCEL_XOUT_H, 14, &rawData[0]); // Read the 14 raw data registers into data array 00525 destination[0] = ((int16_t)rawData[0] << 8) | rawData[1] ; // Turn the MSB and LSB into a signed 16-bit value 00526 destination[1] = ((int16_t)rawData[2] << 8) | rawData[3] ; 00527 destination[2] = ((int16_t)rawData[4] << 8) | rawData[5] ; 00528 destination[3] = ((int16_t)rawData[6] << 8) | rawData[7] ; 00529 destination[4] = ((int16_t)rawData[8] << 8) | rawData[9] ; 00530 destination[5] = ((int16_t)rawData[10] << 8) | rawData[11] ; 00531 destination[6] = ((int16_t)rawData[12] << 8) | rawData[13] ; 00532 }
Generated on Fri Jul 15 2022 06:35:48 by
