Library for the BME220

Fork of BME680 by CHENGQI YANG

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BME680.cpp Source File

BME680.cpp

00001 #include "BME680.h"
00002 
00003 // no idea why this is not the same as the PDF
00004 //const double BME680::const_array1[16] = {1,1,1,1,1,0.99,1,0.992,1,1,0.998,0.995,1,0.99,1,1};
00005 //const double BME680::const_array2[16] = {8000000,4000000,2000000,1000000,499500.4995,248262.1648,125000,63004.03226,31281.28128,15625,7812.5,3906.25,1953.125,976.5625,488.28125,244.140625};
00006 
00007 const uint64_t BME680::lookup_k1_range[16] = {
00008     2147483647UL, 2147483647UL, 2147483647UL, 2147483647UL, 2147483647UL,
00009     2126008810UL, 2147483647UL, 2130303777UL, 2147483647UL, 2147483647UL,
00010     2143188679UL, 2136746228UL, 2147483647UL, 2126008810UL, 2147483647UL,
00011     2147483647UL
00012 };
00013 
00014 const uint64_t BME680::lookup_k2_range[16] = {
00015     4096000000UL, 2048000000UL, 1024000000UL, 512000000UL,
00016     255744255UL, 127110228UL, 64000000UL, 32258064UL, 16016016UL,
00017     8000000UL, 4000000UL, 2000000UL, 1000000UL, 500000UL, 250000UL,
00018     125000UL
00019 };
00020 
00021 const double BME680::_lookup_k1_range[BME680_GAS_RANGE_RL_LENGTH] = {
00022     0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8,
00023     0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0
00024 };
00025 
00026 const double BME680::_lookup_k2_range[BME680_GAS_RANGE_RL_LENGTH] = {
00027     0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8,
00028     -0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
00029 };
00030 
00031 void BME680::setParallelMode()
00032 {
00033     //Select oversampling for T, P, H
00034     setOversamplingTemperature(2);
00035     setOversamplingPressure(5);
00036     setOversamplingHumidity(1);
00037     
00038     //Select IIR filter for pressure & temperature
00039     setIIRfilterCoefficient(0);
00040     
00041     //Enable gas coversion
00042     runGasConversion();
00043     
00044     //Select heater set-points to be used
00045     setHeaterProfile(1);
00046     
00047     //Set wait time between TPHG submeasurements
00048     //Set gas_wait_shared<7:0> (time base unit is 0.477ms)
00049     setGasWaitShared(32, 1);
00050     
00051     //Define heater-on times
00052     //Convert durations to register codes
00053     //Set gas_wait_x<7:0> (time base unit is ms)
00054     setGasWaitTime(0,25,4);
00055     
00056 #ifdef FIXED_POINT_COMPENSATION
00057     setTargetHeaterResistance(0, convertTemperatureResistanceInt(350,30));
00058 #else
00059     setTargetHeaterResistance(0, convertTemperatureResistanceDouble(350,30));
00060 #endif
00061 
00062     setMode(2);
00063 }
00064 
00065 void BME680::setForcedMode()
00066 {
00067     //Select oversampling for T, P, H
00068     setOversamplingTemperature(2);
00069     setOversamplingPressure(5);
00070     setOversamplingHumidity(1);
00071 
00072     //Select IIR filter for pressure & temperature
00073     setIIRfilterCoefficient(0);
00074 
00075     //Enable gas coversion
00076     runGasConversion();
00077 
00078     //Select heater set-points to be used
00079     setHeaterProfile(1);
00080 
00081     //Define heater-on times
00082     //Convert durations to register codes
00083     //Set gas_wait_x<7:0> (time base unit is ms)
00084     setGasWaitTime(0,25,4);
00085 
00086 #ifdef FIXED_POINT_COMPENSATION
00087     setTargetHeaterResistance(0, convertTemperatureResistanceInt(350,30));
00088 #else
00089     setTargetHeaterResistance(0, convertTemperatureResistanceDouble(350,30));
00090 #endif
00091 
00092     //Set mode to sequential mode
00093     //Set mode<1:0> to 0b01
00094     setMode(1);
00095 }
00096 
00097 void BME680::setSequentialMode()
00098 {
00099     //Select stand-by time between measurements
00100     setWakePeriod(1);
00101 
00102     //Select oversampling for T, P, H
00103     setOversamplingTemperature(2);
00104     setOversamplingPressure(5);
00105     setOversamplingHumidity(1);
00106 
00107     //Select IIR filter for pressure & temperature
00108     setIIRfilterCoefficient(0);
00109 
00110     //Enable gas coversion
00111     runGasConversion();
00112 
00113     //Select heater set-points to be used
00114     setHeaterProfile(1);
00115 
00116     //Define heater-on times
00117     //Convert durations to register codes
00118     //Set gas_wait_x<7:0> (time base unit is ms)
00119     setGasWaitTime(0,25,4);
00120 
00121     //Set heater temperatures
00122     //Convert temperature to register code
00123     //Set res_heat_x<7:0>
00124 
00125 #ifdef FIXED_POINT_COMPENSATION
00126     setTargetHeaterResistance(0, convertTemperatureResistanceInt(350,30));
00127 #else
00128     setTargetHeaterResistance(0, convertTemperatureResistanceDouble(350,30));
00129 #endif
00130 
00131     //Set mode to sequential mode
00132     //Set mode<1:0> to 0b11
00133     setMode(3);
00134 }
00135 
00136 #ifdef FIXED_POINT_COMPENSATION
00137 int32_t BME680::getCompensatedTemperature(int field)
00138 {
00139     uint32_t v_uncomp_temperature_u32 = getUncompensatedTemp1Data(field);
00140 
00141     int32_t var1 = ((int32_t)v_uncomp_temperature_u32 >> 3) - ((int32_t)(par_T1 << 1));
00142     int32_t var2 = (var1 * (int32_t) par_T2) >> 11;
00143     int32_t var3 = ((((var1 >> 1) * (var1 >> 1)) >> 12) * ((int32_t)(par_T3 << 4))) >> 14;
00144     t_fine = var2 + var3;
00145     return ((t_fine * 5) + 128) >> 8;
00146 }
00147 
00148 int16_t BME680::getTemperatureInt(int field)
00149 {
00150     getCompensatedTemperature(field);
00151     return (((t_fine - 122880) * 25) + 128) >> 8;
00152 }
00153 
00154 int32_t BME680::getCompensateHumidity(int field)
00155 {
00156     uint32_t v_uncomp_humidity_u32 = getUncompensatedHumidityData(field);
00157 
00158     int32_t temp_scaled = (t_fine * 5 + 128) >> 8;
00159     int32_t var1 = (int32_t)v_uncomp_humidity_u32 -
00160                    ((int32_t)((int32_t)par_H1 << 4)) -
00161                    (((temp_scaled * (int32_t)par_H3) /
00162                      ((int32_t)100)) >> 1);
00163 
00164     int32_t var2 = ((int32_t)par_H2 *
00165                     (((temp_scaled * (int32_t)par_H4) /
00166                       ((int32_t)100)) + (((temp_scaled *
00167                                            ((temp_scaled * (int32_t)par_H5) /
00168                                             ((int32_t)100))) >> 6) / ((int32_t)100)) + (int32_t)(1 << 14))) >> 10;
00169 
00170     int32_t var3 = var1 * var2;
00171 
00172     int32_t var4 = ((((int32_t)par_H6) << 7) +
00173                     ((temp_scaled * (int32_t)par_H7) /
00174                      ((int32_t)100))) >> 4;
00175 
00176     int32_t var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
00177     int32_t var6 = (var4 * var5) >> 1;
00178 
00179     int32_t humidity_comp = (var3 + var6) >> 12;
00180     if (humidity_comp > BME680_MAX_HUMIDITY_VALUE)
00181         humidity_comp = BME680_MAX_HUMIDITY_VALUE;
00182     else if (humidity_comp < BME680_MIN_HUMIDITY_VALUE)
00183         humidity_comp = BME680_MIN_HUMIDITY_VALUE;
00184 
00185     return humidity_comp;
00186 }
00187 
00188 uint16_t BME680::getHumidityInt(int field)
00189 {
00190     uint32_t v_x1_u32 = (uint32_t) getCompensateHumidity(field);
00191     uint16_t v_x2_u32 = (uint16_t)(v_x1_u32 >> 1);
00192     return v_x2_u32;
00193 }
00194 
00195 int32_t BME680::getCompensatePressure(int field)
00196 {
00197     uint32_t v_uncomp_pressure_u32 = getUncompensatedPressureData(field);
00198 
00199     int32_t var1 = (((int32_t)t_fine) >> 1) - 64000;
00200     int32_t var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * (int32_t)par_P6) >> 2;
00201     var2 = var2 + ((var1 * (int32_t)par_P5) << 1);
00202     var2 = (var2 >> 2) + ((int32_t)par_P4 << 16);
00203     var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) *
00204              ((int32_t)par_P3 << 5)) >> 3) +
00205            (((int32_t)par_P2 * var1) >> 1);
00206     var1 = var1 >> 18;
00207     var1 = ((32768 + var1) * (int32_t)par_P1) >> 15;
00208     int32_t pressure_comp = 1048576 - v_uncomp_pressure_u32;
00209     pressure_comp = (int32_t)((pressure_comp - (var2 >> 12)) * ((int32_t)3125));
00210     int32_t var4 = (1 << 31);
00211     if (pressure_comp >= var4)
00212         pressure_comp = ((pressure_comp / (int32_t)var1) << 1);
00213     else
00214         pressure_comp = ((pressure_comp << 1) / (int32_t)var1);
00215     var1 = ((int32_t)par_P9 * (int32_t)(((pressure_comp >> 3) *
00216                                          (pressure_comp >> 3)) >> 13)) >> 12;
00217     var2 = ((int32_t)(pressure_comp >> 2) *
00218             (int32_t)par_P8) >> 13;
00219     int32_t var3 = ((int32_t)(pressure_comp >> 8) * (int32_t)(pressure_comp >> 8) *
00220                     (int32_t)(pressure_comp >> 8) *
00221                     (int32_t)par_P10) >> 17;
00222 
00223     pressure_comp = (int32_t)(pressure_comp) + ((var1 + var2 + var3 +
00224                     ((int32_t)par_P7 << 7)) >> 4);
00225 
00226     return pressure_comp;
00227 }
00228 
00229 uint32_t BME680::getPressureInt(int field)
00230 {
00231     uint32_t pressure = (uint32_t)getCompensatePressure(field);
00232     pressure = (uint32_t)(pressure >> 1);
00233     return pressure;
00234 }
00235 
00236 uint8_t BME680::convertTemperatureResistanceInt(uint16_t heater, int16_t ambient)
00237 {
00238     uint8_t res_heat = 0;
00239 
00240 
00241     if ((heater >= BME680_GAS_PROFILE_TEMPERATURE_MIN)
00242             && (heater <= BME680_GAS_PROFILE_TEMPERATURE_MAX)) {
00243 
00244         int32_t var1 = (((int32_t)ambient * par_GH3) / 10) << 8;
00245         int32_t var2 = (par_GH1 + 784) *
00246                        (((((par_GH2 + 154009) *
00247                            heater * 5) / 100) + 3276800) / 10);
00248         int32_t var3 = var1 + (var2 >> 1);
00249         int32_t var4 = (var3 / (res_heat_range + 4));
00250 
00251         int32_t var5 = (131 * res_heat_val) + 65536;
00252 
00253         int32_t res_heat_x100 = (int32_t)(((var4 / var5) - 250) * 34);
00254         res_heat = (uint8_t) ((res_heat_x100 + 50) / 100);
00255 
00256     }
00257     return res_heat;
00258 }
00259 
00260 int32_t BME680::getCalculateGasInt(int field)
00261 {
00262     uint8_t gas_range_u8 = getGasResistanceRange(field);
00263     uint16_t gas_adc_u16 = getUncompensatedGasResistanceData(field);
00264 
00265     int64_t var1 = (int64_t)((1340 + (5 * (int64_t)range_switching_error)) *
00266                              ((int64_t)lookup_k1_range[gas_range_u8])) >> 16;
00267     int64_t var2 = (int64_t)((int64_t)gas_adc_u16 << 15) - (int64_t)(1 << 24) + var1;
00268     int32_t gas_res = (int32_t)(((((int64_t)lookup_k2_range[gas_range_u8] *
00269                                    (int64_t)var1) >> 9) + (var2 >> 1)) / var2);
00270     return gas_res;
00271 }
00272 
00273 #else
00274 double BME680::getTemperatureDouble(int field)
00275 {
00276     uint32_t uncom_temperature_u32 = getTemp1Data(field);
00277 
00278     double data1_d  = ((((double)uncom_temperature_u32 / 16384.0)
00279                         - ((double)par_T1 / 1024.0))
00280                        * ((double)par_T2));
00281     /* calculate x2 data */
00282     double data2_d  = (((((double)uncom_temperature_u32 / 131072.0) -
00283                          ((double)par_T1 / 8192.0)) *
00284                         (((double)uncom_temperature_u32 / 131072.0) -
00285                          ((double)par_T1 / 8192.0))) *
00286                        ((double)par_T3 * 16.0));
00287     /* t fine value*/
00288     t_fine = (int32_t)(data1_d + data2_d);
00289     /* compensated temperature data*/
00290     return (data1_d + data2_d) / 5120.0;
00291 }
00292 
00293 double BME680::getHumidityDouble(int field)
00294 {
00295     double comp_temperature = getTemperatureDouble(field);
00296     uint16_t uncom_humidity_u16 = getHumidityData(field);
00297 
00298     double var1 = (double)((double)uncom_humidity_u16) - (((double)
00299                   par_H1 * 16.0) +
00300                   (((double)par_H3 / 2.0)
00301                    * comp_temperature));
00302 
00303     double var2 = var1 * ((double)(
00304                               ((double) par_H2 / 262144.0)
00305                               *(1.0 + (((double)par_H4 / 16384.0)
00306                                        * comp_temperature) + (((double)par_H5
00307                                                / 1048576.0) * comp_temperature
00308                                                * comp_temperature))));
00309     double var3 = (double) par_H6 / 16384.0;
00310     double var4 = (double) par_H7 / 2097152.0;
00311 
00312     double humidity_comp = var2 +
00313                            ((var3 + (var4 * comp_temperature)) * var2 * var2);
00314     if (humidity_comp > BME680_MAX_HUMIDITY_VALUE)
00315         humidity_comp = BME680_MAX_HUMIDITY_VALUE;
00316     else if (humidity_comp < BME680_MIN_HUMIDITY_VALUE)
00317         humidity_comp = BME680_MIN_HUMIDITY_VALUE;
00318     return humidity_comp;
00319 }
00320 
00321 double BME680::getPressureDouble(int field)
00322 {
00323     uint32_t uncom_pressure_u32 = getPressureData(field);
00324 
00325     double data1_d = (((double)t_fine / 2.0) - 64000.0);
00326     double data2_d = data1_d * data1_d * (((double)par_P6) / (131072.0));
00327     data2_d = data2_d + (data1_d * ((double)par_P5) * 2.0);
00328     data2_d = (data2_d / 4.0) + (((double)par_P4) * 65536.0);
00329     data1_d = (((((double)par_P3 * data1_d * data1_d) / 16384.0) + ((double)par_P2 * data1_d)) / 524288.0);
00330     data1_d = ((1.0 + (data1_d / 32768.0)) * ((double)par_P1));
00331     double pressure_comp = (1048576.0 - ((double)uncom_pressure_u32));
00332     /* Avoid exception caused by division by zero */
00333     if ((int)data1_d != 0) {
00334         pressure_comp = (((pressure_comp - (data2_d / 4096.0)) * 6250.0) / data1_d);
00335         data1_d = (((double)par_P9) * pressure_comp * pressure_comp) /  2147483648.0;
00336         data2_d = pressure_comp * (((double)par_P8) / 32768.0);
00337         double data3_d = ((pressure_comp / 256.0) * (pressure_comp / 256.0) * (pressure_comp / 256.0) * (par_P10 / 131072.0));
00338         pressure_comp = (pressure_comp + (data1_d + data2_d + data3_d + ((double)par_P7 * 128.0)) / 16.0);
00339         return pressure_comp;
00340     } else
00341         return 0;
00342 }
00343 
00344 double BME680::convertTemperatureResistanceDouble(uint16_t heater, int16_t ambient)
00345 {
00346     double var1 = 0;
00347     double var2 = 0;
00348     double var3 = 0;
00349     double var4 = 0;
00350     double var5 = 0;
00351     double res_heat = 0;
00352 
00353     if ((heater >= BME680_GAS_PROFILE_TEMPERATURE_MIN)
00354             && (heater <= BME680_GAS_PROFILE_TEMPERATURE_MAX)) {
00355 #ifdef  HEATER_C1_ENABLE
00356         var1 = (((double)par_GH1 / (16.0)) + 49.0);
00357         var2 = ((((double)par_GH2 / (32768.0)) * (0.0005)) + 0.00235);
00358 #endif
00359         var3 = ((double)par_GH3 / (1024.0));
00360         var4 = (var1 * (1.0 + (var2 * (double)heater)));
00361         var5 = (var4 + (var3 * (double)ambient));
00362 
00363 #ifdef  HEATER_C1_ENABLE
00364         res_heat = (uint8_t)(3.4 * ((var5 * (4 / (4 + (double)res_heat_range)) * (1/(1 + ((double)res_heat_val * 0.002)))) - 25));
00365 #else
00366         res_heat = (((var5 * (4.0 / (4.0 + (double)res_heat_range))) - 25.0) * 3.4);
00367 #endif
00368 
00369     }
00370     return (uint8_t)res_heat;
00371 }
00372 
00373 double BME680::getCalculateGasDouble(int field)
00374 {
00375     uint8_t gas_range_u8 = getGasResistanceRange(field);
00376     uint16_t gas_adc_u16 = getGasResistanceData(field);
00377     double gas_res_d = 0;
00378 
00379 
00380 #ifdef HEATER_C1_ENABLE
00381 
00382     double var1 = 0;
00383     double var2 = 0;
00384     double var3 = 0;
00385 
00386 
00387     var1 = (1340.0 + (5.0 * range_switching_error));
00388     var2 = (var1) * (1.0 + _lookup_k1_range[gas_range_u8]/100.0);
00389     var3 = 1.0 + (_lookup_k2_range[gas_range_u8]/100.0);
00390 
00391     gas_res_d = 1.0 / (double)(var3 * (0.000000125) *
00392                                (double)(1 << gas_range_u8)
00393                                * (((((double)gas_adc_u16) - 512.00)/var2) + 1.0));
00394 
00395 #else
00396     gas_res_d = 1.0 / ((0.000000125) * (double)(1 << gas_range_u8) *
00397                        ((((double)(gas_adc_u16) - 512.00) / 1365.3333) + 1.0));
00398 #endif
00399     return gas_res_d;
00400 }
00401 #endif
00402 
00403 
00404 
00405 BME680::BME680(I2C * i2c, bool SDO) : _i2c_bus()
00406 {
00407     _i2c_bus = i2c;
00408     if (SDO)
00409         _addr = 0x77 << 1;
00410     else _addr = 0x76 << 1;
00411 
00412     _i2c_bus->frequency(FREQUENCY_FAST);
00413 }
00414 
00415 bool BME680::init()
00416 {
00417     if (getChipID() != 0x61)
00418         return false;
00419 
00420     uint8_t cali[41];
00421     readRegister(0x89, 25);
00422     memcpy(cali, data, 25);
00423     readRegister(0xE1, 16);
00424     memcpy(cali + 25, data, 16);
00425 
00426     /* read temperature calibration*/
00427     par_T1 = (cali[DIG_T1_MSB_REG] << 8) | cali[DIG_T1_LSB_REG];
00428     par_T2 = (cali[DIG_T2_MSB_REG] << 8) | cali[DIG_T2_LSB_REG];
00429     par_T3 = cali[DIG_T3_REG];
00430 
00431     /* read pressure calibration*/
00432     par_P1 = (cali[DIG_P1_MSB_REG] << 8) | cali[DIG_P1_LSB_REG];
00433     par_P2 = (cali[DIG_P2_MSB_REG] << 8) | cali[DIG_P2_LSB_REG];
00434     par_P3 = cali[DIG_P3_REG];
00435     par_P4 = (cali[DIG_P4_MSB_REG] << 8) | cali[DIG_P4_LSB_REG];
00436     par_P5 = (cali[DIG_P5_MSB_REG] << 8) | cali[DIG_P5_LSB_REG];
00437     par_P6 = cali[DIG_P6_REG];
00438     par_P7 = cali[DIG_P7_REG];
00439     par_P8 = (cali[DIG_P8_MSB_REG] << 8) | cali[DIG_P8_LSB_REG];
00440     par_P9 = (cali[DIG_P9_MSB_REG] << 8) | cali[DIG_P9_LSB_REG];
00441     par_P10 = cali[DIG_P10_REG];
00442 
00443     /* read humidity calibration*/
00444     par_H1 = (cali[DIG_H1_MSB_REG] << 4) | (cali[DIG_H1_LSB_REG] & BME680_BIT_MASK_H1_DATA);
00445     par_H2 = (cali[DIG_H2_MSB_REG] << 4) | (cali[DIG_H2_LSB_REG] >> 4);
00446     par_H3 = cali[DIG_H3_REG];
00447     par_H4 = cali[DIG_H4_REG];
00448     par_H5 = cali[DIG_H5_REG];
00449     par_H6 = cali[DIG_H6_REG];
00450     par_H7 = cali[DIG_H7_REG];
00451 
00452     /* read gas calibration*/
00453     par_GH1 = cali[DIG_GH1_REG];
00454     par_GH2 = (cali[DIG_GH2_MSB_REG] <<8) | cali[DIG_GH2_LSB_REG];
00455     par_GH3 = cali[DIG_GH3_REG];
00456 
00457     /**<resistance calculation*/
00458     readRegister(0x02);
00459     res_heat_range = (data[0] >> 4) & 0x03;
00460 
00461     /**<correction factor*/
00462     readRegister(0x00);
00463     res_heat_val = data[0];
00464 
00465     /**<range switching error*/
00466     readRegister(0x04);
00467     range_switching_error = (data[0] & 0xF0) >> 4;
00468     /*
00469        uint16_t BME680::getParG1()
00470     {
00471        readRegister(0xEB, 2);
00472        return (data[1] << 8) | data[0];
00473     }
00474 
00475     uint8_t BME680::getParG2()
00476     {
00477        readRegister(0xED);
00478        return data[0];
00479     }
00480 
00481     uint8_t BME680::getParG3()
00482     {
00483        readRegister(0xEE);
00484        return data[0];
00485     }
00486     */
00487     return true;
00488 }
00489 
00490 uint32_t BME680::getUncompensatedPressureData(int field)
00491 {
00492     readRegister(0x1F + field * 0x11, 3);
00493     return (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
00494 }
00495 
00496 uint32_t BME680::getUncompensatedTemp1Data(int field)
00497 {
00498     readRegister(0x22 + field * 0x11, 3);
00499     return (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
00500 }
00501 
00502 uint32_t BME680::getUncompensatedHumidityData(int field)
00503 {
00504     readRegister(0x25 + field * 0x11, 2);
00505     return (data[0] << 8) | data[1];
00506 }
00507 
00508 uint16_t BME680::getUncompensatedGasResistanceData(int field)
00509 {
00510     readRegister(0x2A + field * 0x11, 2);
00511     return (data[0] << 2) | (data[1] >> 6);
00512 }
00513 
00514 uint8_t BME680::getGasResistanceRange(int field)
00515 {
00516     readRegister(0x2B + field * 0x11);
00517     return data[0] & 0x0F;
00518 }
00519 
00520 bool BME680::isNewData(int field)
00521 {
00522     readRegister(0x1D + field * 0x11);
00523     return (data[0] & 0x80) == 0x80 ? true : false;
00524 }
00525 
00526 bool BME680::isGasMeasuring(int field)
00527 {
00528     readRegister(0x1D + field * 0x11);
00529     return (data[0] & 0x40) == 0x40 ? true : false;
00530 }
00531 
00532 bool BME680::isMeasuring(int field)
00533 {
00534     readRegister(0x1D + field * 0x11);
00535     return (data[0] & 0x20) == 0x20 ? true : false;
00536 }
00537 
00538 int BME680::getGasMeasurementIndex(int field)
00539 {
00540     readRegister(0x1D + field * 0x11);
00541     return data[0] & 0x0F;
00542 }
00543 
00544 int BME680::getSubMeasurementIndex(int field)
00545 {
00546     readRegister(0x1E + field * 0x11);
00547     return data[0];
00548 }
00549 
00550 bool BME680::isGasValid(int field)
00551 {
00552     readRegister(0x2B + field * 0x11);
00553     return (data[0] & 0x20) == 0x20 ? true : false;
00554 }
00555 
00556 bool BME680::isHeaterStable(int field)
00557 {
00558     readRegister(0x2B + field * 0x11);
00559     return (data[0] & 0x10) == 0x10 ? true : false;
00560 }
00561 
00562 uint8_t BME680::getHeaterCurrent(int setPoint)
00563 {
00564     readRegister(0x50 + setPoint);
00565     return data[0] >> 1;
00566 }
00567 
00568 void BME680::setHeaterCurrent(int setPoint, uint8_t value)
00569 {
00570     writeRegister(0x50 + setPoint, value << 1);
00571 }
00572 
00573 int8_t BME680::getTargetHeaterResistance(int setPoint)
00574 {
00575     readRegister(0x5A + setPoint);
00576     return data[0];
00577 }
00578 
00579 void BME680::setTargetHeaterResistance(int setPoint, int8_t value)
00580 {
00581     writeRegister(0x5A + setPoint, value);
00582 }
00583 
00584 int BME680::getGasWaitTime(int setPoint)
00585 {
00586     readRegister(0x64 + setPoint);
00587     return (data[0] & 0x3F) * (data[0] >> 6);
00588 }
00589 
00590 void BME680::setGasWaitTime(int setPoint, int time, int multiplication)
00591 {
00592     writeRegister(0x64 + setPoint, (multiplication << 6) | (time & 0x3F));
00593 }
00594 
00595 int BME680::getGasWaitShared()
00596 {
00597     readRegister(0x6E);
00598     return (data[0] & 0x1F) * (data[0] >> 6);
00599 }
00600 
00601 void BME680::setGasWaitShared(int time, int multiplication)
00602 {
00603     writeRegister(0x6E, (multiplication << 6) | (time & 0x1F));
00604 }
00605 
00606 void BME680::setHeaterOff()
00607 {
00608     readRegister(0x70);
00609     data[0] |= 0x08;
00610     writeRegister(0x70, data[0]);
00611 }
00612 
00613 int BME680::getHeaterProfile()
00614 {
00615     readRegister(0x70);
00616     return data[0] &= 0x08;
00617 }
00618 
00619 void BME680::setHeaterProfile(int vlaue)
00620 {
00621     readRegister(0x71);
00622     data[0] &= 0xF0;
00623     data[0] |= vlaue & 0x0F;
00624     writeRegister(0x71, data[0]);
00625 }
00626 
00627 void BME680::runGasConversion()
00628 {
00629     readRegister(0x71);
00630     data[0] |= 0x10;
00631     writeRegister(0x71, data[0]);
00632 }
00633 
00634 float BME680::getWakePeriod()
00635 {
00636     readRegister(0x71);
00637     int temp = (data[0] & 0x80) >> 4;
00638     readRegister(0x75);
00639     temp |= data[0] >> 5;
00640 
00641     switch(temp) {
00642         case 0:
00643             return 0.59f;
00644         case 1:
00645             return 62.5f;
00646         case 2:
00647             return 125;
00648         case 3:
00649             return 250;
00650         case 4:
00651             return 500;
00652         case 5:
00653             return 1000;
00654         case 6:
00655             return 10;
00656         case 7:
00657             return 20;
00658         default:
00659             return 0;
00660     }
00661 }
00662 
00663 void  BME680::setWakePeriod(int value)
00664 {
00665     readRegister(0x71);
00666     data[0] = (data[0] & 0x7F) | ((value & 0x0F) >> 3);
00667     writeRegister(0x71, data[0]);
00668 
00669     readRegister(0x75);
00670     data[0] = (data[0] & 0x1F) | ((value & 0x07) << 5);
00671     writeRegister(0x75, data[0]);
00672 }
00673 
00674 int BME680::getOversamplingHumidity()
00675 {
00676     readRegister(0x72);
00677     switch (data[0] & 0x07) {
00678         case 0:
00679             return 0;
00680         case 1:
00681             return 1;
00682         case 2:
00683             return 2;
00684         case 3:
00685             return 4;
00686         case 4:
00687             return 8;
00688         case 5:
00689             return 16;
00690     }
00691 
00692     return 0;
00693 }
00694 
00695 void BME680::setOversamplingHumidity(int value)
00696 {
00697     readRegister(0x72);
00698     data[0] = (data[0] & 0xF8) | (value & 0x07);
00699     writeRegister(0x72, data[0]);
00700 }
00701 
00702 int BME680::getOversamplingPressure()
00703 {
00704     readRegister(0x74);
00705     switch ((data[0] & 0x1C) >> 2) {
00706         case 0:
00707             return 0;
00708         case 1:
00709             return 1;
00710         case 2:
00711             return 2;
00712         case 3:
00713             return 4;
00714         case 4:
00715             return 8;
00716         case 5:
00717             return 16;
00718     }
00719 
00720     return 0;
00721 }
00722 
00723 void BME680::setOversamplingPressure(int value)
00724 {
00725     readRegister(0x74);
00726     data[0] = (data[0] & 0xE3) | ((value & 0x07) << 2);
00727     writeRegister(0x74, data[0]);
00728 }
00729 
00730 int BME680::getOversamplingTemperature()
00731 {
00732     readRegister(0x74);
00733     switch ((data[0] & 0xE0) >> 5) {
00734         case 0:
00735             return 0;
00736         case 1:
00737             return 1;
00738         case 2:
00739             return 2;
00740         case 3:
00741             return 4;
00742         case 4:
00743             return 8;
00744         case 5:
00745             return 16;
00746     }
00747 
00748     return 0;
00749 }
00750 
00751 void BME680::setOversamplingTemperature(int value)
00752 {
00753     readRegister(0x74);
00754     data[0] = (data[0] & 0x1F) | ((value & 0x07) << 5);
00755     writeRegister(0x74, data[0]);
00756 }
00757 
00758 int BME680::getIIRfilterCoefficient()
00759 {
00760     readRegister(0x75);
00761     switch ((data[0] & 0x1C) >> 2) {
00762         case 0:
00763             return 0;
00764         case 1:
00765             return 1;
00766         case 2:
00767             return 3;
00768         case 3:
00769             return 7;
00770         case 4:
00771             return 15;
00772         case 5:
00773             return 31;
00774         case 6:
00775             return 63;
00776         case 7:
00777             return 127;
00778     }
00779     return 0;
00780 }
00781 
00782 void BME680::setIIRfilterCoefficient(int value)
00783 {
00784     readRegister(0x75);
00785     data[0] = (data[0] & 0xE3) | ((value & 0x07) << 2);
00786     writeRegister(0x75, data[0]);
00787 }
00788 
00789 int BME680::getMode()
00790 {
00791     readRegister(0x74);
00792     return data[0] & 0x03;
00793 }
00794 
00795 void BME680::setMode(int mode)
00796 {
00797     readRegister(0x74);
00798     data[0] = (data[0] & 0xFC) | (mode & 0x03);
00799     writeRegister(0x74, data[0]);
00800 }
00801 
00802 int BME680::getChipID()
00803 {
00804     readRegister(0xD0);
00805     return data[0];
00806 }
00807 
00808 void BME680::readRegister(int reg, int size)
00809 {
00810     _i2c_bus->start();
00811     if (_i2c_bus->write(_addr) != 1) USBserialComms.printf("BME680 addr write failed (read)\r");
00812     _i2c_bus->write(reg);
00813     _i2c_bus->start();
00814     _i2c_bus->write(_addr | 0x01);
00815     int i = 0;
00816     for (; i< size -1; i++)
00817         data[i] = _i2c_bus->read(1);
00818     data[i] = _i2c_bus->read(0);
00819     _i2c_bus->stop();
00820 }
00821 
00822 void BME680::writeRegister(int reg, int value)
00823 {
00824     _i2c_bus->start();
00825     if (_i2c_bus->write(_addr) != 1) USBserialComms.printf("BME680 addr write failed (write)\r");
00826     _i2c_bus->write(reg);
00827     _i2c_bus->write(value);
00828     _i2c_bus->stop();
00829 }