semin ahn / Mbed OS zeta_stm_kinetic

Dependencies:   BufferedSerial

Committer:
_seminahn
Date:
Tue Nov 30 08:13:05 2021 +0000
Revision:
3:a4677501ae87
v1.2.5, change imu freq

Who changed what in which revision?

UserRevisionLine numberNew contents of line
_seminahn 3:a4677501ae87 1 /*
_seminahn 3:a4677501ae87 2 * 20201024 - (MBED code) MPU-9250 AHRS
_seminahn 3:a4677501ae87 3 *
_seminahn 3:a4677501ae87 4 */
_seminahn 3:a4677501ae87 5 #include "mbed.h"
_seminahn 3:a4677501ae87 6 #include "MPU9250_SPI.h"
_seminahn 3:a4677501ae87 7 #include "MPU9250RegisterMap.h"
_seminahn 3:a4677501ae87 8 #include <cmath>
_seminahn 3:a4677501ae87 9
_seminahn 3:a4677501ae87 10
_seminahn 3:a4677501ae87 11 //define NO_ROS 0 // need also match define in "main.cpp"
_seminahn 3:a4677501ae87 12
_seminahn 3:a4677501ae87 13
_seminahn 3:a4677501ae87 14 #if (NO_ROS) // use Serial pc only when not using ROS
_seminahn 3:a4677501ae87 15 extern Serial pc;
_seminahn 3:a4677501ae87 16 #else
_seminahn 3:a4677501ae87 17 #include <ros.h>
_seminahn 3:a4677501ae87 18 extern ros::NodeHandle nh;
_seminahn 3:a4677501ae87 19 #endif
_seminahn 3:a4677501ae87 20
_seminahn 3:a4677501ae87 21 volatile bool MPU9250_SPI::_dataReady=false;
_seminahn 3:a4677501ae87 22
_seminahn 3:a4677501ae87 23 MPU9250_SPI::MPU9250_SPI(PinName mosi,PinName miso,PinName sclk, PinName cs, PinName intpin)
_seminahn 3:a4677501ae87 24 : _spi(mosi,miso,sclk), _csPin(cs), _intPin(intpin),_mMode(MGN_CONT_MEAS2),_mBits( MGN_16BITS),_srd(SR_200HZ)
_seminahn 3:a4677501ae87 25 {
_seminahn 3:a4677501ae87 26 magCalibration.x=0;magCalibration.y=0;magCalibration.z=0;
_seminahn 3:a4677501ae87 27 magBias.x=0; magBias.y=0; magBias.z=0;
_seminahn 3:a4677501ae87 28 magScale.x=1;magScale.y=1;magScale.z=1;
_seminahn 3:a4677501ae87 29 gyroBias.x =0; gyroBias.y =0; gyroBias.z =0;
_seminahn 3:a4677501ae87 30 accelBias.x=0; accelBias.y=0; accelBias.z=0;
_seminahn 3:a4677501ae87 31 magnetic_declination = 8.5;
_seminahn 3:a4677501ae87 32 q[0]=1.0f; q[1]=0.0f; q[2]=0.0f; q[3]=0.0f;
_seminahn 3:a4677501ae87 33 _csPin=1;
_seminahn 3:a4677501ae87 34 //qFilter.begin(100);
_seminahn 3:a4677501ae87 35 }
_seminahn 3:a4677501ae87 36
_seminahn 3:a4677501ae87 37 void MPU9250_SPI::setup()
_seminahn 3:a4677501ae87 38 {
_seminahn 3:a4677501ae87 39
_seminahn 3:a4677501ae87 40 _csPin=1; // setting CS pin high
_seminahn 3:a4677501ae87 41 _spi.format(8,3); // SPI mode 3
_seminahn 3:a4677501ae87 42 _spi.frequency(SPI_HS_CLOCK); // 1Mega
_seminahn 3:a4677501ae87 43 uint8_t m_whoami = 0x00;
_seminahn 3:a4677501ae87 44 uint8_t a_whoami = 0x00;
_seminahn 3:a4677501ae87 45 // while(true){
_seminahn 3:a4677501ae87 46 // _csPin = 0; // select device
_seminahn 3:a4677501ae87 47 // _spi.write(0x75 | 0x80); // to read slave data
_seminahn 3:a4677501ae87 48 // int whoami = _spi.write(0x33); // send any byte to read
_seminahn 3:a4677501ae87 49 // _csPin = 1; // Deselect the device
_seminahn 3:a4677501ae87 50 // pc.printf("WHOAMI register = 0x%X\n", whoami);
_seminahn 3:a4677501ae87 51 // wait(0.1);
_seminahn 3:a4677501ae87 52 // }
_seminahn 3:a4677501ae87 53 m_whoami = isConnectedMPU9250();
_seminahn 3:a4677501ae87 54 if (m_whoami==MPU9250_WHOAMI_DEFAULT_VALUE) {
_seminahn 3:a4677501ae87 55 //nh.loginfo("MPU9250 is online...");
_seminahn 3:a4677501ae87 56 #ifdef PRINT_DETAILS
_seminahn 3:a4677501ae87 57 #if (NO_ROS)
_seminahn 3:a4677501ae87 58 pc.printf("MPU9250 is online...\n");
_seminahn 3:a4677501ae87 59 #else
_seminahn 3:a4677501ae87 60
_seminahn 3:a4677501ae87 61 #endif
_seminahn 3:a4677501ae87 62 #endif
_seminahn 3:a4677501ae87 63 initMPU9250();
_seminahn 3:a4677501ae87 64 a_whoami = isConnectedAK8963();
_seminahn 3:a4677501ae87 65 if (a_whoami == AK8963_WHOAMI_DEFAULT_VALUE) {
_seminahn 3:a4677501ae87 66 initAK8963();
_seminahn 3:a4677501ae87 67 }
_seminahn 3:a4677501ae87 68 else {
_seminahn 3:a4677501ae87 69 #if (NO_ROS)
_seminahn 3:a4677501ae87 70 pc.printf("Could not connect to AK8963: 0x%x\n",a_whoami);
_seminahn 3:a4677501ae87 71 #endif
_seminahn 3:a4677501ae87 72 while(1);
_seminahn 3:a4677501ae87 73 }
_seminahn 3:a4677501ae87 74 }
_seminahn 3:a4677501ae87 75 else {
_seminahn 3:a4677501ae87 76 #if (NO_ROS)
_seminahn 3:a4677501ae87 77 pc.printf("Could not connect to MPU9250: 0x%x\n",m_whoami);
_seminahn 3:a4677501ae87 78 #endif
_seminahn 3:a4677501ae87 79 while(1);
_seminahn 3:a4677501ae87 80 }
_seminahn 3:a4677501ae87 81 _intPin.rise(callback(this, &MPU9250_SPI::intService));
_seminahn 3:a4677501ae87 82 _tmr.start();
_seminahn 3:a4677501ae87 83 }
_seminahn 3:a4677501ae87 84
_seminahn 3:a4677501ae87 85 void MPU9250_SPI::update(FusionMethod method)
_seminahn 3:a4677501ae87 86 {
_seminahn 3:a4677501ae87 87 if (_dataReady){
_seminahn 3:a4677501ae87 88 updateSensors();
_seminahn 3:a4677501ae87 89 float deltat = (_tmr.read_us()/ 1000000.0f); // set integration time by time elapsed since last filter update
_seminahn 3:a4677501ae87 90 _tmr.reset();
_seminahn 3:a4677501ae87 91 if (method == MADGWICK){
_seminahn 3:a4677501ae87 92 //qFilter.update(g.x,g.y,g.z,a.x,a.y,a.z,m.x,m.y,m.z); // dot의 방향이 전진인 경우
_seminahn 3:a4677501ae87 93 //pc.printf("gx: %.3f, gy: %.3f, gz: %.3f, ax: %.3f, ay: %.3f, az: %.3f\n\r",g.x,g.y,g.z,a.x,a.y,a.z);
_seminahn 3:a4677501ae87 94 //pc.printf("%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t\n\r",g.x,g.y,g.z,a.x,a.y,a.z);
_seminahn 3:a4677501ae87 95 qFilter.invSampleFreq = deltat;
_seminahn 3:a4677501ae87 96
_seminahn 3:a4677501ae87 97
_seminahn 3:a4677501ae87 98 a.x = 0.0;
_seminahn 3:a4677501ae87 99 a.y = 0.0;
_seminahn 3:a4677501ae87 100 a.z = 1.0;
_seminahn 3:a4677501ae87 101
_seminahn 3:a4677501ae87 102
_seminahn 3:a4677501ae87 103 qFilter.updateIMU(g.x,g.y,g.z,a.x,a.y,a.z);
_seminahn 3:a4677501ae87 104 q[0] = qFilter.q0;
_seminahn 3:a4677501ae87 105 q[1] = qFilter.q1;
_seminahn 3:a4677501ae87 106 q[2] = qFilter.q2;
_seminahn 3:a4677501ae87 107 q[3] = qFilter.q3;
_seminahn 3:a4677501ae87 108 //pc.printf("q0: %.3f, q1: %.3f, q2: %.3f, q3: %.3f\n\r",q[0],q[1],q[2],q[3]);
_seminahn 3:a4677501ae87 109 //pc.printf("%.3f\t%.3f\t%.3f\t%.3f\t\n\r",q[0],q[1],q[2],q[3]);
_seminahn 3:a4677501ae87 110 updateRPY();
_seminahn 3:a4677501ae87 111 _dataReady = false;
_seminahn 3:a4677501ae87 112 }
_seminahn 3:a4677501ae87 113 else{
_seminahn 3:a4677501ae87 114 compFilter(deltat);
_seminahn 3:a4677501ae87 115 //pc.printf("i entered compFilter!!!\n\r");
_seminahn 3:a4677501ae87 116 }
_seminahn 3:a4677501ae87 117 }
_seminahn 3:a4677501ae87 118 }
_seminahn 3:a4677501ae87 119
_seminahn 3:a4677501ae87 120 void MPU9250_SPI::compFilter(float dt)
_seminahn 3:a4677501ae87 121 {
_seminahn 3:a4677501ae87 122 Vect3 _a, _g, _m;
_seminahn 3:a4677501ae87 123 _a.x= a.y; _a.y= a.x; _a.z= -a.z;
_seminahn 3:a4677501ae87 124 _g.x= DEG_TO_RAD*g.y; _g.y= DEG_TO_RAD*g.x; _g.z= -DEG_TO_RAD*g.z;
_seminahn 3:a4677501ae87 125 float ayz= sqrt(_a.y*_a.y+_a.z*_a.z);
_seminahn 3:a4677501ae87 126 float rollAcc= atan2(-_a.y,-_a.z);
_seminahn 3:a4677501ae87 127 float pitchAcc= atan2(_a.x,ayz);
_seminahn 3:a4677501ae87 128 roll= ALPHA*(roll+_g.x*dt)+BETA*rollAcc;
_seminahn 3:a4677501ae87 129 pitch= ALPHA*(pitch+_g.y*dt)+BETA*pitchAcc;
_seminahn 3:a4677501ae87 130 float c_th=cos(pitch), s_th=sin(pitch), c_pi=cos(roll), s_pi=sin(roll);
_seminahn 3:a4677501ae87 131 _m.x= m.x*c_th+m.y*s_pi*c_th+m.z*c_pi*s_th;
_seminahn 3:a4677501ae87 132 _m.y= m.y*c_pi-m.z*s_pi;
_seminahn 3:a4677501ae87 133 float heading=-atan2(_m.y, _m.x);
_seminahn 3:a4677501ae87 134 if ((yaw-heading)>M_PI) heading+=TWO_PI;
_seminahn 3:a4677501ae87 135 else if ((yaw-heading)<-M_PI) yaw+=TWO_PI;
_seminahn 3:a4677501ae87 136 yaw= ALPHA*(yaw+_g.z*dt)+BETA*heading;
_seminahn 3:a4677501ae87 137 yaw= (yaw> M_PI) ? (yaw - TWO_PI) : ((yaw < -M_PI) ? (yaw +TWO_PI) : yaw);
_seminahn 3:a4677501ae87 138 }
_seminahn 3:a4677501ae87 139
_seminahn 3:a4677501ae87 140 void MPU9250_SPI::update(Vect3& _a,Vect3& _g,Vect3& _m)
_seminahn 3:a4677501ae87 141 {
_seminahn 3:a4677501ae87 142 if (_dataReady) { // On interrupt, check if data ready interrupt
_seminahn 3:a4677501ae87 143 updateSensors();
_seminahn 3:a4677501ae87 144 _a=a;_g=g;_m=m;
_seminahn 3:a4677501ae87 145 }
_seminahn 3:a4677501ae87 146 }
_seminahn 3:a4677501ae87 147
_seminahn 3:a4677501ae87 148 uint8_t MPU9250_SPI::isConnectedMPU9250()
_seminahn 3:a4677501ae87 149 {
_seminahn 3:a4677501ae87 150 uint8_t c = readByte(WHO_AM_I_MPU9250);
_seminahn 3:a4677501ae87 151 #ifdef PRINT_DETAILS
_seminahn 3:a4677501ae87 152 pc.printf("MPU9250 WHO AM I = 0x%x\n",c);
_seminahn 3:a4677501ae87 153 #endif
_seminahn 3:a4677501ae87 154 return c; // (c == MPU9250_WHOAMI_DEFAULT_VALUE);
_seminahn 3:a4677501ae87 155 }
_seminahn 3:a4677501ae87 156
_seminahn 3:a4677501ae87 157 uint8_t MPU9250_SPI::isConnectedAK8963()
_seminahn 3:a4677501ae87 158 {
_seminahn 3:a4677501ae87 159 uint8_t c = readAK8963Byte(AK8963_WHO_AM_I);
_seminahn 3:a4677501ae87 160 #ifdef PRINT_DETAILS
_seminahn 3:a4677501ae87 161 pc.printf("AK8963 WHO AM I = 0x%x\n ",c);
_seminahn 3:a4677501ae87 162 #endif
_seminahn 3:a4677501ae87 163 return c; // (c == AK8963_WHOAMI_DEFAULT_VALUE);
_seminahn 3:a4677501ae87 164 }
_seminahn 3:a4677501ae87 165
_seminahn 3:a4677501ae87 166 void MPU9250_SPI::initMPU9250()
_seminahn 3:a4677501ae87 167 {
_seminahn 3:a4677501ae87 168 wait_ms(100);
_seminahn 3:a4677501ae87 169 writeByte(PWR_MGMT_1, CLOCK_SEL_PLL);
_seminahn 3:a4677501ae87 170 writeByte(USER_CTRL,I2C_MST_EN); // Master enable
_seminahn 3:a4677501ae87 171 writeByte(I2C_MST_CTRL,I2C_MST_CLK); // I2C master clock =400HZ
_seminahn 3:a4677501ae87 172 replaceBlockAK(AK8963_CNTL,MGN_POWER_DN,0,4); // Power down
_seminahn 3:a4677501ae87 173 writeByte(PWR_MGMT_1, PWR_RESET); // Clear sleep mode bit (6), enable all sensors
_seminahn 3:a4677501ae87 174 wait_ms(100);
_seminahn 3:a4677501ae87 175 writeByte(PWR_MGMT_1, CLOCK_SEL_PLL);
_seminahn 3:a4677501ae87 176 //setDlpfBandwidth( DLPF_BANDWIDTH_41HZ);
_seminahn 3:a4677501ae87 177 writeByte(SMPLRT_DIV, SR_100HZ); //{SR_1000HZ=0, SR_200HZ=4, SR_100HZ=9 }
_seminahn 3:a4677501ae87 178 // writeByte(SMPLRT_DIV, SR_100HZ);
_seminahn 3:a4677501ae87 179 setGyroRange(GYRO_RANGE_2000DPS);
_seminahn 3:a4677501ae87 180 writeByte(PWR_MGMT_2,SEN_ENABLE);
_seminahn 3:a4677501ae87 181 setAccelRange(ACCEL_RANGE_16G);//{ _2G, _4G, _8G, _16G }
_seminahn 3:a4677501ae87 182 setDlpfBandwidth(DLPF_BANDWIDTH_41HZ); // [250HZ, 184HZ, 92HZ, 41HZ, 20HZ, 10HZ, 5HZ]
_seminahn 3:a4677501ae87 183 writeByte(INT_PIN_CFG, 0x20); // LATCH_INT_EN=1, BYPASS_EN=1-->0 (0x22)
_seminahn 3:a4677501ae87 184 writeByte(INT_ENABLE, 0x01); // Enable raw data ready (bit 0) interrupt
_seminahn 3:a4677501ae87 185 writeByte(USER_CTRL,I2C_MST_EN);
_seminahn 3:a4677501ae87 186 wait_ms(100);
_seminahn 3:a4677501ae87 187 writeByte(I2C_MST_CTRL,I2C_MST_CLK);
_seminahn 3:a4677501ae87 188 wait_ms(100);
_seminahn 3:a4677501ae87 189 }
_seminahn 3:a4677501ae87 190
_seminahn 3:a4677501ae87 191 void MPU9250_SPI::initAK8963()
_seminahn 3:a4677501ae87 192 {
_seminahn 3:a4677501ae87 193 uint8_t rawData[3]; // x/y/z gyro calibration data stored here
_seminahn 3:a4677501ae87 194 replaceBlockAK(AK8963_CNTL,MGN_POWER_DN,0,4); // Power down magnetometer
_seminahn 3:a4677501ae87 195 wait_ms(50);
_seminahn 3:a4677501ae87 196 replaceBlockAK(AK8963_CNTL,MGN_FUSE_ROM,0,4);
_seminahn 3:a4677501ae87 197 wait_ms(50);
_seminahn 3:a4677501ae87 198 readAK8963Bytes( AK8963_ASAX, 3, rawData); // Read the x-, y-, and z-axis calibration values
_seminahn 3:a4677501ae87 199 magCalibration.x = (float)(rawData[0] - 128)/256.f + 1.f; // Return x-axis sensitivity adjustment values, etc.
_seminahn 3:a4677501ae87 200 magCalibration.y = (float)(rawData[1] - 128)/256.f + 1.f;
_seminahn 3:a4677501ae87 201 magCalibration.z = (float)(rawData[2] - 128)/256.f + 1.f;
_seminahn 3:a4677501ae87 202 replaceBlockAK(AK8963_CNTL,MGN_POWER_DN,0,4); // Power down magnetometer
_seminahn 3:a4677501ae87 203 wait_ms(50);
_seminahn 3:a4677501ae87 204 replaceBlockAK(AK8963_CNTL,((_mBits << 4 )| _mMode),0,5); // Set measurment mode, mMode[0:3]
_seminahn 3:a4677501ae87 205 writeByte(PWR_MGMT_1,CLOCK_SEL_PLL);
_seminahn 3:a4677501ae87 206 wait_ms(50);
_seminahn 3:a4677501ae87 207 mRes=10. * 4912. / 32760.0; // for Magenetometer 16BITS
_seminahn 3:a4677501ae87 208 #ifdef PRINT_DETAILS
_seminahn 3:a4677501ae87 209 pc.printf("Calibration values:\n");
_seminahn 3:a4677501ae87 210 pc.printf("X-Axis sensitivity adjustment value %7.2f \n",magCalibration.x);
_seminahn 3:a4677501ae87 211 pc.printf("Y-Axis sensitivity adjustment value %7.2f \n",magCalibration.y);
_seminahn 3:a4677501ae87 212 pc.printf("Z-Axis sensitivity adjustment value %7.2f \n",magCalibration.z);
_seminahn 3:a4677501ae87 213 pc.printf("X-Axis sensitivity offset value %7.2f \n",magBias.x);
_seminahn 3:a4677501ae87 214 pc.printf("Y-Axis sensitivity offset value %7.2f \n",magBias.y);
_seminahn 3:a4677501ae87 215 pc.printf("Z-Axis sensitivity offset value %7.2f \n",magBias.z);
_seminahn 3:a4677501ae87 216 #endif
_seminahn 3:a4677501ae87 217 }
_seminahn 3:a4677501ae87 218
_seminahn 3:a4677501ae87 219 void MPU9250_SPI::setAccelRange(AccelRange range)
_seminahn 3:a4677501ae87 220 {
_seminahn 3:a4677501ae87 221 switch(range) {
_seminahn 3:a4677501ae87 222 case ACCEL_RANGE_2G:
_seminahn 3:a4677501ae87 223 aRes = 2.0f/32767.5f; break;
_seminahn 3:a4677501ae87 224 case ACCEL_RANGE_4G:
_seminahn 3:a4677501ae87 225 aRes = 4.0f/32767.5f; break;
_seminahn 3:a4677501ae87 226 case ACCEL_RANGE_8G:
_seminahn 3:a4677501ae87 227 aRes = 8.0f/32767.5f; break;
_seminahn 3:a4677501ae87 228 case ACCEL_RANGE_16G:
_seminahn 3:a4677501ae87 229 aRes = 16.0f/32767.5f; // setting the accel scale to 16G
_seminahn 3:a4677501ae87 230 break;
_seminahn 3:a4677501ae87 231 }
_seminahn 3:a4677501ae87 232 replaceBlock(ACCEL_CONFIG,range,3,2); // addr, value, at, size
_seminahn 3:a4677501ae87 233 _accelRange = range;
_seminahn 3:a4677501ae87 234 }
_seminahn 3:a4677501ae87 235
_seminahn 3:a4677501ae87 236 void MPU9250_SPI::setGyroRange(GyroRange range)
_seminahn 3:a4677501ae87 237 {
_seminahn 3:a4677501ae87 238 switch(range) {
_seminahn 3:a4677501ae87 239 case GYRO_RANGE_250DPS:
_seminahn 3:a4677501ae87 240 gRes = 250.0f/32767.5f; break;
_seminahn 3:a4677501ae87 241 case GYRO_RANGE_500DPS:
_seminahn 3:a4677501ae87 242 gRes = 500.0f/32767.5f; break;
_seminahn 3:a4677501ae87 243 case GYRO_RANGE_1000DPS:
_seminahn 3:a4677501ae87 244 gRes = 1000.0f/32767.5f; break;
_seminahn 3:a4677501ae87 245 case GYRO_RANGE_2000DPS:
_seminahn 3:a4677501ae87 246 gRes = 2000.0f/32767.5f ; break;
_seminahn 3:a4677501ae87 247 }
_seminahn 3:a4677501ae87 248 replaceBlock(GYRO_CONFIG,range,3,2);
_seminahn 3:a4677501ae87 249 _gyroRange = range;
_seminahn 3:a4677501ae87 250 }
_seminahn 3:a4677501ae87 251
_seminahn 3:a4677501ae87 252 void MPU9250_SPI::setDlpfBandwidth(DlpfBandwidth bandwidth)
_seminahn 3:a4677501ae87 253 {
_seminahn 3:a4677501ae87 254 replaceBlock(ACCEL_CONFIG2,bandwidth,0,4); //Accel DLPF [0:2]
_seminahn 3:a4677501ae87 255 replaceBlock(MPU_CONFIG,bandwidth,0,3); //Gyro DLPF [0:2]
_seminahn 3:a4677501ae87 256 _bandwidth = bandwidth;
_seminahn 3:a4677501ae87 257 }
_seminahn 3:a4677501ae87 258
_seminahn 3:a4677501ae87 259 void MPU9250_SPI::setSampleRate(SampleRate srd)
_seminahn 3:a4677501ae87 260 {
_seminahn 3:a4677501ae87 261 writeByte(SMPLRT_DIV, srd); // sampling rate set
_seminahn 3:a4677501ae87 262 _srd = srd;
_seminahn 3:a4677501ae87 263 }
_seminahn 3:a4677501ae87 264
_seminahn 3:a4677501ae87 265 void MPU9250_SPI::calibrateMag()
_seminahn 3:a4677501ae87 266 {
_seminahn 3:a4677501ae87 267 magCalMPU9250();
_seminahn 3:a4677501ae87 268 }
_seminahn 3:a4677501ae87 269
_seminahn 3:a4677501ae87 270 void MPU9250_SPI::enableDataReadyInterrupt()
_seminahn 3:a4677501ae87 271 {
_seminahn 3:a4677501ae87 272 writeByte(INT_PIN_CFG,0x00); // setup interrupt, 50 us pulse
_seminahn 3:a4677501ae87 273 writeByte(INT_ENABLE,0x01) ; // set to data ready
_seminahn 3:a4677501ae87 274 }
_seminahn 3:a4677501ae87 275
_seminahn 3:a4677501ae87 276 void MPU9250_SPI::updateSensors()
_seminahn 3:a4677501ae87 277 {
_seminahn 3:a4677501ae87 278 int16_t MPU9250Data[10]; // MPU9250 accel/gyro 에서 16비트 정수로 7개 저장
_seminahn 3:a4677501ae87 279 uint8_t rawData[21]; // 가속도 자이로 원시 데이터 보관
_seminahn 3:a4677501ae87 280 writeByte(I2C_SLV0_ADDR,AK8963_I2C_ADDR|SPI_READ); // Set the I2C slave addres of AK8963 and set for read.
_seminahn 3:a4677501ae87 281 writeByte(I2C_SLV0_REG,AK8963_XOUT_L); // I2C slave 0 register address from where to begin data transfer
_seminahn 3:a4677501ae87 282 writeByte(I2C_SLV0_CTRL, 0x87); // Read 7 bytes from the magnetometer
_seminahn 3:a4677501ae87 283 readBytes(ACCEL_XOUT_H, 21, rawData); // 16비트 정수로 7개 저장--> 14byte
_seminahn 3:a4677501ae87 284 MPU9250Data[0] = ((int16_t)rawData[0] << 8) | rawData[1] ; // signed 16-bit (MSB + LSB)
_seminahn 3:a4677501ae87 285 MPU9250Data[1] = ((int16_t)rawData[2] << 8) | rawData[3] ;
_seminahn 3:a4677501ae87 286 MPU9250Data[2] = ((int16_t)rawData[4] << 8) | rawData[5] ;
_seminahn 3:a4677501ae87 287 MPU9250Data[3] = ((int16_t)rawData[6] << 8) | rawData[7] ;
_seminahn 3:a4677501ae87 288 MPU9250Data[4] = ((int16_t)rawData[8] << 8) | rawData[9] ;
_seminahn 3:a4677501ae87 289 MPU9250Data[5] = ((int16_t)rawData[10] << 8) | rawData[11] ;
_seminahn 3:a4677501ae87 290 MPU9250Data[6] = ((int16_t)rawData[12] << 8) | rawData[13] ;
_seminahn 3:a4677501ae87 291 MPU9250Data[7] = (((int16_t)rawData[15]) << 8) |rawData[14];
_seminahn 3:a4677501ae87 292 MPU9250Data[8] = (((int16_t)rawData[17]) << 8) |rawData[16];
_seminahn 3:a4677501ae87 293 MPU9250Data[9] = (((int16_t)rawData[19]) << 8) |rawData[18];
_seminahn 3:a4677501ae87 294 a.x = (float)MPU9250Data[0] * aRes - accelBias.x; // 가속도 해상도와 바이어스 보정
_seminahn 3:a4677501ae87 295 a.y = (float)MPU9250Data[1] * aRes - accelBias.y;
_seminahn 3:a4677501ae87 296 a.z = (float)MPU9250Data[2] * aRes - accelBias.z;
_seminahn 3:a4677501ae87 297 g.x = (float)MPU9250Data[4] * gRes- gyroBias.x; // 자이로 해상도 보정
_seminahn 3:a4677501ae87 298 g.y = (float)MPU9250Data[5] * gRes- gyroBias.y; // 자이로 바이어스는 칩내부에서 보정함!!!
_seminahn 3:a4677501ae87 299 g.z = (float)MPU9250Data[6] * gRes- gyroBias.z;
_seminahn 3:a4677501ae87 300 if(abs(g.x) < 1.0) g.x = 0.0;
_seminahn 3:a4677501ae87 301 if(abs(g.y) < 1.0) g.y = 0.0;
_seminahn 3:a4677501ae87 302 if(abs(g.z) < 1.0) g.z = 0.0;
_seminahn 3:a4677501ae87 303 m.x = (float)(MPU9250Data[7] * mRes * magCalibration.x - magBias.x) * magScale.x;
_seminahn 3:a4677501ae87 304 m.y = (float)(MPU9250Data[8] * mRes * magCalibration.y - magBias.y) * magScale.y;
_seminahn 3:a4677501ae87 305 m.z = (float)(MPU9250Data[9] * mRes * magCalibration.z - magBias.z) * magScale.z;
_seminahn 3:a4677501ae87 306 }
_seminahn 3:a4677501ae87 307
_seminahn 3:a4677501ae87 308 void MPU9250_SPI::updateAccelGyro()
_seminahn 3:a4677501ae87 309 {
_seminahn 3:a4677501ae87 310 int16_t MPU9250Data[7]; // MPU9250 accel/gyro 에서 16비트 정수로 7개 저장
_seminahn 3:a4677501ae87 311 readMPU9250Data(MPU9250Data); // 읽으면 INT 핀 해제
_seminahn 3:a4677501ae87 312 a.x = (float)MPU9250Data[0] * aRes - accelBias.x; // 가속도 해상도와 바이어스 보정
_seminahn 3:a4677501ae87 313 a.y = (float)MPU9250Data[1] * aRes - accelBias.y;
_seminahn 3:a4677501ae87 314 a.z = (float)MPU9250Data[2] * aRes - accelBias.z;
_seminahn 3:a4677501ae87 315 g.x = (float)MPU9250Data[4] * gRes - gyroBias.x; // 자이로 해상도 보정
_seminahn 3:a4677501ae87 316 g.y = (float)MPU9250Data[5] * gRes - gyroBias.y; //
_seminahn 3:a4677501ae87 317 g.z = (float)MPU9250Data[6] * gRes - gyroBias.z;
_seminahn 3:a4677501ae87 318 }
_seminahn 3:a4677501ae87 319
_seminahn 3:a4677501ae87 320 void MPU9250_SPI::readMPU9250Data(int16_t * destination)
_seminahn 3:a4677501ae87 321 {
_seminahn 3:a4677501ae87 322 uint8_t rawData[14]; // 가속도 자이로 원시 데이터 보관
_seminahn 3:a4677501ae87 323 readBytes(ACCEL_XOUT_H, 14, rawData); // 16비트 정수로 7개 저장--> 14byte
_seminahn 3:a4677501ae87 324 destination[0] = ((int16_t)rawData[0] << 8) | rawData[1] ; // signed 16-bit (MSB + LSB)
_seminahn 3:a4677501ae87 325 destination[1] = ((int16_t)rawData[2] << 8) | rawData[3] ;
_seminahn 3:a4677501ae87 326 destination[2] = ((int16_t)rawData[4] << 8) | rawData[5] ;
_seminahn 3:a4677501ae87 327 destination[3] = ((int16_t)rawData[6] << 8) | rawData[7] ;
_seminahn 3:a4677501ae87 328 destination[4] = ((int16_t)rawData[8] << 8) | rawData[9] ;
_seminahn 3:a4677501ae87 329 destination[5] = ((int16_t)rawData[10] << 8) | rawData[11] ;
_seminahn 3:a4677501ae87 330 destination[6] = ((int16_t)rawData[12] << 8) | rawData[13] ;
_seminahn 3:a4677501ae87 331 }
_seminahn 3:a4677501ae87 332
_seminahn 3:a4677501ae87 333 void MPU9250_SPI::updateMag()
_seminahn 3:a4677501ae87 334 {
_seminahn 3:a4677501ae87 335 int16_t magCount[3] = {0, 0, 0}; // 16-bit 지자기 데이터
_seminahn 3:a4677501ae87 336 readMagData(magCount); // 지자기 데이터 읽기
_seminahn 3:a4677501ae87 337 // 지자기 해상도, 검정값, 바이어스 보정, 검정값 (magCalibration[] )은 칩의 ROM에서
_seminahn 3:a4677501ae87 338 m.x = (float)(magCount[0] * mRes * magCalibration.x - magBias.x) * magScale.x;
_seminahn 3:a4677501ae87 339 m.y = (float)(magCount[1] * mRes * magCalibration.y - magBias.y) * magScale.y;
_seminahn 3:a4677501ae87 340 m.z = (float)(magCount[2] * mRes * magCalibration.z - magBias.z) * magScale.z;
_seminahn 3:a4677501ae87 341 }
_seminahn 3:a4677501ae87 342
_seminahn 3:a4677501ae87 343 void MPU9250_SPI::readMagData(int16_t * destination)
_seminahn 3:a4677501ae87 344 {
_seminahn 3:a4677501ae87 345 uint8_t rawData[7]; // x/y/z gyro register data, ST2 register stored here, must read ST2 at end of data acquisition
_seminahn 3:a4677501ae87 346 if(readAK8963Byte(AK8963_ST1) & 0x01) { // wait for magnetometer data ready bit to be set
_seminahn 3:a4677501ae87 347 readAK8963Bytes(AK8963_XOUT_L, 7,rawData); // Read the six raw data and ST2 registers sequentially into data array
_seminahn 3:a4677501ae87 348 uint8_t c = rawData[6]; // End data read by reading ST2 register
_seminahn 3:a4677501ae87 349 if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data
_seminahn 3:a4677501ae87 350 destination[0] = ((int16_t)rawData[1] << 8) | rawData[0]; // Turn the MSB and LSB into a signed 16-bit value
_seminahn 3:a4677501ae87 351 destination[1] = ((int16_t)rawData[3] << 8) | rawData[2]; // Data stored as little Endian
_seminahn 3:a4677501ae87 352 destination[2] = ((int16_t)rawData[5] << 8) | rawData[4];
_seminahn 3:a4677501ae87 353 }
_seminahn 3:a4677501ae87 354 }
_seminahn 3:a4677501ae87 355 }
_seminahn 3:a4677501ae87 356
_seminahn 3:a4677501ae87 357 void MPU9250_SPI::calibrateGyro()
_seminahn 3:a4677501ae87 358 {
_seminahn 3:a4677501ae87 359 size_t _numSamples=128;
_seminahn 3:a4677501ae87 360 Vect3 gyroSum;gyroSum.x=0;gyroSum.y=0;gyroSum.z=0;
_seminahn 3:a4677501ae87 361 // added semin
_seminahn 3:a4677501ae87 362 Vect3 accSum;accSum.x=0;accSum.y=0;accSum.z=0;
_seminahn 3:a4677501ae87 363 #if (NO_ROS)
_seminahn 3:a4677501ae87 364 pc.printf("Please, don't move!\n");
_seminahn 3:a4677501ae87 365 #endif
_seminahn 3:a4677501ae87 366 wait_ms(100);
_seminahn 3:a4677501ae87 367 for (size_t i=0; i < _numSamples; i++) {
_seminahn 3:a4677501ae87 368 updateAccelGyro();
_seminahn 3:a4677501ae87 369 gyroSum.x+= (g.x + gyroBias.x)/(( float)_numSamples);
_seminahn 3:a4677501ae87 370 gyroSum.y+= (g.y + gyroBias.y)/(( float)_numSamples);
_seminahn 3:a4677501ae87 371 gyroSum.z+= (g.z + gyroBias.z)/(( float)_numSamples);
_seminahn 3:a4677501ae87 372 accSum.x+= (a.x + accelBias.x)/(( float)_numSamples);
_seminahn 3:a4677501ae87 373 accSum.y+= (a.y + accelBias.y)/(( float)_numSamples);
_seminahn 3:a4677501ae87 374 accSum.z+= (a.z + accelBias.z)/(( float)_numSamples);
_seminahn 3:a4677501ae87 375 wait_ms(20);
_seminahn 3:a4677501ae87 376 }
_seminahn 3:a4677501ae87 377 accelBias = accSum;
_seminahn 3:a4677501ae87 378 accelBias.z = accelBias.z - 1.0;
_seminahn 3:a4677501ae87 379 gyroBias = gyroSum;
_seminahn 3:a4677501ae87 380 #if (NO_ROS)
_seminahn 3:a4677501ae87 381 pc.printf("Gyro Calibration done!\n");
_seminahn 3:a4677501ae87 382 pc.printf("MPU9250 Gyro biases (deg/s)\n");
_seminahn 3:a4677501ae87 383 pc.printf("%7.3f, %7.3f , %7.3f\n", gyroBias.x, gyroBias.y, gyroBias.z);
_seminahn 3:a4677501ae87 384 #endif
_seminahn 3:a4677501ae87 385 }
_seminahn 3:a4677501ae87 386
_seminahn 3:a4677501ae87 387 void MPU9250_SPI::magCalMPU9250()
_seminahn 3:a4677501ae87 388 {
_seminahn 3:a4677501ae87 389 uint16_t ii = 0, sample_count = 0;
_seminahn 3:a4677501ae87 390 int32_t mag_bias[3] = {0, 0, 0}, mag_scale[3] = {0, 0, 0};
_seminahn 3:a4677501ae87 391 int16_t mag_max[3] = {-32767, -32767, -32767}, mag_min[3] = {32767, 32767, 32767}, mag_temp[3] = {0, 0, 0};
_seminahn 3:a4677501ae87 392 #if (NO_ROS)
_seminahn 3:a4677501ae87 393 pc.printf("Mag Calibration: Wave device in a figure eight until done!\n");
_seminahn 3:a4677501ae87 394 #endif
_seminahn 3:a4677501ae87 395 wait_ms(3000);
_seminahn 3:a4677501ae87 396 if (_mMode == MGN_CONT_MEAS1) sample_count = 128; // at 8 Hz ODR, new mag data is available every 125 ms
_seminahn 3:a4677501ae87 397 else if (_mMode == MGN_CONT_MEAS2) sample_count = 1500; // at 100 Hz ODR, new mag data is available every 10 ms
_seminahn 3:a4677501ae87 398 for(ii = 0; ii < sample_count; ii++) {
_seminahn 3:a4677501ae87 399 readMagData(mag_temp); // Read the mag data
_seminahn 3:a4677501ae87 400 for (int jj = 0; jj < 3; jj++) {
_seminahn 3:a4677501ae87 401 if(mag_temp[jj] > mag_max[jj]) mag_max[jj] = mag_temp[jj];
_seminahn 3:a4677501ae87 402 if(mag_temp[jj] < mag_min[jj]) mag_min[jj] = mag_temp[jj];
_seminahn 3:a4677501ae87 403 }
_seminahn 3:a4677501ae87 404 if(_mMode == MGN_CONT_MEAS1) wait_ms(135); // at 8 Hz ODR, new mag data is available every 125 ms
_seminahn 3:a4677501ae87 405 if(_mMode == MGN_CONT_MEAS2) wait_ms(12); // at 100 Hz ODR, new mag data is available every 10 ms
_seminahn 3:a4677501ae87 406 }
_seminahn 3:a4677501ae87 407 #if (NO_ROS)
_seminahn 3:a4677501ae87 408 pc.printf("mag x min/max: %d /%d \n",mag_min[0],mag_max[0]);
_seminahn 3:a4677501ae87 409 pc.printf("mag y min/max: %d /%d \n",mag_min[1],mag_max[1]);
_seminahn 3:a4677501ae87 410 pc.printf("mag z min/max: %d /%d \n",mag_min[2],mag_max[2]);
_seminahn 3:a4677501ae87 411 #endif
_seminahn 3:a4677501ae87 412 // Get hard iron correction
_seminahn 3:a4677501ae87 413 mag_bias[0] = (mag_max[0] + mag_min[0])/2; // get average x mag bias in counts
_seminahn 3:a4677501ae87 414 mag_bias[1] = (mag_max[1] + mag_min[1])/2; // get average y mag bias in counts
_seminahn 3:a4677501ae87 415 mag_bias[2] = (mag_max[2] + mag_min[2])/2; // get average z mag bias in counts
_seminahn 3:a4677501ae87 416
_seminahn 3:a4677501ae87 417 magBias.x = (float) mag_bias[0]*mRes*magCalibration.x; // save mag biases in G for main program
_seminahn 3:a4677501ae87 418 magBias.y = (float) mag_bias[1]*mRes*magCalibration.y;
_seminahn 3:a4677501ae87 419 magBias.z = (float) mag_bias[2]*mRes*magCalibration.z;
_seminahn 3:a4677501ae87 420
_seminahn 3:a4677501ae87 421 // Get soft iron correction estimate
_seminahn 3:a4677501ae87 422 mag_scale[0] = (mag_max[0] - mag_min[0])/2; // get average x axis max chord length in counts
_seminahn 3:a4677501ae87 423 mag_scale[1] = (mag_max[1] - mag_min[1])/2; // get average y axis max chord length in counts
_seminahn 3:a4677501ae87 424 mag_scale[2] = (mag_max[2] - mag_min[2])/2; // get average z axis max chord length in counts
_seminahn 3:a4677501ae87 425
_seminahn 3:a4677501ae87 426 float avg_rad = mag_scale[0] + mag_scale[1] + mag_scale[2];
_seminahn 3:a4677501ae87 427 avg_rad /= 3.0;
_seminahn 3:a4677501ae87 428
_seminahn 3:a4677501ae87 429 magScale.x = avg_rad/((float)mag_scale[0]);
_seminahn 3:a4677501ae87 430 magScale.y = avg_rad/((float)mag_scale[1]);
_seminahn 3:a4677501ae87 431 magScale.z = avg_rad/((float)mag_scale[2]);
_seminahn 3:a4677501ae87 432 #if (NO_ROS)
_seminahn 3:a4677501ae87 433 pc.printf("Mag Calibration done!\n");
_seminahn 3:a4677501ae87 434 pc.printf("AK8963 mag biases (mG)\_numSamples\n");
_seminahn 3:a4677501ae87 435 pc.printf("%7.3f, %7.3f , %7.3f\n", magBias.x, magBias.y, magBias.z);
_seminahn 3:a4677501ae87 436 pc.printf("AK8963 mag scale (mG)\n");
_seminahn 3:a4677501ae87 437 pc.printf("%7.3f, %7.3f , %7.3f\n", magScale.x, magScale.y,magScale.z);
_seminahn 3:a4677501ae87 438 #endif
_seminahn 3:a4677501ae87 439 }
_seminahn 3:a4677501ae87 440
_seminahn 3:a4677501ae87 441 /* write data to device */
_seminahn 3:a4677501ae87 442 void MPU9250_SPI::writeByte(uint8_t subAddress, uint8_t data)
_seminahn 3:a4677501ae87 443 {
_seminahn 3:a4677501ae87 444 // _spi->beginTransaction(SPISettings(SPI_HS_CLOCK, MSBFIRST, SPI_MODE3)); // begin the transaction
_seminahn 3:a4677501ae87 445 // digitalWrite(_csPin,LOW); // select the MPU9250 chip
_seminahn 3:a4677501ae87 446 // _spi->transfer(subAddress); // write the register address
_seminahn 3:a4677501ae87 447 // _spi->transfer(data); // write the data
_seminahn 3:a4677501ae87 448 // digitalWrite(_csPin,HIGH); // deselect the MPU9250 chip
_seminahn 3:a4677501ae87 449 // _spi->endTransaction(); // end the transaction
_seminahn 3:a4677501ae87 450 _spi.frequency(SPI_LS_CLOCK); // setup clock
_seminahn 3:a4677501ae87 451 _csPin=0; // select the MPU9250 chip
_seminahn 3:a4677501ae87 452 _spi.write(subAddress); // write the register address
_seminahn 3:a4677501ae87 453 _spi.write(data); // write the data
_seminahn 3:a4677501ae87 454 _csPin=1; // deselect the MPU9250 chip
_seminahn 3:a4677501ae87 455 }
_seminahn 3:a4677501ae87 456
_seminahn 3:a4677501ae87 457 uint8_t MPU9250_SPI::readByte(uint8_t subAddress)
_seminahn 3:a4677501ae87 458 {
_seminahn 3:a4677501ae87 459 // _spi->beginTransaction(SPISettings(SPI_HS_CLOCK, MSBFIRST, SPI_MODE3));
_seminahn 3:a4677501ae87 460 // digitalWrite(_csPin,LOW); // select the MPU9250 chip
_seminahn 3:a4677501ae87 461 // _spi->transfer(subAddress | SPI_READ); // specify the starting register address
_seminahn 3:a4677501ae87 462 // uint8_t data = _spi->transfer(0x00); // read the data
_seminahn 3:a4677501ae87 463 // digitalWrite(_csPin,HIGH); // deselect the MPU9250 chip
_seminahn 3:a4677501ae87 464 // _spi->endTransaction(); // end the transaction
_seminahn 3:a4677501ae87 465
_seminahn 3:a4677501ae87 466 _spi.frequency(SPI_LS_CLOCK); // setup clock
_seminahn 3:a4677501ae87 467 _csPin=0; // select the MPU9250 chip
_seminahn 3:a4677501ae87 468 _spi.write(subAddress| SPI_READ); // use READ MASK
_seminahn 3:a4677501ae87 469 uint8_t data =_spi.write(0); // write any to get data
_seminahn 3:a4677501ae87 470 _csPin=1; // deselect the MPU9250 chip
_seminahn 3:a4677501ae87 471 return data;
_seminahn 3:a4677501ae87 472 }
_seminahn 3:a4677501ae87 473
_seminahn 3:a4677501ae87 474 void MPU9250_SPI::readBytes(uint8_t subAddress, uint8_t cnt, uint8_t* dest)
_seminahn 3:a4677501ae87 475 {
_seminahn 3:a4677501ae87 476 // _spi->beginTransaction(SPISettings(SPI_HS_CLOCK, MSBFIRST, SPI_MODE3));
_seminahn 3:a4677501ae87 477 // digitalWrite(_csPin,LOW); // select the MPU9250 chip
_seminahn 3:a4677501ae87 478 // _spi->transfer(subAddress | SPI_READ); // specify the starting register address
_seminahn 3:a4677501ae87 479 // for(uint8_t i = 0; i < count; i++){
_seminahn 3:a4677501ae87 480 // dest[i] = _spi->transfer(0x00); // read the data
_seminahn 3:a4677501ae87 481 // }
_seminahn 3:a4677501ae87 482 // digitalWrite(_csPin,HIGH); // deselect the MPU9250 chip
_seminahn 3:a4677501ae87 483 // _spi->endTransaction(); // end the transaction
_seminahn 3:a4677501ae87 484 _spi.frequency(SPI_HS_CLOCK); // setup clock
_seminahn 3:a4677501ae87 485 _csPin=0; // select the MPU9250 chip
_seminahn 3:a4677501ae87 486 _spi.write(subAddress | SPI_READ); // specify the starting register address
_seminahn 3:a4677501ae87 487 for(uint8_t i = 0; i < cnt; i++){
_seminahn 3:a4677501ae87 488 dest[i] = _spi.write(0x00); // read the data
_seminahn 3:a4677501ae87 489 }
_seminahn 3:a4677501ae87 490 _csPin=1; // deselect the MPU9250 chip
_seminahn 3:a4677501ae87 491 }
_seminahn 3:a4677501ae87 492
_seminahn 3:a4677501ae87 493 void MPU9250_SPI::writeAK8963Byte(uint8_t subAddress, uint8_t data)
_seminahn 3:a4677501ae87 494 {
_seminahn 3:a4677501ae87 495 writeByte(I2C_SLV0_ADDR,AK8963_I2C_ADDR) ; // set slave 0 to the AK8963 and set for write
_seminahn 3:a4677501ae87 496 writeByte(I2C_SLV0_REG,subAddress) ; // set the register to the desired AK8963 sub address
_seminahn 3:a4677501ae87 497 writeByte(I2C_SLV0_DO,data) ; // store the data for write
_seminahn 3:a4677501ae87 498 writeByte(I2C_SLV0_CTRL,I2C_SLV0_EN | (uint8_t)1); // enable I2C and send 1 byte
_seminahn 3:a4677501ae87 499 }
_seminahn 3:a4677501ae87 500
_seminahn 3:a4677501ae87 501 void MPU9250_SPI::readAK8963Bytes(uint8_t subAddress, uint8_t count, uint8_t* dest)
_seminahn 3:a4677501ae87 502 {
_seminahn 3:a4677501ae87 503 writeByte(I2C_SLV0_ADDR,AK8963_I2C_ADDR | I2C_READ_FLAG) ; // set slave 0 to the AK8963 and set for read
_seminahn 3:a4677501ae87 504 writeByte(I2C_SLV0_REG,subAddress) ; // set the register to the desired AK8963 sub address
_seminahn 3:a4677501ae87 505 writeByte(I2C_SLV0_CTRL,I2C_SLV0_EN | count); // enable I2C and request the bytes
_seminahn 3:a4677501ae87 506 wait_ms(1); // takes some time for these registers to fill
_seminahn 3:a4677501ae87 507 readBytes(EXT_SENS_DATA_00,count,dest); // read the bytes off the MPU9250 EXT_SENS_DATA registers
_seminahn 3:a4677501ae87 508 }
_seminahn 3:a4677501ae87 509
_seminahn 3:a4677501ae87 510 uint8_t MPU9250_SPI::readAK8963Byte(uint8_t subAddress)
_seminahn 3:a4677501ae87 511 {
_seminahn 3:a4677501ae87 512 writeByte(I2C_SLV0_ADDR,AK8963_I2C_ADDR | I2C_READ_FLAG) ; // set slave 0 to the AK8963 and set for read
_seminahn 3:a4677501ae87 513 writeByte(I2C_SLV0_REG,subAddress) ; // set the register to the desired AK8963 sub address
_seminahn 3:a4677501ae87 514 writeByte(I2C_SLV0_CTRL,I2C_SLV0_EN | (uint8_t)1); // enable I2C and request the bytes
_seminahn 3:a4677501ae87 515 wait_ms(11); // takes some time for these registers to fill
_seminahn 3:a4677501ae87 516 return readByte(EXT_SENS_DATA_00); // read the bytes off the MPU9250 EXT_SENS_DATA registers
_seminahn 3:a4677501ae87 517 }
_seminahn 3:a4677501ae87 518
_seminahn 3:a4677501ae87 519 void MPU9250_SPI::replaceBlock(uint8_t address, uint8_t block, uint8_t at, uint8_t sz)
_seminahn 3:a4677501ae87 520 {
_seminahn 3:a4677501ae87 521 uint8_t data=readByte(address);
_seminahn 3:a4677501ae87 522 data &= ~(((1<<sz)-1)<<at);
_seminahn 3:a4677501ae87 523 data |= block<<at;
_seminahn 3:a4677501ae87 524 writeByte(address, data );
_seminahn 3:a4677501ae87 525 }
_seminahn 3:a4677501ae87 526
_seminahn 3:a4677501ae87 527 void MPU9250_SPI::replaceBlockAK(uint8_t address, uint8_t block, uint8_t at, uint8_t sz)
_seminahn 3:a4677501ae87 528 {
_seminahn 3:a4677501ae87 529 uint8_t data=readByte(address);
_seminahn 3:a4677501ae87 530 data &= ~(((1<<sz)-1)<<at);
_seminahn 3:a4677501ae87 531 data |= block<<at;
_seminahn 3:a4677501ae87 532 writeAK8963Byte(address, data );
_seminahn 3:a4677501ae87 533 }
_seminahn 3:a4677501ae87 534
_seminahn 3:a4677501ae87 535 void MPU9250_SPI::updateRPY() // RPY : Roll Pitch Yaw
_seminahn 3:a4677501ae87 536 {
_seminahn 3:a4677501ae87 537 a12 = 2.0f * (q[1] * q[2] + q[0] * q[3]);
_seminahn 3:a4677501ae87 538 a22 = q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3];
_seminahn 3:a4677501ae87 539 a31 = 2.0f * (q[0] * q[1] + q[2] * q[3]);
_seminahn 3:a4677501ae87 540 a32 = 2.0f * (q[1] * q[3] - q[0] * q[2]);
_seminahn 3:a4677501ae87 541 a33 = q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3];
_seminahn 3:a4677501ae87 542 pitch = -asinf(a32);
_seminahn 3:a4677501ae87 543 roll = atan2f(a31, a33);
_seminahn 3:a4677501ae87 544 yaw = atan2f(a12, a22);
_seminahn 3:a4677501ae87 545 yaw += magnetic_declination*DEG_TO_RAD;
_seminahn 3:a4677501ae87 546 yaw= (yaw> M_PI) ? (yaw - TWO_PI) : ((yaw < - M_PI) ? (yaw +TWO_PI) : yaw);
_seminahn 3:a4677501ae87 547 }
_seminahn 3:a4677501ae87 548
_seminahn 3:a4677501ae87 549
_seminahn 3:a4677501ae87 550 /***** EOF *****/