MPU9250

Dependents:   OneCircleRobot

Fork of MPU9250 by Kiko Ishimoto

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MPU9250.cpp Source File

MPU9250.cpp

00001 /*CODED by Qiyong Mu on 21/06/2014
00002 kylongmu@msn.com
00003 */
00004 
00005 #include <mbed.h>
00006 #include "MPU9250.h"
00007 
00008 mpu9250_spi::mpu9250_spi(SPI& _spi, PinName _cs) : spi(_spi), cs(_cs)
00009 {
00010     /* uint8_t offset[3][2] =
00011          {-21 , MPUREG_XG_OFFS_TC};
00012      for(i=0; i<offset; i++) {
00013          WriteReg(offset[i][1], offset[i][0]);
00014          wait(0.001);  //I2C must slow down the write speed, otherwise it won't work
00015      }*/
00016     Magnetometer_offset[0]=0;
00017     Magnetometer_offset[1]=0;
00018     Magnetometer_offset[2]=0;
00019 }
00020 
00021 unsigned int mpu9250_spi::WriteReg( uint8_t WriteAddr, uint8_t WriteData )
00022 {
00023     unsigned int temp_val;
00024     select();
00025     spi.write(WriteAddr);
00026     temp_val=spi.write(WriteData);
00027     deselect();
00028     wait_us(50);
00029     return temp_val;
00030 }
00031 unsigned int  mpu9250_spi::ReadReg( uint8_t WriteAddr, uint8_t WriteData )
00032 {
00033     return WriteReg(WriteAddr | READ_FLAG,WriteData);
00034 }
00035 void mpu9250_spi::ReadRegs( uint8_t ReadAddr, uint8_t *ReadBuf, unsigned int Bytes )
00036 {
00037     unsigned int  i = 0;
00038 
00039     select();
00040     spi.write(ReadAddr | READ_FLAG);
00041     for(i=0; i<Bytes; i++)
00042         ReadBuf[i] = spi.write(0x00);
00043     deselect();
00044     wait_us(50);
00045 }
00046 
00047 /*-----------------------------------------------------------------------------------------------
00048                                     INITIALIZATION
00049 usage: call this function at startup, giving the sample rate divider (raging from 0 to 255) and
00050 low pass filter value; suitable values are:
00051 BITS_DLPF_CFG_256HZ_NOLPF2
00052 BITS_DLPF_CFG_188HZ
00053 BITS_DLPF_CFG_98HZ
00054 BITS_DLPF_CFG_42HZ
00055 BITS_DLPF_CFG_20HZ
00056 BITS_DLPF_CFG_10HZ
00057 BITS_DLPF_CFG_5HZ
00058 BITS_DLPF_CFG_2100HZ_NOLPF
00059 returns 1 if an error occurred
00060 -----------------------------------------------------------------------------------------------*/
00061 #define MPU_InitRegNum 17
00062 
00063 bool mpu9250_spi::init(int sample_rate_div,int low_pass_filter)
00064 {
00065     uint8_t i = 0;
00066     uint8_t MPU_Init_Data[MPU_InitRegNum][2] = {
00067         {0x80, MPUREG_PWR_MGMT_1},     // Reset Device
00068         {0x01, MPUREG_PWR_MGMT_1},     // Clock Source
00069         {0x00, MPUREG_PWR_MGMT_2},     // Enable Acc & Gyro
00070         {low_pass_filter, MPUREG_CONFIG},         // Use DLPF set Gyroscope bandwidth 184Hz, temperature bandwidth 188Hz
00071         {0x18, MPUREG_GYRO_CONFIG},    // +-2000dps
00072         {0x08, MPUREG_ACCEL_CONFIG},   // +-4G
00073         {0x09, MPUREG_ACCEL_CONFIG_2}, // Set Acc Data Rates, Enable Acc LPF , Bandwidth 184Hz
00074         {0x30, MPUREG_INT_PIN_CFG},    //
00075         //{0x40, MPUREG_I2C_MST_CTRL},   // I2C Speed 348 kHz
00076         //{0x20, MPUREG_USER_CTRL},      // Enable AUX
00077         {0x20, MPUREG_USER_CTRL},       // I2C Master mode
00078         {0x0D, MPUREG_I2C_MST_CTRL}, //  I2C configuration multi-master  IIC 400KHz
00079 
00080         {AK8963_I2C_ADDR, MPUREG_I2C_SLV0_ADDR},  //Set the I2C slave addres of AK8963 and set for write.
00081         //{0x09, MPUREG_I2C_SLV4_CTRL},
00082         //{0x81, MPUREG_I2C_MST_DELAY_CTRL}, //Enable I2C delay
00083 
00084         {AK8963_CNTL2, MPUREG_I2C_SLV0_REG}, //I2C slave 0 register address from where to begin data transfer
00085         {0x01, MPUREG_I2C_SLV0_DO}, // Reset AK8963
00086         {0x81, MPUREG_I2C_SLV0_CTRL},  //Enable I2C and set 1 byte
00087 
00088         {AK8963_CNTL1, MPUREG_I2C_SLV0_REG}, //I2C slave 0 register address from where to begin data transfer
00089         {0x12, MPUREG_I2C_SLV0_DO}, // Register value to continuous measurement in 16bit
00090         {0x81, MPUREG_I2C_SLV0_CTRL}  //Enable I2C and set 1 byte
00091 
00092     };
00093     spi.format(8,0);
00094     spi.frequency(1000000);
00095 
00096     for(i=0; i<MPU_InitRegNum; i++) {
00097         WriteReg(MPU_Init_Data[i][1], MPU_Init_Data[i][0]);
00098         wait(0.001);  //I2C must slow down the write speed, otherwise it won't work
00099     }
00100 
00101     set_acc_scale(2);
00102     set_gyro_scale(250);
00103 
00104     //AK8963_calib_Magnetometer();  //Can't load this function here , strange problem?
00105     return 0;
00106 }
00107 /*-----------------------------------------------------------------------------------------------
00108                                 ACCELEROMETER SCALE
00109 usage: call this function at startup, after initialization, to set the right range for the
00110 accelerometers. Suitable ranges are:
00111 BITS_FS_2G
00112 BITS_FS_4G
00113 BITS_FS_8G
00114 BITS_FS_16G
00115 returns the range set (2,4,8 or 16)
00116 -----------------------------------------------------------------------------------------------*/
00117 unsigned int mpu9250_spi::set_acc_scale(int scale)
00118 {
00119     unsigned int temp_scale;
00120     WriteReg(MPUREG_ACCEL_CONFIG, scale);
00121 
00122     switch (scale) {
00123         case BITS_FS_2G:
00124             acc_divider=16384;
00125             break;
00126         case BITS_FS_4G:
00127             acc_divider=8192;
00128             break;
00129         case BITS_FS_8G:
00130             acc_divider=4096;
00131             break;
00132         case BITS_FS_16G:
00133             acc_divider=2048;
00134             break;
00135     }
00136     temp_scale=WriteReg(MPUREG_ACCEL_CONFIG|READ_FLAG, 0x00);
00137 
00138     switch (temp_scale) {
00139         case BITS_FS_2G:
00140             temp_scale=2;
00141             break;
00142         case BITS_FS_4G:
00143             temp_scale=4;
00144             break;
00145         case BITS_FS_8G:
00146             temp_scale=8;
00147             break;
00148         case BITS_FS_16G:
00149             temp_scale=16;
00150             break;
00151     }
00152     return temp_scale;
00153 }
00154 
00155 
00156 /*-----------------------------------------------------------------------------------------------
00157                                 GYROSCOPE SCALE
00158 usage: call this function at startup, after initialization, to set the right range for the
00159 gyroscopes. Suitable ranges are:
00160 BITS_FS_250DPS
00161 BITS_FS_500DPS
00162 BITS_FS_1000DPS
00163 BITS_FS_2000DPS
00164 returns the range set (250,500,1000 or 2000)
00165 -----------------------------------------------------------------------------------------------*/
00166 unsigned int mpu9250_spi::set_gyro_scale(int scale)
00167 {
00168     unsigned int temp_scale;
00169     WriteReg(MPUREG_GYRO_CONFIG, scale);
00170     switch (scale) {
00171         case BITS_FS_250DPS:
00172             gyro_divider=131;
00173             break;
00174         case BITS_FS_500DPS:
00175             gyro_divider=65.5;
00176             break;
00177         case BITS_FS_1000DPS:
00178             gyro_divider=32.8;
00179             break;
00180         case BITS_FS_2000DPS:
00181             gyro_divider=16.4;
00182             break;
00183     }
00184     temp_scale=WriteReg(MPUREG_GYRO_CONFIG|READ_FLAG, 0x00);
00185     switch (temp_scale) {
00186         case BITS_FS_250DPS:
00187             temp_scale=250;
00188             break;
00189         case BITS_FS_500DPS:
00190             temp_scale=500;
00191             break;
00192         case BITS_FS_1000DPS:
00193             temp_scale=1000;
00194             break;
00195         case BITS_FS_2000DPS:
00196             temp_scale=2000;
00197             break;
00198     }
00199     return temp_scale;
00200 }
00201 
00202 
00203 /*-----------------------------------------------------------------------------------------------
00204                                 WHO AM I?
00205 usage: call this function to know if SPI is working correctly. It checks the I2C address of the
00206 mpu9250 which should be 104 when in SPI mode.
00207 returns the I2C address (104)
00208 -----------------------------------------------------------------------------------------------*/
00209 unsigned int mpu9250_spi::whoami()
00210 {
00211     unsigned int response;
00212     response=WriteReg(MPUREG_WHOAMI|READ_FLAG, 0x00);
00213     return response;
00214 }
00215 
00216 
00217 /*-----------------------------------------------------------------------------------------------
00218                                 READ ACCELEROMETER
00219 usage: call this function to read accelerometer data. Axis represents selected axis:
00220 0 -> X axis
00221 1 -> Y axis
00222 2 -> Z axis
00223 -----------------------------------------------------------------------------------------------*/
00224 void mpu9250_spi::read_acc()
00225 {
00226     uint8_t response[6];
00227     int16_t bit_data;
00228     float data;
00229     int i;
00230     ReadRegs(MPUREG_ACCEL_XOUT_H,response,6);
00231     for(i=0; i<3; i++) {
00232         bit_data=((int16_t)response[i*2]<<8)|response[i*2+1];
00233         data=(float)bit_data;
00234         accelerometer_data[i]=data/acc_divider;
00235         accelerometer_data[i]=0.1*accelerometer_data[i]+0.9*accelerometer_data_prev[i];
00236         accelerometer_data_prev[i]=accelerometer_data[i];
00237     }
00238 
00239 }
00240 
00241 /*-----------------------------------------------------------------------------------------------
00242                                 READ GYROSCOPE
00243 usage: call this function to read gyroscope data. Axis represents selected axis:
00244 0 -> X axis
00245 1 -> Y axis
00246 2 -> Z axis
00247 -----------------------------------------------------------------------------------------------*/
00248 void mpu9250_spi::read_rot()
00249 {
00250     uint8_t response[6];
00251     int16_t bit_data;
00252     float data;
00253     int i;
00254     ReadRegs(MPUREG_GYRO_XOUT_H,response,6);
00255     for(i=0; i<3; i++) {
00256         bit_data=((int16_t)response[i*2]<<8)|response[i*2+1];
00257         data=(float)bit_data;
00258         gyroscope_data[i]=data;
00259     }
00260 
00261 }
00262 
00263 /*-----------------------------------------------------------------------------------------------
00264                                 READ TEMPERATURE
00265 usage: call this function to read temperature data.
00266 returns the value in °C
00267 -----------------------------------------------------------------------------------------------*/
00268 void mpu9250_spi::read_temp()
00269 {
00270     uint8_t response[2];
00271     int16_t bit_data;
00272     float data;
00273     ReadRegs(MPUREG_TEMP_OUT_H,response,2);
00274 
00275     bit_data=((int16_t)response[0]<<8)|response[1];
00276     data=(float)bit_data;
00277     Temperature=(data/340)+36.53;
00278     deselect();
00279 }
00280 
00281 /*-----------------------------------------------------------------------------------------------
00282                                 READ ACCELEROMETER CALIBRATION
00283 usage: call this function to read accelerometer data. Axis represents selected axis:
00284 0 -> X axis
00285 1 -> Y axis
00286 2 -> Z axis
00287 returns Factory Trim value
00288 -----------------------------------------------------------------------------------------------*/
00289 void mpu9250_spi::calib_acc()
00290 {
00291     uint8_t response[4];
00292     int temp_scale;
00293     //READ CURRENT ACC SCALE
00294     temp_scale=WriteReg(MPUREG_ACCEL_CONFIG|READ_FLAG, 0x00);
00295     set_acc_scale(BITS_FS_8G);
00296     //ENABLE SELF TEST need modify
00297     //temp_scale=WriteReg(MPUREG_ACCEL_CONFIG, 0x80>>axis);
00298 
00299     ReadRegs(MPUREG_SELF_TEST_X,response,4);
00300     calib_data[0]=((response[0]&11100000)>>3)|((response[3]&00110000)>>4);
00301     calib_data[1]=((response[1]&11100000)>>3)|((response[3]&00001100)>>2);
00302     calib_data[2]=((response[2]&11100000)>>3)|((response[3]&00000011));
00303 
00304     set_acc_scale(temp_scale);
00305 }
00306 uint8_t mpu9250_spi::AK8963_whoami()
00307 {
00308     uint8_t response;
00309     WriteReg(MPUREG_I2C_SLV0_ADDR,AK8963_I2C_ADDR|READ_FLAG); //Set the I2C slave addres of AK8963 and set for read.
00310     WriteReg(MPUREG_I2C_SLV0_REG, AK8963_WIA); //I2C slave 0 register address from where to begin data transfer
00311     WriteReg(MPUREG_I2C_SLV0_CTRL, 0x81); //Read 1 byte from the magnetometer
00312 
00313     //WriteReg(MPUREG_I2C_SLV0_CTRL, 0x81);    //Enable I2C and set bytes
00314     wait(0.001);
00315     response=WriteReg(MPUREG_EXT_SENS_DATA_00|READ_FLAG, 0x00);    //Read I2C
00316     //ReadRegs(MPUREG_EXT_SENS_DATA_00,response,1);
00317     //response=WriteReg(MPUREG_I2C_SLV0_DO, 0x00);    //Read I2C
00318 
00319     return response;
00320 }
00321 double* mpu9250_spi::AK8936_read_Orientation(double *getdata)
00322 {
00323 
00324     double gx = accelerometer_data[0];
00325     double gy = accelerometer_data[1];
00326     double gz = accelerometer_data[2];
00327     double mx = Magnetometer[0];//-centorx;
00328     double my = Magnetometer[1];//-centory;
00329     double mz = Magnetometer[2];//-centorz;
00330     double g0x=0.01,g0y=0.001,g0z=0.99;
00331     double Gproduct = gx*g0x+gy*g0y+gz*g0z;
00332     double Glengh = sqrt(gx*gx+gy*gy+gz*gz);
00333     double G0lengh =sqrt(g0x*g0x+g0y*g0y+g0z*g0z);
00334     double nx = (gy * g0z - gz * g0y);
00335     double ny = (gz * g0x - gx * g0z);
00336     double nz = (gx * g0y - gy * g0x);
00337     double GPlengh = sqrt(nx*nx+ny*ny+nz*nz);
00338     nx/=GPlengh;
00339     ny/=GPlengh;
00340     nz/=GPlengh;
00341     double accang = acos((Gproduct)/(fabs(Glengh)*fabs(G0lengh)));/*
00342     double hx=(nx*nx*(1-cos(accang))+cos(accang))*mx + (nx*ny*(1-cos(accang))+nz*sin(accang))*my + (nz*nx*(1-cos(accang))+ny*sin(accang))*mz;
00343     double hy=(nx*ny*(1-cos(accang))+nz*sin(accang))*mx + (ny*ny*(1-cos(accang))+cos(accang))*my + (ny*nz*(1-cos(accang))+nx*sin(accang))*mz;*/
00344     double Mrot[3][3] = {
00345         {nx*nx*(1-cos(accang))+cos(accang)    , nx*ny*(1-cos(accang))+nz*sin(accang) ,nz*nx*(1-cos(accang))+ny*sin(accang)},
00346         {nx*ny*(1-cos(accang))+nz*sin(accang) , ny*ny*(1-cos(accang))+cos(accang)    ,ny*nz*(1-cos(accang))+nx*sin(accang)},
00347         {nz*nx*(1-cos(accang))+ny*sin(accang) , ny*nz*(1-cos(accang))+nx*sin(accang) ,nz*nz*(1-cos(accang))+cos(accang)}
00348     };
00349     double MrotD[3][3];
00350     double temp[3][3];
00351     for(int i=0; i<3; i++)
00352         for(int j=0; j<3; j++) {
00353             temp[j][i]=Mrot[i][j];
00354             MrotD[j][i]=temp[j][i];
00355         }
00356     double hx = MrotD[0][0]*mx+MrotD[0][1]*my+MrotD[0][2]*mz;
00357     double hy = MrotD[1][0]*mx+MrotD[1][1]*my+MrotD[1][2]*mz;
00358     double hz = MrotD[2][0]*mx+MrotD[2][1]*my+MrotD[2][2]*mz;
00359     double heading = atan2(hy,hx)*180/3.14;
00360     if (heading > 0)
00361         heading = 360 - heading;
00362     else
00363         heading = -heading;
00364     float pitch = atan(-hx/sqrt(hy*hy+hz*hz))*180/3.14; //invert gx because +pitch is up. range is +/-90 degrees
00365     float roll = atan(hy/sqrt(hx*hx+hz*hz))*180/3.14;   // right side down is +roll
00366     if (gz > 0)
00367     {
00368         if ( roll > 0)
00369             roll = 180 - roll;
00370         else
00371             roll = -180 - roll;
00372     }
00373      getdata[0]=heading;
00374      getdata[1]=pitch;
00375      getdata[2]=roll;
00376      return getdata;
00377 }
00378 void mpu9250_spi::AK8963_setoffset(int x,double offset)
00379 {
00380     if((x<0)||(x>3))return;
00381     Magnetometer_offset[x]+=offset;
00382 }
00383 void mpu9250_spi::AK8963_calib_Magnetometer()
00384 {
00385     uint8_t response[3];
00386     float data;
00387     int i;
00388 
00389     WriteReg(MPUREG_I2C_SLV0_ADDR,AK8963_I2C_ADDR|READ_FLAG); //Set the I2C slave addres of AK8963 and set for read.
00390     WriteReg(MPUREG_I2C_SLV0_REG, AK8963_ASAX); //I2C slave 0 register address from where to begin data transfer
00391     WriteReg(MPUREG_I2C_SLV0_CTRL, 0x83); //Read 3 bytes from the magnetometer
00392 
00393     //WriteReg(MPUREG_I2C_SLV0_CTRL, 0x81);    //Enable I2C and set bytes
00394     wait(0.001);
00395     //response[0]=WriteReg(MPUREG_EXT_SENS_DATA_01|READ_FLAG, 0x00);    //Read I2C
00396     ReadRegs(MPUREG_EXT_SENS_DATA_00,response,3);
00397 
00398     //response=WriteReg(MPUREG_I2C_SLV0_DO, 0x00);    //Read I2C
00399     for(i=0; i<3; i++) {
00400         data=response[i];
00401         Magnetometer_ASA[i]=((data-128)/256+1)*Magnetometer_Sensitivity_Scale_Factor;
00402     }
00403 }
00404 void mpu9250_spi::AK8963_read_Magnetometer()
00405 {
00406     uint8_t response[7];
00407     int16_t bit_data;
00408     float data;
00409     int i;
00410 
00411     WriteReg(MPUREG_I2C_SLV0_ADDR,AK8963_I2C_ADDR|READ_FLAG); //Set the I2C slave addres of AK8963 and set for read.
00412     WriteReg(MPUREG_I2C_SLV0_REG, AK8963_HXL); //I2C slave 0 register address from where to begin data transfer
00413     WriteReg(MPUREG_I2C_SLV0_CTRL, 0x87); //Read 6 bytes from the magnetometer
00414 
00415     wait(0.001);
00416     ReadRegs(MPUREG_EXT_SENS_DATA_00,response,7);
00417     //must start your read from AK8963A register 0x03 and read seven bytes so that upon read of ST2 register 0x09 the AK8963A will unlatch the data registers for the next measurement.
00418     for(i=0; i<3; i++) {
00419         bit_data=((int16_t)response[i*2+1]<<8)|response[i*2];
00420         data=(float)bit_data;
00421         Magnetometer[i]=data*Magnetometer_ASA[i]-Magnetometer_offset[i];
00422     }
00423 }
00424 void mpu9250_spi::read_all()
00425 {
00426     uint8_t response[21];
00427     int16_t bit_data;
00428     float data;
00429     int i;
00430 
00431     //Send I2C command at first
00432     WriteReg(MPUREG_I2C_SLV0_ADDR,AK8963_I2C_ADDR|READ_FLAG); //Set the I2C slave addres of AK8963 and set for read.
00433     WriteReg(MPUREG_I2C_SLV0_REG, AK8963_HXL); //I2C slave 0 register address from where to begin data transfer
00434     WriteReg(MPUREG_I2C_SLV0_CTRL, 0x87); //Read 7 bytes from the magnetometer
00435     //must start your read from AK8963A register 0x03 and read seven bytes so that upon read of ST2 register 0x09 the AK8963A will unlatch the data registers for the next measurement.
00436 
00437     //wait(0.001);
00438     ReadRegs(MPUREG_ACCEL_XOUT_H,response,21);
00439     //Get accelerometer value
00440     for(i=0; i<3; i++) {
00441         bit_data=((int16_t)response[i*2]<<8)|response[i*2+1];
00442         data=(float)bit_data;
00443         accelerometer_data[i]=data/acc_divider;
00444         //accelerometer_data[i]=0.1*accelerometer_data[i]+0.9*accelerometer_data_prev[i];
00445         //accelerometer_data_prev[i]=accelerometer_data[i];
00446     }
00447     //Get temperature
00448     bit_data=((int16_t)response[i*2]<<8)|response[i*2+1];
00449     data=(float)bit_data;
00450     Temperature=((data-21)/333.87)+21;
00451     //Get gyroscop value
00452     for(i=4; i<7; i++) {
00453         bit_data=((int16_t)response[i*2]<<8)|response[i*2+1];
00454         data=(float)bit_data;
00455         gyroscope_data[i-4]=data/gyro_divider;
00456     }
00457     //Get Magnetometer value
00458     for(i=7; i<10; i++) {
00459         bit_data=((int16_t)response[i*2+1]<<8)|response[i*2];
00460         data=(float)bit_data;
00461         Magnetometer[i-7]=data*Magnetometer_ASA[i-7]-Magnetometer_offset[i-7];
00462     }
00463 }
00464 
00465 
00466 
00467 void mpu9250_spi::SpeedSet()
00468 {
00469     get_speedrate();
00470     read_acc();
00471     /*for(int i=0;i<3;i++)
00472         ratespeed[i]=acc[i];*/
00473     double S[3];
00474     speedT.stop();
00475     for(int i=0; i<3; i++) {
00476 
00477         S[i]  =((double)(ratespeed[i]+prev_ratespeed[i])*speedT.read()/2);
00478         speed[i]+=(double)S[i];
00479         speed[i]=floor(speed[i]*100.0)/100.0;
00480         Synthesis_speed[i]+=(double)S[i];
00481         Synthesis_speed[i]=0.9*(double)(Synthesis_speed[i]+(double)ratespeed[i]/100.5)+0.1*ratespeed[i];
00482         kalman_speed[i]=kalmaspeed[i].getAngle((double)kalman_speed[i], (double)ratespeed[i], (double)angleT.read()*1000);
00483         comp_speed[i]=kalman_speed[i]*0.01+Synthesis_speed[i]*0.01+comp_speed[i]*0.98;
00484         prev_ratespeed[i]=ratespeed[i];
00485     }
00486     speedT.reset();
00487     speedT.start();
00488 }
00489 void mpu9250_spi::MeterSet()
00490 {
00491     double S[3];
00492     for(int i = 0 ; i<3 ; i++)
00493         ratemeter[i]=comp_speed[i]*1000;
00494     meterT.stop();
00495     for(int i=0; i<3; i++) {
00496 
00497         S[i]  =((double)(ratemeter[i]+prev_ratemeter[i])*meterT.read()/2);
00498         meter[i]+=(double)S[i];
00499         Synthesis_meter[i]+=(double)S[i];
00500         Synthesis_meter[i]=0.9*(double)(Synthesis_meter[i]+(double)ratemeter[i]/100.5)+0.1*meter[i];
00501         kalman_meter[i]=kalmameter[i].getAngle((double)kalman_meter[i], (double)ratemeter[i], (double)angleT.read()*1000);
00502         comp_meter[i]=kalman_meter[i]*0.01+Synthesis_meter[i]*0.01+comp_meter[i]*0.98;
00503         prev_ratemeter[i]=ratemeter[i];
00504     }
00505     meterT.reset();
00506     meterT.start();
00507 }
00508 
00509 
00510 
00511 void mpu9250_spi::MPU_setup()
00512 {
00513     z_offset=2;
00514     x_offset=0;
00515     y_offset=0;
00516     uint8_t buffer[6];
00517 
00518     for(int i=0; i<sampleNum; i++) {
00519         ReadRegs(MPUREG_ACCEL_XOUT_H,buffer,6);
00520         int Xacc = (int)buffer[1] << 8 | (int)buffer[0];
00521         int Yacc = (int)buffer[3] << 8 | (int)buffer[2];
00522         int Zacc = (int)buffer[5] << 8 | (int)buffer[4]-255;
00523         if((int)Xacc-x_offset>xnoise)
00524             xnoise=(int)Xacc-x_offset;
00525         else if((int)Xacc-x_offset<-xnoise)
00526             xnoise=-(int)Xacc-x_offset;
00527 
00528         if((int)Yacc-y_offset>ynoise)
00529             ynoise=(int)Yacc-y_offset;
00530         else if((int)Yacc-y_offset<-ynoise)
00531             ynoise=-(int)Yacc-y_offset;
00532 
00533         if((int)Zacc-z_offset>znoise)
00534             znoise=(int)Zacc-z_offset;
00535         else if((int)Zacc-z_offset<-znoise)
00536             znoise=-(int)Zacc-z_offset;
00537     }
00538 
00539 
00540 }
00541 void mpu9250_spi::MPU_setnum(int Num,float time,double rate)
00542 {
00543     sampleNum=Num;
00544     sampleTime=time;
00545     Rate=rate;
00546 }
00547 
00548 
00549 void mpu9250_spi::get_angle_acc()
00550 {
00551     //short data[3];
00552     //get_axis_acc(data);
00553     float R = sqrt(pow((float)accelerometer_data[0],2) + pow((float)accelerometer_data[1],2) + pow((float)accelerometer_data[2],2));
00554     angle_acc[0]=atan2(accelerometer_data[0],accelerometer_data[2])*(180 / 3.1415);
00555     angle_acc[1]=atan2(accelerometer_data[1],accelerometer_data[2])*(180 / 3.1415);
00556     angle_acc[2]=atan2(accelerometer_data[2],accelerometer_data[0])*(180 / 3.1415);
00557     /*angle_acc[1] =   -((180 / 3.1415) * acos((float)accelerometer_data[1] / R)-90);                                    // roll - angle of magnetic field vector in x direction
00558     angle_acc[0] =   (180 / 3.1415) * acos((float)accelerometer_data[0] / R)-90;                                    // pitch - angle of magnetic field vector in y direction
00559     angle_acc[2] =   (180 / 3.1415) * acos((float)accelerometer_data[2] / R); //*/
00560     /*
00561     angle_acc[0] = atan2(accelerometer_data[0],sqrt(pow((float)accelerometer_data[1],2)+pow((float)accelerometer_data[2],2)))*180/3.1415;
00562     angle_acc[1] = atan2(accelerometer_data[1],sqrt(pow((float)accelerometer_data[0],2)+pow((float)accelerometer_data[2],2)))*180/3.1415;
00563     angle_acc[2] = atan2(sqrt(pow((float)accelerometer_data[1],2)+pow((float)accelerometer_data[2],2)),accelerometer_data[2])*180/3.1415;
00564     */
00565     
00566 }
00567 void mpu9250_spi::get_rate()
00568 {
00569     uint8_t response[6];
00570     short offset_t[3]= {0,0,0};
00571     ReadRegs(MPUREG_GYRO_XOUT_H,response,6);
00572     for(int i=0; i<3; i++) {
00573         short bit_data=((int16_t)response[i*2]<<8)|response[i*2+1];
00574         rate[i]=((double)(bit_data*0.01)-offset_t[i])/gyro_divider;;
00575         //printf("%d",rate[i]);
00576     }
00577 }
00578 
00579 void mpu9250_spi::get_speedrate()
00580 {
00581     uint8_t response[6];
00582     short offset_t[3]= {0,0,0};
00583     ReadRegs(MPUREG_ACCEL_XOUT_H,response,6);
00584     for(int i=0; i<3; i++) {
00585         short bit_data=((int16_t)response[i*2]<<8)|response[i*2+1];
00586         ratespeed[i]=(short)(bit_data*0.01)-offset_t[i];
00587     }
00588 }
00589 void mpu9250_spi::get_angle(double *x,double *y,double *z)
00590 {
00591     *x=(floor(angle[0]*100.0)/100.0);
00592     *y=(floor(angle[1]*100.0)/100.0);
00593     *z=(floor(angle[2]*100.0)/100.0);
00594 }
00595 void mpu9250_spi::set_angle()
00596 {
00597     get_rate();
00598     read_acc();
00599     get_angle_acc();
00600     double S[3];
00601     angleT.stop();
00602     for(int i=0; i<3; i++) {
00603         //rate[i]=gyroscope_data[i]*0.01;
00604         double angA=angle_acc[i];
00605         S[i]  =((double)(rate[i]+prev_rate[i])*angleT.read()/2);
00606         S[i]=(floor(S[i]*100.0)/100.0);//-offset_angle[i];
00607         if(i == 2) angle[i] += S[1]*gyro_divider;
00608         else angle[i] += S[i]*gyro_divider;;//(floor(S[i]*10000.0)/10000.0);//-offset_angle[i];
00609         //angle[i]+=(double)S[i];
00610         Synthesis_angle[i]+=(double)angle[i];
00611         Synthesis_angle[i]=0.92*(double)(Synthesis_angle[i]+(double)rate[i])+0.08*angA;
00612         kalman_angle[i]=kalma[i].getAngle((double)angA, (double)rate[i], (double)angleT.read_ms());
00613         comp_angle[i]=kalman_angle[i];//Synthesis_angle[i]*0.5+kalman_angle[i]*0+angle[i]*0.3+angle_acc[i]*0.2;
00614         comp_angle[i]=kalman_angle[i]*0.4+Synthesis_angle[i]*0.4+comp_angle[i]*0.2;
00615         prev_rate[i]=rate[i];
00616     }
00617     angleT.reset();
00618     angleT.start();
00619 }
00620 void mpu9250_spi::set_angleoffset()
00621 {
00622     double axis[3],offseta[3];
00623     offseta[0]=offseta[1]=offseta[2]=0;
00624     offset_angle[0]=0;
00625     offset_angle[1]=0;
00626     offset_angle[2]=0;
00627     for(int i=0; i<sampleNum; i++) {
00628         offseta[0]+=rate[0];
00629         offseta[1]+=rate[1];
00630         offseta[2]+=rate[2];
00631     }
00632     offset_angle[0]=offseta[0]/sampleNum;
00633     offset_angle[1]=offseta[1]/sampleNum;
00634     offset_angle[2]=offseta[2]/sampleNum;
00635     offset_angle[0]=(floor(offset_angle[0]*100.0)/100.0);
00636     offset_angle[1]=(floor(offset_angle[1]*100.0)/100.0);
00637     offset_angle[2]=(floor(offset_angle[2]*100.0)/100.0);
00638     angle[0]=0;
00639     angle[1]=0;
00640     angle[2]=0;
00641 }
00642 void mpu9250_spi::set_noise()
00643 {
00644     short gyro[3];
00645     noise[0]=noise[1]=noise[2]=0;
00646     uint8_t response[6];
00647     for(int i=0; i<sampleNum; i++) {
00648 
00649         for(int t=0; t<3; t++) {
00650             for(int i=0; i<3; i++) {
00651                 short bit_data=((int16_t)response[i*2]<<8)|response[i*2+1];
00652                 gyro[i]=(short)bit_data;
00653             }
00654             if((int)gyro[t]>noise[t])
00655                 noise[t]=(int)gyro[t];
00656             else if((int)gyro[t]<-noise[t])
00657                 noise[t]=-(int)gyro[t];
00658         }
00659     }
00660     noise[0]*=sampleTime;
00661     noise[1]*=sampleTime;
00662     noise[2]*=sampleTime;
00663 }
00664 void mpu9250_spi::set_offset()
00665 {
00666     short axis[3],offseta[3];
00667     uint8_t response[6];
00668     offseta[0]=0;
00669     offseta[1]=0;
00670     offseta[2]=0;
00671     for(int i=0; i<sampleNum; i++) {
00672         for(int i=0; i<3; i++) {
00673             short bit_data=((int16_t)response[i*2]<<8)|response[i*2+1];
00674             axis[i]=(short)bit_data;
00675         }
00676         offseta[0]+=axis[0];
00677         offseta[1]+=axis[1];
00678         offseta[2]+=axis[2];
00679     }
00680     offset[0]=offseta[0]/sampleNum;
00681     offset[1]=offseta[1]/sampleNum;
00682     offset[2]=offseta[2]/sampleNum;
00683 }
00684 mpu9250_spi::kalman::kalman(void)
00685 {
00686     P[0][0]     = 0;
00687     P[0][1]     = 0;
00688     P[1][0]     = 0;
00689     P[1][1]     = 0;
00690 
00691     angle       = 0;
00692     bias        = 0;
00693 
00694     Q_angle     = 0.001;
00695     Q_gyroBias  = 0.003;
00696     R_angle     = 0.03;
00697 }
00698 
00699 double mpu9250_spi::kalman::getAngle(double newAngle, double newRate, double dt)
00700 {
00701     //predict the angle according to the gyroscope
00702     rate         = newRate - bias;
00703     angle        = dt * rate;
00704     //update the error covariance
00705     P[0][0]     += dt * (dt * P[1][1] * P[0][1] - P[1][0] + Q_angle);
00706     P[0][1]     -= dt * P[1][1];
00707     P[1][0]     -= dt * P[1][1];
00708     P[1][1]     += dt * Q_gyroBias;
00709     //difference between the predicted angle and the accelerometer angle
00710     y            = newAngle - angle;
00711     //estimation error
00712     S            = P[0][0] + R_angle;
00713     //determine the kalman gain according to the error covariance and the distrust
00714     K[0]         = P[0][0]/S;
00715     K[1]         = P[1][0]/S;
00716     //adjust the angle according to the kalman gain and the difference with the measurement
00717     angle       += K[0] * y;
00718     bias        += K[1] * y;
00719     //update the error covariance
00720     P[0][0]     -= K[0] * P[0][0];
00721     P[0][1]     -= K[0] * P[0][1];
00722     P[1][0]     -= K[1] * P[0][0];
00723     P[1][1]     -= K[1] * P[0][1];
00724 
00725     return angle;
00726 }
00727 void mpu9250_spi::kalman::setAngle(double newAngle)
00728 {
00729     angle = newAngle;
00730 };
00731 void mpu9250_spi::kalman::setQangle(double newQ_angle)
00732 {
00733     Q_angle = newQ_angle;
00734 };
00735 void mpu9250_spi::kalman::setQgyroBias(double newQ_gyroBias)
00736 {
00737     Q_gyroBias = newQ_gyroBias;
00738 };
00739 void mpu9250_spi::kalman::setRangle(double newR_angle)
00740 {
00741     R_angle = newR_angle;
00742 };
00743 
00744 double mpu9250_spi::kalman::getRate(void)
00745 {
00746     return rate;
00747 };
00748 double mpu9250_spi::kalman::getQangle(void)
00749 {
00750     return Q_angle;
00751 };
00752 double mpu9250_spi::kalman::getQbias(void)
00753 {
00754     return Q_gyroBias;
00755 };
00756 double mpu9250_spi::kalman::getRangle(void)
00757 {
00758     return R_angle;
00759 };
00760 
00761 /*-----------------------------------------------------------------------------------------------
00762                                 SPI SELECT AND DESELECT
00763 usage: enable and disable mpu9250 communication bus
00764 -----------------------------------------------------------------------------------------------*/
00765 void mpu9250_spi::select()
00766 {
00767     //Set CS low to start transmission (interrupts conversion)
00768     cs = 0;
00769 }
00770 void mpu9250_spi::deselect()
00771 {
00772     //Set CS high to stop transmission (restarts conversion)
00773     cs = 1;
00774 }