Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BME680 by
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 }
Generated on Sun Jul 17 2022 17:56:45 by
1.7.2
