Library for the BME220
Fork of BME680 by
Embed:
(wiki syntax)
Show/hide line numbers
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