BME680 is an integrated environmental sensor developed specifically for mobile applications and wearables where size and low power consumption are key requirements.
Dependents: Example_DS3231_test
Revision 0:c70b7ececf93, committed 2016-07-22
- Comitter:
- yangcq88517
- Date:
- Fri Jul 22 17:38:11 2016 +0000
- Child:
- 1:85088a918342
- Commit message:
- initial upload
Changed in this revision
BME680.cpp | Show annotated file Show diff for this revision Revisions of this file |
BME680.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BME680.cpp Fri Jul 22 17:38:11 2016 +0000 @@ -0,0 +1,725 @@ +#include "BME680.h" + +// no idea why this is not the same as the PDF +//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}; +//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}; + + +const uint64_t BME680::lookup_k1_range[16] = { + 2147483647UL, 2147483647UL, 2147483647UL, 2147483647UL, 2147483647UL, + 2126008810UL, 2147483647UL, 2130303777UL, 2147483647UL, 2147483647UL, + 2143188679UL, 2136746228UL, 2147483647UL, 2126008810UL, 2147483647UL, + 2147483647UL + }; + +const uint64_t BME680::lookup_k2_range[16] = { + 4096000000UL, 2048000000UL, 1024000000UL, 512000000UL, + 255744255UL, 127110228UL, 64000000UL, 32258064UL, 16016016UL, + 8000000UL, 4000000UL, 2000000UL, 1000000UL, 500000UL, 250000UL, + 125000UL + }; + +const double BME680::_lookup_k1_range[BME680_GAS_RANGE_RL_LENGTH] = { + 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8, + 0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0 +}; +const double BME680::_lookup_k2_range[BME680_GAS_RANGE_RL_LENGTH] = { + 0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8, + -0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +#ifdef FIXED_POINT_COMPENSATION +int32_t BME680::getCompensatedTemperature(int field) +{ + uint32_t v_uncomp_temperature_u32 = getTemp1Data(field); + + int32_t var1 = ((int32_t)v_uncomp_temperature_u32 >> 3) - ((int32_t)(par_T1 << 1)); + int32_t var2 = (var1 * (int32_t) par_T2) >> 11; + int32_t var3 = ((((var1 >> 1) * (var1 >> 1)) >> 12) * ((int32_t)(par_T3 << 4))) >> 14; + t_fine = var2 + var3; + return ((t_fine * 5) + 128) >> 8; +} + +int16_t BME680::getTemperatureInt(int field) +{ + getCompensatedTemperature(field); + return (((t_fine - 122880) * 25) + 128) >> 8; +} + +int32_t BME680::getCompensateHumidity(int field) +{ + uint32_t v_uncomp_humidity_u32 = getHumidityData(field); + + int32_t temp_scaled = (t_fine * 5 + 128) >> 8; + int32_t var1 = (int32_t)v_uncomp_humidity_u32 - + ((int32_t)((int32_t)par_H1 << 4)) - + (((temp_scaled * (int32_t)par_H3) / + ((int32_t)100)) >> 1); + + int32_t var2 = ((int32_t)par_H2 * + (((temp_scaled * (int32_t)par_H4) / + ((int32_t)100)) + (((temp_scaled * + ((temp_scaled * (int32_t)par_H5) / + ((int32_t)100))) >> 6) / ((int32_t)100)) + (int32_t)(1 << 14))) >> 10; + + int32_t var3 = var1 * var2; + + int32_t var4 = ((((int32_t)par_H6) << 7) + + ((temp_scaled * (int32_t)par_H7) / + ((int32_t)100))) >> 4; + + int32_t var5 = ((var3 >> 14) * (var3 >> 14)) >> 10; + int32_t var6 = (var4 * var5) >> 1; + + int32_t humidity_comp = (var3 + var6) >> 12; + if (humidity_comp > BME680_MAX_HUMIDITY_VALUE) + humidity_comp = BME680_MAX_HUMIDITY_VALUE; + else if (humidity_comp < BME680_MIN_HUMIDITY_VALUE) + humidity_comp = BME680_MIN_HUMIDITY_VALUE; + + return humidity_comp; +} + +uint16_t BME680::getHumidityInt(int field) +{ + uint32_t v_x1_u32 = (uint32_t) getCompensateHumidity(field); + uint16_t v_x2_u32 = (uint16_t)(v_x1_u32 >> 1); + return v_x2_u32; +} + +int32_t BME680::getCompensatePressure(int field) +{ + uint32_t v_uncomp_pressure_u32 = getPressureData(field); + + int32_t var1 = (((int32_t)t_fine) >> 1) - 64000; + int32_t var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * (int32_t)par_P6) >> 2; + var2 = var2 + ((var1 * (int32_t)par_P5) << 1); + var2 = (var2 >> 2) + ((int32_t)par_P4 << 16); + var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * + ((int32_t)par_P3 << 5)) >> 3) + + (((int32_t)par_P2 * var1) >> 1); + var1 = var1 >> 18; + var1 = ((32768 + var1) * (int32_t)par_P1) >> 15; + int32_t pressure_comp = 1048576 - v_uncomp_pressure_u32; + pressure_comp = (int32_t)((pressure_comp - (var2 >> 12)) * ((int32_t)3125)); + int32_t var4 = (1 << 31); + if (pressure_comp >= var4) + pressure_comp = ((pressure_comp / (int32_t)var1) << 1); + else + pressure_comp = ((pressure_comp << 1) / (int32_t)var1); + var1 = ((int32_t)par_P9 * (int32_t)(((pressure_comp >> 3) * + (pressure_comp >> 3)) >> 13)) >> 12; + var2 = ((int32_t)(pressure_comp >> 2) * + (int32_t)par_P8) >> 13; + int32_t var3 = ((int32_t)(pressure_comp >> 8) * (int32_t)(pressure_comp >> 8) * + (int32_t)(pressure_comp >> 8) * + (int32_t)par_P10) >> 17; + + pressure_comp = (int32_t)(pressure_comp) + ((var1 + var2 + var3 + + ((int32_t)par_P7 << 7)) >> 4); + + return pressure_comp; +} + +uint32_t BME680::getPressureInt(int field) +{ + uint32_t pressure = (uint32_t)getCompensatePressure(field); + pressure = (uint32_t)(pressure >> 1); + return pressure; +} + +uint8_t BME680::convertTemperatureResistanceInt(uint16_t heater, int16_t ambient) +{ + uint8_t res_heat = 0; + + + if ((heater >= BME680_GAS_PROFILE_TEMPERATURE_MIN) + && (heater <= BME680_GAS_PROFILE_TEMPERATURE_MAX)) { + + int32_t var1 = (((int32_t)ambient * par_GH3) / 10) << 8; + int32_t var2 = (par_GH1 + 784) * + (((((par_GH2 + 154009) * + heater * 5) / 100) + 3276800) / 10); + int32_t var3 = var1 + (var2 >> 1); + int32_t var4 = (var3 / (res_heat_range + 4)); + + int32_t var5 = (131 * res_heat_val) + 65536; + + int32_t res_heat_x100 = (int32_t)(((var4 / var5) - 250) * 34); + res_heat = (uint8_t) ((res_heat_x100 + 50) / 100); + + } + return res_heat; +} + +int32_t BME680::getCalculateGasInt(int field) +{ + uint8_t gas_range_u8 = getGasResistanceRange(field); + uint16_t gas_adc_u16 = getGasResistanceData(field); + + int64_t var1 = (int64_t)((1340 + (5 * (int64_t)range_switching_error)) * + ((int64_t)lookup_k1_range[gas_range_u8])) >> 16; + int64_t var2 = (int64_t)((int64_t)gas_adc_u16 << 15) - (int64_t)(1 << 24) + var1; + int32_t gas_res = (int32_t)(((((int64_t)lookup_k2_range[gas_range_u8] * + (int64_t)var1) >> 9) + (var2 >> 1)) / var2); + return gas_res; +} + +#else +double BME680::getTemperatureDouble(int field) +{ + uint32_t uncom_temperature_u32 = getTemp1Data(field); + + double data1_d = ((((double)uncom_temperature_u32 / 16384.0) + - ((double)par_T1 / 1024.0)) + * ((double)par_T2)); + /* calculate x2 data */ + double data2_d = (((((double)uncom_temperature_u32 / 131072.0) - + ((double)par_T1 / 8192.0)) * + (((double)uncom_temperature_u32 / 131072.0) - + ((double)par_T1 / 8192.0))) * + ((double)par_T3 * 16.0)); + /* t fine value*/ + t_fine = (int32_t)(data1_d + data2_d); + /* compensated temperature data*/ + return (data1_d + data2_d) / 5120.0; +} + +double BME680::getHumidityDouble(int field) +{ + double comp_temperature = getTemperatureDouble(field); + uint16_t uncom_humidity_u16 = getHumidityData(field); + + double var1 = (double)((double)uncom_humidity_u16) - (((double) + par_H1 * 16.0) + + (((double)par_H3 / 2.0) + * comp_temperature)); + + double var2 = var1 * ((double)( + ((double) par_H2 / 262144.0) + *(1.0 + (((double)par_H4 / 16384.0) + * comp_temperature) + (((double)par_H5 + / 1048576.0) * comp_temperature + * comp_temperature)))); + double var3 = (double) par_H6 / 16384.0; + double var4 = (double) par_H7 / 2097152.0; + + double humidity_comp = var2 + + ((var3 + (var4 * comp_temperature)) * var2 * var2); + if (humidity_comp > BME680_MAX_HUMIDITY_VALUE) + humidity_comp = BME680_MAX_HUMIDITY_VALUE; + else if (humidity_comp < BME680_MIN_HUMIDITY_VALUE) + humidity_comp = BME680_MIN_HUMIDITY_VALUE; + return humidity_comp; +} + +double BME680::getPressureDouble(int field) +{ + uint32_t uncom_pressure_u32 = getPressureData(field); + + double data1_d = (((double)t_fine / 2.0) - 64000.0); + double data2_d = data1_d * data1_d * (((double)par_P6) / (131072.0)); + data2_d = data2_d + (data1_d * ((double)par_P5) * 2.0); + data2_d = (data2_d / 4.0) + (((double)par_P4) * 65536.0); + data1_d = (((((double)par_P3 * data1_d * data1_d) / 16384.0) + ((double)par_P2 * data1_d)) / 524288.0); + data1_d = ((1.0 + (data1_d / 32768.0)) * ((double)par_P1)); + double pressure_comp = (1048576.0 - ((double)uncom_pressure_u32)); + /* Avoid exception caused by division by zero */ + if ((int)data1_d != 0) { + pressure_comp = (((pressure_comp - (data2_d / 4096.0)) * 6250.0) / data1_d); + data1_d = (((double)par_P9) * pressure_comp * pressure_comp) / 2147483648.0; + data2_d = pressure_comp * (((double)par_P8) / 32768.0); + double data3_d = ((pressure_comp / 256.0) * (pressure_comp / 256.0) * (pressure_comp / 256.0) * (par_P10 / 131072.0)); + pressure_comp = (pressure_comp + (data1_d + data2_d + data3_d + ((double)par_P7 * 128.0)) / 16.0); + return pressure_comp; + } else + return 0; +} + +double BME680::convertTemperatureResistanceDouble(uint16_t heater, int16_t ambient) +{ + double var1 = 0; + double var2 = 0; + double var3 = 0; + double var4 = 0; + double var5 = 0; + double res_heat = 0; + + if ((heater >= BME680_GAS_PROFILE_TEMPERATURE_MIN) + && (heater <= BME680_GAS_PROFILE_TEMPERATURE_MAX)) { +#ifdef HEATER_C1_ENABLE + var1 = (((double)par_GH1 / (16.0)) + 49.0); + var2 = ((((double)par_GH2 / (32768.0)) * (0.0005)) + 0.00235); +#endif + var3 = ((double)par_GH3 / (1024.0)); + var4 = (var1 * (1.0 + (var2 * (double)heater))); + var5 = (var4 + (var3 * (double)ambient)); + +#ifdef HEATER_C1_ENABLE + res_heat = (uint8_t)(3.4 * ((var5 * (4 / (4 + (double)res_heat_range)) * (1/(1 + ((double)res_heat_val * 0.002)))) - 25)); +#else + res_heat = (((var5 * (4.0 / (4.0 + (double)res_heat_range))) - 25.0) * 3.4); +#endif + + } + return (uint8_t)res_heat; +} + +double BME680::getCalculateGasDouble(int field) +{ + uint8_t gas_range_u8 = getGasResistanceRange(field); + uint16_t gas_adc_u16 = getGasResistanceData(field); + double gas_res_d = 0; + + +#ifdef HEATER_C1_ENABLE + + double var1 = 0; + double var2 = 0; + double var3 = 0; + + + var1 = (1340.0 + (5.0 * range_switching_error)); + var2 = (var1) * (1.0 + _lookup_k1_range[gas_range_u8]/100.0); + var3 = 1.0 + (_lookup_k2_range[gas_range_u8]/100.0); + + gas_res_d = 1.0 / (double)(var3 * (0.000000125) * + (double)(1 << gas_range_u8) + * (((((double)gas_adc_u16) - 512.00)/var2) + 1.0)); + +#else + gas_res_d = 1.0 / ((0.000000125) * (double)(1 << gas_range_u8) * + ((((double)(gas_adc_u16) - 512.00) / 1365.3333) + 1.0)); +#endif + return gas_res_d; +} +#endif + + + +BME680::BME680(PinName sda, PinName scl, bool SDO) + :_i2c_bus(sda, scl) +{ + if (SDO) + _addr = 0x77 << 1; + else _addr = 0x76 << 1; + + _i2c_bus.frequency(FREQUENCY_FAST); +} + +bool BME680::init() +{ + if (getChipID() != 0x61) + return false; + + uint8_t cali[41]; + readRegister(0x89, 25); + memcpy(cali, data, 25); + readRegister(0xE1, 16); + memcpy(cali + 25, data, 16); + + /* read temperature calibration*/ + par_T1 = (cali[DIG_T1_MSB_REG] << 8) | cali[DIG_T1_LSB_REG]; + par_T2 = (cali[DIG_T2_MSB_REG] << 8) | cali[DIG_T2_LSB_REG]; + par_T3 = cali[DIG_T3_REG]; + + /* read pressure calibration*/ + par_P1 = (cali[DIG_P1_MSB_REG] << 8) | cali[DIG_P1_LSB_REG]; + par_P2 = (cali[DIG_P2_MSB_REG] << 8) | cali[DIG_P2_LSB_REG]; + par_P3 = cali[DIG_P3_REG]; + par_P4 = (cali[DIG_P4_MSB_REG] << 8) | cali[DIG_P4_LSB_REG]; + par_P5 = (cali[DIG_P5_MSB_REG] << 8) | cali[DIG_P5_LSB_REG]; + par_P6 = cali[DIG_P6_REG]; + par_P7 = cali[DIG_P7_REG]; + par_P8 = (cali[DIG_P8_MSB_REG] << 8) | cali[DIG_P8_LSB_REG]; + par_P9 = (cali[DIG_P9_MSB_REG] << 8) | cali[DIG_P9_LSB_REG]; + par_P10 = cali[DIG_P10_REG]; + + /* read humidity calibration*/ + par_H1 = (cali[DIG_H1_MSB_REG] << 4) | (cali[DIG_H1_LSB_REG] & BME680_BIT_MASK_H1_DATA); + par_H2 = (cali[DIG_H2_MSB_REG] << 4) | (cali[DIG_H2_LSB_REG] >> 4); + par_H3 = cali[DIG_H3_REG]; + par_H4 = cali[DIG_H4_REG]; + par_H5 = cali[DIG_H5_REG]; + par_H6 = cali[DIG_H6_REG]; + par_H7 = cali[DIG_H7_REG]; + + /* read gas calibration*/ + par_GH1 = cali[DIG_GH1_REG]; + par_GH2 = (cali[DIG_GH2_MSB_REG] <<8) | cali[DIG_GH2_LSB_REG]; + par_GH3 = cali[DIG_GH3_REG]; + + /**<resistance calculation*/ + readRegister(0x02); + res_heat_range = (data[0] >> 4) & 0x03; + + /**<correction factor*/ + readRegister(0x00); + res_heat_val = data[0]; + + /**<range switching error*/ + readRegister(0x04); + range_switching_error = (data[0] & 0xF0) >> 4; + /* + uint16_t BME680::getParG1() + { + readRegister(0xEB, 2); + return (data[1] << 8) | data[0]; + } + + uint8_t BME680::getParG2() + { + readRegister(0xED); + return data[0]; + } + + uint8_t BME680::getParG3() + { + readRegister(0xEE); + return data[0]; + } + */ + return true; +} + +uint32_t BME680::getPressureData(int field) +{ + readRegister(0x1F + field * 0x11, 3); + return (data[0] << 12) | (data[1] << 4) | (data[2] >> 4); +} + +uint32_t BME680::getTemp1Data(int field) +{ + readRegister(0x22 + field * 0x11, 3); + return (data[0] << 12) | (data[1] << 4) | (data[2] >> 4); +} + +uint32_t BME680::getHumidityData(int field) +{ + readRegister(0x25 + field * 0x11, 2); + return (data[0] << 8) | data[1]; +} + +uint16_t BME680::getGasResistanceData(int field) +{ + readRegister(0x2A + field * 0x11, 2); + return (data[0] << 2) | (data[1] >> 6); +} + +uint8_t BME680::getGasResistanceRange(int field) +{ + readRegister(0x2B + field * 0x11); + return data[0] & 0x0F; +} + +bool BME680::isNewData(int field) +{ + readRegister(0x1D + field * 0x11); + return (data[0] & 0x80) == 0x80 ? true : false; +} + +bool BME680::isGasMeasuring(int field) +{ + readRegister(0x1D + field * 0x11); + return (data[0] & 0x40) == 0x40 ? true : false; +} + +bool BME680::isMeasuring(int field) +{ + readRegister(0x1D + field * 0x11); + return (data[0] & 0x20) == 0x20 ? true : false; +} + +int BME680::getGasMeasurementIndex(int field) +{ + readRegister(0x1D + field * 0x11); + return data[0] & 0x0F; +} + +int BME680::getSubMeasurementIndex(int field) +{ + readRegister(0x1E + field * 0x11); + return data[0]; +} + +bool BME680::isGasValid(int field) +{ + readRegister(0x2B + field * 0x11); + return (data[0] & 0x20) == 0x20 ? true : false; +} + +bool BME680::isHeaterStable(int field) +{ + readRegister(0x2B + field * 0x11); + return (data[0] & 0x10) == 0x10 ? true : false; +} + +uint8_t BME680::getHeaterCurrent(int setPoint) +{ + readRegister(0x50 + setPoint); + return data[0] >> 1; +} + +void BME680::setHeaterCurrent(int setPoint, uint8_t value) +{ + writeRegister(0x50 + setPoint, value << 1); +} + +int8_t BME680::getTargetHeaterResistance(int setPoint) +{ + readRegister(0x5A + setPoint); + return data[0]; +} + +void BME680::setTargetHeaterResistance(int setPoint, int8_t value) +{ + writeRegister(0x5A + setPoint, value); +} + +int BME680::getGasWaitTime(int setPoint) +{ + readRegister(0x64 + setPoint); + return (data[0] & 0x3F) * (data[0] >> 6); +} + +void BME680::setGasWaitTime(int setPoint, int time, int multiplication) +{ + writeRegister(0x64 + setPoint, (multiplication << 6) | (time & 0x3F)); +} + +int BME680::getGasWaitShared() +{ + readRegister(0x6E); + return (data[0] & 0x1F) * (data[0] >> 6); +} + +void BME680::setGasWaitShared(int time, int multiplication) +{ + writeRegister(0x6E, (multiplication << 6) | (time & 0x1F)); +} + +void BME680::setHeaterOff() +{ + readRegister(0x70); + data[0] |= 0x08; + writeRegister(0x70, data[0]); +} + +int BME680::getHeaterProfile() +{ + readRegister(0x70); + return data[0] &= 0x08; +} + +void BME680::setHeaterProfile(int vlaue) +{ + readRegister(0x71); + data[0] &= 0xF0; + data[0] |= vlaue & 0x0F; + writeRegister(0x71, data[0]); +} + +void BME680::runGasConversion() +{ + readRegister(0x71); + data[0] |= 0x10; + writeRegister(0x71, data[0]); +} + +float BME680::getWakePeriod() +{ + readRegister(0x71); + int temp = (data[0] & 0x80) >> 4; + readRegister(0x75); + temp |= data[0] >> 5; + + switch(temp) { + case 0: + return 0.59f; + case 1: + return 62.5f; + case 2: + return 125; + case 3: + return 250; + case 4: + return 500; + case 5: + return 1000; + case 6: + return 10; + case 7: + return 20; + default: + return 0; + } +} + +void BME680::setWakePeriod(int value) +{ + readRegister(0x71); + data[0] = (data[0] & 0x7F) | ((value & 0x0F) >> 3); + writeRegister(0x71, data[0]); + + readRegister(0x75); + data[0] = (data[0] & 0x1F) | ((value & 0x07) << 5); + writeRegister(0x75, data[0]); +} + +int BME680::getOversamplingHumidity() +{ + readRegister(0x72); + switch (data[0] & 0x07) { + case 0: + return 0; + case 1: + return 1; + case 2: + return 2; + case 3: + return 4; + case 4: + return 8; + case 5: + return 16; + } + + return 0; +} + +void BME680::setOversamplingHumidity(int value) +{ + readRegister(0x72); + data[0] = (data[0] & 0xF8) | (value & 0x07); + writeRegister(0x72, data[0]); +} + +int BME680::getOversamplingPressure() +{ + readRegister(0x74); + switch ((data[0] & 0x1C) >> 2) { + case 0: + return 0; + case 1: + return 1; + case 2: + return 2; + case 3: + return 4; + case 4: + return 8; + case 5: + return 16; + } + + return 0; +} + +void BME680::setOversamplingPressure(int value) +{ + readRegister(0x74); + data[0] = (data[0] & 0xE3) | ((value & 0x07) << 2); + writeRegister(0x74, data[0]); +} + +int BME680::getOversamplingTemperature() +{ + readRegister(0x74); + switch ((data[0] & 0xE0) >> 5) { + case 0: + return 0; + case 1: + return 1; + case 2: + return 2; + case 3: + return 4; + case 4: + return 8; + case 5: + return 16; + } + + return 0; +} + +void BME680::setOversamplingTemperature(int value) +{ + readRegister(0x74); + data[0] = (data[0] & 0x1F) | ((value & 0x07) << 5); + writeRegister(0x74, data[0]); +} + +int BME680::getIIRfilterCoefficient() +{ + readRegister(0x75); + switch ((data[0] & 0x1C) >> 2) { + case 0: + return 0; + case 1: + return 1; + case 2: + return 3; + case 3: + return 7; + case 4: + return 15; + case 5: + return 31; + case 6: + return 63; + case 7: + return 127; + } + return 0; +} + +void BME680::setIIRfilterCoefficient(int value) +{ + readRegister(0x75); + data[0] = (data[0] & 0xE3) | ((value & 0x07) << 2); + writeRegister(0x75, data[0]); +} + +int BME680::getMode() +{ + readRegister(0x74); + return data[0] & 0x03; +} + +void BME680::setMode(int mode) +{ + readRegister(0x74); + data[0] = (data[0] & 0xFC) | (mode & 0x03); + writeRegister(0x74, data[0]); +} + +int BME680::getChipID() +{ + readRegister(0xD0); + return data[0]; +} + +void BME680::readRegister(int reg, int size) +{ + _i2c_bus.start(); + _i2c_bus.write(_addr); + _i2c_bus.write(reg); + _i2c_bus.start(); + _i2c_bus.write(_addr | 0x01); + int i = 0; + for (; i< size -1; i++) + data[i] = _i2c_bus.read(1); + data[i] = _i2c_bus.read(0); + _i2c_bus.stop(); +} + +void BME680::writeRegister(int reg, int value) +{ + _i2c_bus.start(); + _i2c_bus.write(_addr); + _i2c_bus.write(reg); + _i2c_bus.write(value); + _i2c_bus.stop(); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BME680.h Fri Jul 22 17:38:11 2016 +0000 @@ -0,0 +1,736 @@ +#ifndef UK_AC_HERTS_SMARTLAB_BME680 +#define UK_AC_HERTS_SMARTLAB_BME680 + +#include "mbed.h" +#include "stdint.h" + +/* +* Use below macro for fixed Point Calculation +* else Floating Point calculation will be used +*/ +#define FIXED_POINT_COMPENSATION + +// no idea what it is for +#define HEATER_C1_ENABLE + +// Sensor Specific constants */ +#define BME680_SLEEP_MODE (0x00) +#define BME680_FORCED_MODE (0x01) +#define BME680_PARALLEL_MODE (0x02) +#define BME680_SEQUENTIAL_MODE (0x03) +#define BME680_GAS_PROFILE_TEMPERATURE_MIN (200) +#define BME680_GAS_PROFILE_TEMPERATURE_MAX (400) +#define BME680_GAS_RANGE_RL_LENGTH (16) +#define BME680_SIGN_BIT_MASK (0x08) + +#ifdef FIXED_POINT_COMPENSATION +//< Multiply by 1000, In order to convert float value into fixed point +#define BME680_MAX_HUMIDITY_VALUE (102400) +#define BME680_MIN_HUMIDITY_VALUE (0) +#else +#define BME680_MAX_HUMIDITY_VALUE (double)(100.0) +#define BME680_MIN_HUMIDITY_VALUE (double)(0.0) +#endif + +/// BME680 integrated environmental sensor. This API supports FIXED and FLOATING compenstion. By default it supports FIXED, to use FLOATING user need to disable "FIXED_POINT_COMPENSATION" in the BME680.h file. +class BME680 +{ +private: + static const int FREQUENCY_STANDARD = 100000; + static const int FREQUENCY_FULL = 400000; + static const int FREQUENCY_FAST = 1000000; + static const int FREQUENCY_HIGH = 3200000; + + I2C _i2c_bus; + int _addr; + uint8_t data[30]; + + //static const double const_array1[]; + //static const double const_array2[]; + static const uint64_t lookup_k1_range[]; + static const uint64_t lookup_k2_range[]; + static const double _lookup_k1_range[]; + static const double _lookup_k2_range[]; + + /* For Calibration Data*/ + static const int DIG_T2_LSB_REG = 1; + static const int DIG_T2_MSB_REG = 2; + static const int DIG_T3_REG = 3; + static const int DIG_P1_LSB_REG = 5; + static const int DIG_P1_MSB_REG = 6; + static const int DIG_P2_LSB_REG = 7; + static const int DIG_P2_MSB_REG = 8; + static const int DIG_P3_REG = 9; + static const int DIG_P4_LSB_REG = 11; + static const int DIG_P4_MSB_REG = 12; + static const int DIG_P5_LSB_REG = 13; + static const int DIG_P5_MSB_REG = 14; + static const int DIG_P7_REG = 15; + static const int DIG_P6_REG = 16; + static const int DIG_P8_LSB_REG = 19; + static const int DIG_P8_MSB_REG = 20; + static const int DIG_P9_LSB_REG = 21; + static const int DIG_P9_MSB_REG = 22; + static const int DIG_P10_REG = 23; + static const int DIG_H2_MSB_REG = 25; + static const int DIG_H2_LSB_REG = 26; + static const int DIG_H1_LSB_REG = 26; + static const int DIG_H1_MSB_REG = 27; + static const int DIG_H3_REG = 28; + static const int DIG_H4_REG = 29; + static const int DIG_H5_REG = 30; + static const int DIG_H6_REG = 31; + static const int DIG_H7_REG = 32; + static const int DIG_T1_LSB_REG = 33; + static const int DIG_T1_MSB_REG = 34; + static const int DIG_GH2_LSB_REG = 35; + static const int DIG_GH2_MSB_REG = 36; + static const int DIG_GH1_REG = 37; + static const int DIG_GH3_REG = 38; + + static const int BME680_BIT_MASK_H1_DATA = 0x0F; + + int8_t par_T3;/**<calibration T3 data*/ + int8_t par_P3;/**<calibration P3 data*/ + int8_t par_P6;/**<calibration P6 data*/ + int8_t par_P7;/**<calibration P7 data*/ + uint8_t par_P10;/**<calibration P10 data*/ + int8_t par_H3;/**<calibration H3 data*/ + int8_t par_H4;/**<calibration H4 data*/ + int8_t par_H5;/**<calibration H5 data*/ + uint8_t par_H6;/**<calibration H6 data*/ + int8_t par_H7;/**<calibration H7 data*/ + int8_t par_GH1;/**<calibration GH1 data*/ + uint8_t res_heat_range;/**<resistance calculation*/ + int8_t res_heat_val; /**<correction factor*/ + int8_t range_switching_error;/**<range switching error*/ + int16_t par_GH2;/**<calibration GH2 data*/ + uint16_t par_T1;/**<calibration T1 data*/ + int16_t par_T2;/**<calibration T2 data*/ + uint16_t par_P1;/**<calibration P1 data*/ + int16_t par_P2;/**<calibration P2 data*/ + int16_t par_P4;/**<calibration P4 data*/ + int16_t par_P5;/**<calibration P5 data*/ + int16_t par_P8;/**<calibration P8 data*/ + int16_t par_P9;/**<calibration P9 data*/ + uint16_t par_H1;/**<calibration H1 data*/ + uint16_t par_H2;/**<calibration H2 data*/ + int32_t t_fine;/**<calibration T_FINE data*/ + int8_t par_GH3;/**<calibration GH3 data*/ + + void readRegister(int reg, int size = 1); + + void writeRegister(int reg, int value); + +public: + + /// NOT IMPLEMENTED + void setSequentialMode(); + + /// NOT IMPLEMENTED + void setForcedMode(); + + /// NOT IMPLEMENTED + void setParallelMode(); + + /* + * @param sda I2C sda signal + * @param scl I2C scl signal + * @param SDO Slave address LSB (High->true, Low->false) + */ + BME680(PinName sda, PinName scl, bool SDO); + + /** + * !! MUST CALL THIS FIRST !! + * read the chip id and calibration data of the BME680 sensor + */ + bool init(); + // DATA ######################################################################### + +#ifdef FIXED_POINT_COMPENSATION + /** + * This function is used to convert the uncompensated + * temperature data to compensated temperature data using + * compensation formula(integer version) + * @note Returns the value in 0.01 degree Centigrade + * Output value of "5123" equals 51.23 DegC. + * + * @param field 0-2 + * + * @return Returns the compensated temperature data + * + */ + int32_t getCompensatedTemperature(int field = 0); + + /** + * Reads actual temperature from uncompensated temperature + * @note Returns the value with 500LSB/DegC centred around 24 DegC + * output value of "5123" equals(5123/500)+24 = 34.246DegC + * + * + * @param v_uncomp_temperature_u32: value of uncompensated temperature + * @param bme680: structure pointer. + * + * + * @return Return the actual temperature as s16 output + * + */ + int16_t getTemperatureInt(int field = 0); + + /** + * @brief This function is used to convert the uncompensated + * humidity data to compensated humidity data using + * compensation formula(integer version) + * + * @note Returns the value in %rH as unsigned 32bit integer + * in Q22.10 format(22 integer 10 fractional bits). + * @note An output value of 42313 + * represents 42313 / 1024 = 41.321 %rH + * + * + * + * @param v_uncomp_humidity_u32: value of uncompensated humidity + * @param bme680: structure pointer. + * + * @return Return the compensated humidity data + * + */ + int32_t getCompensateHumidity(int field = 0); + + /** + * @brief Reads actual humidity from uncompensated humidity + * @note Returns the value in %rH as unsigned 16bit integer + * @note An output value of 42313 + * represents 42313/512 = 82.643 %rH + * + * + * + * @param v_uncomp_humidity_u32: value of uncompensated humidity + * @param bme680: structure pointer. + * + * @return Return the actual relative humidity output as u16 + * + */ + uint16_t getHumidityInt(int field = 0); + + /** + * @brief This function is used to convert the uncompensated + * pressure data to compensated pressure data data using + * compensation formula(integer version) + * + * @note Returns the value in Pascal(Pa) + * Output value of "96386" equals 96386 Pa = + * 963.86 hPa = 963.86 millibar + * + * + * + * @param v_uncomp_pressure_u32 : value of uncompensated pressure + * @param bme680: structure pointer. + * + * @return Return the compensated pressure data + * + */ + int32_t getCompensatePressure(int field = 0); + + /** + * @brief Reads actual pressure from uncompensated pressure + * @note Returns the value in Pa. + * @note Output value of "12337434" + * @note represents 12337434 / 128 = 96386.2 Pa = 963.862 hPa + * + * + * + * @param v_uncomp_pressure_u32 : value of uncompensated pressure + * @param bme680: structure pointer. + * + * @return the actual pressure in u32 + * + */ + uint32_t getPressureInt(int field = 0); + + /** + * @brief This function is used to convert temperature to resistance + * using the integer compensation formula + * + * @param heater_temp_u16: The value of heater temperature + * @param ambient_temp_s16: The value of ambient temperature + * @param bme680: structure pointer. + * + * @return calculated resistance from temperature + * + * + * + */ + uint8_t convertTemperatureResistanceInt(uint16_t heater, int16_t ambient); + + + /** + * @brief This function is used to convert uncompensated gas data to + * compensated gas data using compensation formula(integer version) + * + * @param gas_adc_u16: The value of gas resistance calculated + * using temperature + * @param gas_range_u8: The value of gas range form register value + * @param bme680: structure pointer. + * + * @return calculated compensated gas from compensation formula + * @retval compensated gas data + * + * + */ + int32_t getCalculateGasInt(int field = 0); + +#else + /** + * This function used to convert temperature data + * to uncompensated temperature data using compensation formula + * @note returns the value in Degree centigrade + * @note Output value of "51.23" equals 51.23 DegC. + * @param field 0-2 + * @return Return the actual temperature in floating point + */ + double getTemperatureDouble(int field = 0); + + /** + * @brief This function is used to convert the uncompensated + * humidity data to compensated humidity data data using + * compensation formula + * @note returns the value in relative humidity (%rH) + * @note Output value of "42.12" equals 42.12 %rH + * + * @param uncom_humidity_u16 : value of uncompensated humidity + * @param comp_temperature : value of compensated temperature + * @param bme680: structure pointer. + * + * + * @return Return the compensated humidity data in floating point + * + */ + double getHumidityDouble(int field = 0); + + /** + * @brief This function is used to convert the uncompensated + * pressure data to compensated data using compensation formula + * @note Returns pressure in Pa as double. + * @note Output value of "96386.2" + * equals 96386.2 Pa = 963.862 hPa. + * + * + * @param uncom_pressure_u32 : value of uncompensated pressure + * @param bme680: structure pointer. + * + * @return Return the compensated pressure data in floating point + * + */ + double getPressureDouble(int field = 0); + + /** + * @brief This function is used to convert temperature to resistance + * using the compensation formula + * + * @param heater_temp_u16: The value of heater temperature + * @param ambient_temp_s16: The value of ambient temperature + * @param bme680: structure pointer. + * + * @return calculated resistance from temperature + * + * + * + */ + double convertTemperatureResistanceDouble(uint16_t heater, int16_t ambient); + + /** + * @brief This function is used to convert uncompensated gas data to + * compensated gas data using compensation formula + * + * @param gas_adc_u16: The value of gas resistance calculated + * using temperature + * @param gas_range_u8: The value of gas range form register value + * @param bme680: structure pointer. + * + * @return calculated compensated gas from compensation formula + * @retval compensated gas + * + * + */ + double getCalculateGasDouble(int field = 0); +#endif + + + /** + * [press_msb] [press_lsb] [press_xlsb] + * Pressure, temperature, humidity and gas data of BME680 are stored in 3 data field registers + * named field0, field1, and field2. The data fields are updated sequentially and always results of + * the three latest measurements are available for the user; if the last but one conversion was written + * to field number k, the current conversion results are written to field with number (k+1) mod 3. All + * data outputs from data fields are buffered using shadowing registers to ensure keeping stable + * data if update of the data registers comes simultaneously with serial interface reading out. + * Note: Only field0 will be updated in forced mode + * @param field 0-2 + */ + uint32_t getPressureData(int field); + + /** + * [temp1_msb] [temp1_lsb] [temp1_xlsb] + * Pressure, temperature, humidity and gas data of BME680 are stored in 3 data field registers + * named field0, field1, and field2. The data fields are updated sequentially and always results of + * the three latest measurements are available for the user; if the last but one conversion was written + * to field number k, the current conversion results are written to field with number (k+1) mod 3. All + * data outputs from data fields are buffered using shadowing registers to ensure keeping stable + * data if update of the data registers comes simultaneously with serial interface reading out. + * Note: Only field0 will be updated in forced mode + * @param field 0-2 + */ + uint32_t getTemp1Data(int field); + + /** + * [hum_msb] [hum_lsb] + * Pressure, temperature, humidity and gas data of BME680 are stored in 3 data field registers + * named field0, field1, and field2. The data fields are updated sequentially and always results of + * the three latest measurements are available for the user; if the last but one conversion was written + * to field number k, the current conversion results are written to field with number (k+1) mod 3. All + * data outputs from data fields are buffered using shadowing registers to ensure keeping stable + * data if update of the data registers comes simultaneously with serial interface reading out. + * Note: Only field0 will be updated in forced mode + * @param field 0-2 + */ + uint32_t getHumidityData(int field); + + /** + * [gas_rl] + * Pressure, temperature, humidity and gas data of BME680 are stored in 3 data field registers + * named field0, field1, and field2. The data fields are updated sequentially and always results of + * the three latest measurements are available for the user; if the last but one conversion was written + * to field number k, the current conversion results are written to field with number (k+1) mod 3. All + * data outputs from data fields are buffered using shadowing registers to ensure keeping stable + * data if update of the data registers comes simultaneously with serial interface reading out. + * Note: Only field0 will be updated in forced mode + * @param field 0-2 + */ + uint16_t getGasResistanceData(int field); + + /** + * [gas_range_rl] + * Pressure, temperature, humidity and gas data of BME680 are stored in 3 data field registers + * named field0, field1, and field2. The data fields are updated sequentially and always results of + * the three latest measurements are available for the user; if the last but one conversion was written + * to field number k, the current conversion results are written to field with number (k+1) mod 3. All + * data outputs from data fields are buffered using shadowing registers to ensure keeping stable + * data if update of the data registers comes simultaneously with serial interface reading out. + * Contains ADC range of measured gas resistance + * Note: Only field0 will be updated in forced mode + * @param field 0-2 + */ + uint8_t getGasResistanceRange(int field); + + + // STATUS ######################################################################### + + /** + * [new_data_x] + * The measured data are stored into the output data registers at the end of each TPHG conversion + * phase along with status flags and index of measurement. The part of the register map for output + * data storage is composed of 3 data fields (TPHG data field0|1|2)) keeping results from the last 3 + * measurements. Availability of new (yet unread) results is indicated by new_data_0|1|2 flags. + * @param field 0-2 + */ + bool isNewData(int field); + + /** + * [gas_measuring] + * Measuring bit is set to “1‟ only during gas measurements, goes to “0‟ as soon as measurement + * is completed and data transferred to data registers. The registers storing the configuration values + * for the measurement (gas_wait_shared, gas_wait_x, res_heat_x, idac_heat_x, image registers) + * should not be changed when the device is measuring. + * @param field 0-2 + */ + bool isGasMeasuring(int field); + + /** + * [measuring] + * Measuring status will be set to ‘1’ whenever a conversion (Pressure, Temperature, humidity & + * gas) is running and back to ‘0’ when the results have been transferred to the data registers. + * @param field 0-2 + */ + bool isMeasuring(int field); + + /** + * [gas_meas_index_x] + * User can program a sequence of up to 10 conversions by setting nb_conv<3:0>. Each conversion + * has its own heater resistance target but 3 field registers to store conversion results. The actual + * gas conversion number in the measurement sequence (up to 10 conversions numbered from 0 + * to 9) is stored in gas_meas_index register. + * @param field 0-2 + */ + int getGasMeasurementIndex(int field); + + /** + * [sub_meas_index_x] + * sub_meas_index_x registers form “virtual time sensor” and contain a snapshot of the internal 8 + * bit conversion counter. Conversion counter is incremented with each TPHG conversion; the + * counter thus contains the number of conversions modulo 256 executed since the last change of + * device mode. + * Note: This index is incremented only if gas conversion is active. + * @param field 0-2 + */ + int getSubMeasurementIndex(int field); + + /** + * [gas_valid_rl] + * In parallel mode, each TPHG sequence contains a gas measurement slot, either a real one which + * result is used or a dummy one to keep a constant sampling rate and predictable device timing. A + * real gas conversion (i.e., not a dummy one) is indicated by the gas_valid_rl status register. + * @param field 0-2 + */ + bool isGasValid(int field); + + /** + * [heat_stab_rl] + * Heater temperature stability for target heater resistance is indicated heat_stab_x status bits. + * @param field 0-2 + */ + bool isHeaterStable(int field); + + // GAS CONTROL ######################################################################### + + /** + * [idac_heat_x] + * BME680 contains a heater control block that will inject enough current into the heater resistance + * to achieve the requested heater temperature. There is a control loop which periodically measures + * heater resistance value and adapts the value of current injected from a DAC. + * BME680 heater operation could be speeded up by setting an initial heater current for a target + * heater temperature by using register idac_heat_x<7:0>. This step is optional since the control + * loop will find the current after a few iterations anyway. + * Current injected to the heater in mA = (idac_heat_7_1 + 1) / 8 + * Where: idac_heat_7_1 = decimal value stored in idac_heat<7:1> (unsigned, value from 0 to 127) + * @param setPoint 0-9 + */ + uint8_t getHeaterCurrent(int setPoint); + + /** + * [idac_heat_x] + * BME680 contains a heater control block that will inject enough current into the heater resistance + * to achieve the requested heater temperature. There is a control loop which periodically measures + * heater resistance value and adapts the value of current injected from a DAC. + * BME680 heater operation could be speeded up by setting an initial heater current for a target + * heater temperature by using register idac_heat_x<7:0>. This step is optional since the control + * loop will find the current after a few iterations anyway. + * Current injected to the heater in mA = (idac_heat_7_1 + 1) / 8 + * Where: idac_heat_7_1 = decimal value stored in idac_heat<7:1> (unsigned, value from 0 to 127) + * @param setPoint 0-9 + */ + void setHeaterCurrent(int setPoint, uint8_t value); + + /** + * [res_heat_x] + * Target heater resistance is programmed by user through res_heat_x<7:0> registers. + * res_heat_x = 3.4* ((R_Target*(4/4+res_heat_range))-25) / ((res_heat_val * 0.002) + 1)) + * Where + * R_Target is the target heater resistance in Ohm + * res_heat_x is the decimal value that needs to be stored in register with same name + * res_heat_range is heater range stored in register address 0x02 <5:4> + * res_heat_val is heater resistance correction factor stored in register address 0x00 (signed, value from -128 to 127) + * @param setPoint 0-9 + */ + int8_t getTargetHeaterResistance(int setPoint); + + /** + * [res_heat_x] + * Target heater resistance is programmed by user through res_heat_x<7:0> registers. + * res_heat_x = 3.4* ((R_Target*(4/4+res_heat_range))-25) / ((res_heat_val * 0.002) + 1)) + * Where + * R_Target is the target heater resistance in Ohm + * res_heat_x is the decimal value that needs to be stored in register with same name + * res_heat_range is heater range stored in register address 0x02 <5:4> + * res_heat_val is heater resistance correction factor stored in register address 0x00 (signed, value from -128 to 127) + * @param setPoint 0-9 + */ + void setTargetHeaterResistance(int setPoint, int8_t value); + + /** + * [gas_wait_x] + * gas_wait_x controls heater timing of the gas sensor. Functionality of this register will vary based on power modes. + * Forced Mode & Sequential mode + * Time between beginning of heat phase and start of sensor resistance conversion depend on gas_wait_x settings as mentioned below. + * Parallel Mode + * The number of TPHG sub-measurement sequences within the one Gas conversion for one target + * temperature resistance is defined by gas_wait_x settings. + * Note: Please take care about gas_wait_x on shifting modes between parallel & sequential/forced mode as register functionality will change. + * @return result * 0.477 ms + * @param setPoint 0-9 + */ + int getGasWaitTime(int setPoint); + + /** + * [gas_wait_x] + * gas_wait_x controls heater timing of the gas sensor. Functionality of this register will vary based on power modes. + * Forced Mode & Sequential mode + * Time between beginning of heat phase and start of sensor resistance conversion depend on gas_wait_x settings as mentioned below. + * Parallel Mode + * The number of TPHG sub-measurement sequences within the one Gas conversion for one target + * temperature resistance is defined by gas_wait_x settings. + * Note: Please take care about gas_wait_x on shifting modes between parallel & sequential/forced mode as register functionality will change. + * @return result * 0.477 ms + * @param setPoint 0-9 + * @param time 64 timer values with 1ms step sizes, all zeros means no wait. + * @param multiplication [0, 1, 2, 3] -> [1, 4, 16, 64] + */ + void setGasWaitTime(int setPoint, int time, int multiplication); + + /** + * [gas_wait_shared] + * The programmable wait time between two TPHG sub-measurement sequences of parallel mode depends on gas_wait_shared settings as follows + */ + int getGasWaitShared(); + + /** + * [gas_wait_shared] + * The programmable wait time between two TPHG sub-measurement sequences of parallel mode depends on gas_wait_shared settings as follows + * @param setPoint 0-9 + * @param time 64 timer values with 0.477 ms step sizes, all zeros means no wait. + * @param multiplication [0x00, 0x01, 0x10, 0x11] -> [1, 4, 16, 64] + */ + void setGasWaitShared(int time, int multiplication); + + /** + * [heat_off] + * Turn off current injected to heater + */ + void setHeaterOff(); + + /** + * [nb_conv] + * is used to select heater set-points of BME680 + * Sequential & Parallel Mode + * User can program a sequence of up to 10 conversions by setting nb_conv<3:0>. Each conversion has its own heater resistance target but 3 field registers to store conversion results. The actual + * gas conversion number in the measurement sequence (up to 10 conversions numbered from 0 to 9) is stored in gas measurement index register + * In parallel mode, no TPH conversions are ran at all. In sequential mode, TPH conversions are run according to osrs_t|p|h settings, gas is skipped + * @return Sequential & Parallel : number of profiles (0-10), 0 means no gas conversion + * @return Forced : indicates index of heater profile + */ + int getHeaterProfile(); + + /** + * [nb_conv] + * is used to select heater set-points of BME680 + * Sequential & Parallel Mode + * User can program a sequence of up to 10 conversions by setting nb_conv<3:0>. Each conversion has its own heater resistance target but 3 field registers to store conversion results. The actual + * gas conversion number in the measurement sequence (up to 10 conversions numbered from 0 to 9) is stored in gas measurement index register + * In parallel mode, no TPH conversions are ran at all. In sequential mode, TPH conversions are run according to osrs_t|p|h settings, gas is skipped + * @param Sequential & Parallel : number of profiles (0-10), 0 means no gas conversion + * @param Forced : indicates index of heater profile + */ + void setHeaterProfile(int value); + + /** + * [run_gas_l] + * The gas conversions are started only in appropriate mode if run_gas_l=1 + */ + void runGasConversion(); + + /** + * [odr] + * Wake period in sequential mode – odr + * In the sequential mode operation the device periodically enters stand-by state and returns to an operational state after a given wake-up period. Wake period can be programmed by odr<3:0> register as shown below + * @return in ms, 0 means device does not go to standby + */ + float getWakePeriod(); + + /** + * [odr] + * Wake period in sequential mode – odr + * In the sequential mode operation the device periodically enters stand-by state and returns to an operational state after a given wake-up period. Wake period can be programmed by odr<3:0> register as shown below + * @param value : [0 - 8+] [0.59,62.5,125,250,500,1000,10,20,no standby] + */ + void setWakePeriod(int value); + + // PRESSURE TEMPERATURE HUMIDITY CONTROL ######################################################################### + + /** + * [osrs_h] + * @return value : [0,1,2,4,8,16] -> [skip,X1,X2,X4,X8,X16], 0 means skipped (output set to 0x8000) + */ + int getOversamplingHumidity(); + + /** + * [osrs_h] + * @param value : [0,1,2,3,4,5] -> [skip,X1,X2,X4,X8,X16], 0 means skipped (output set to 0x8000) + */ + void setOversamplingHumidity(int value); + + /** + * [osrs_p] + * @return value : [0,1,2,4,8,16] -> [skip,X1,X2,X4,X8,X16], 0 means skipped (output set to 0x8000) + */ + int getOversamplingPressure(); + + /** + * [osrs_p] + * @param value : [0,1,2,3,4,5] -> [skip,X1,X2,X4,X8,X16], 0 means skipped (output set to 0x8000) + */ + void setOversamplingPressure(int value); + + /** + * [osrs_t] + * @return value : [0,1,2,4,8,16] -> [skip,X1,X2,X4,X8,X16], 0 means skipped (output set to 0x8000) + */ + int getOversamplingTemperature(); + + /** + * [osrs_t] + * @param value : [0,1,2,3,4,5] -> [skip,X1,X2,X4,X8,X16], 0 means skipped (output set to 0x8000) + */ + void setOversamplingTemperature(int value); + + /** + * [filter] + * IIR filter control + * IIR filter applies to temperature and pressure data but not to humidity and gas data. The data + * coming from the ADC are filtered and then loaded into the data registers. The T, P result registers + * are updated together at the same time at the end of measurement. IIR filter output resolution is + * 20 bits. The T, P result registers are reset to value 0x80000 when the T, P measurements have + * been skipped (osrs_x=”000‟). The appropriate filter memory is kept unchanged (the value fromt he last measurement is kept). When the appropriate OSRS register is set back to nonzero, then + * the first value stored to the T, P result register is filtered. + * @return value : [0,1,3,7,15,31,63,127] + */ + int getIIRfilterCoefficient(); + + /** + * [filter] + * IIR filter control + * IIR filter applies to temperature and pressure data but not to humidity and gas data. The data + * coming from the ADC are filtered and then loaded into the data registers. The T, P result registers + * are updated together at the same time at the end of measurement. IIR filter output resolution is + * 20 bits. The T, P result registers are reset to value 0x80000 when the T, P measurements have + * been skipped (osrs_x=”000‟). The appropriate filter memory is kept unchanged (the value fromt he last measurement is kept). When the appropriate OSRS register is set back to nonzero, then + * the first value stored to the T, P result register is filtered. + * @param value : [0,1,2,3,4,5,6,7] -> [0,1,3,7,15,31,63,127] + */ + void setIIRfilterCoefficient(int value); + + // GENERAL CONTROL ######################################################################### + + /** + * [mode] + * Four measurement modes are available for BME680; that is sleep, sequential, parallel and forced + * mode.Four measurement modes are available for BME680; that is sleep, sequential, parallel and forced mode. + * @param mode : [0,1,2,3] -> [Sleep, Forced, Parallel, Sequential] + */ + void setMode(int mode); + + /** + * [mode] + * Four measurement modes are available for BME680; that is sleep, sequential, parallel and forced + * mode.Four measurement modes are available for BME680; that is sleep, sequential, parallel and forced mode. + * @return value : [0,1,2,3] -> [Sleep, Forced, Parallel, Sequential] + */ + int getMode(); + + /** + * [chip_id] + * Chip id of the device, this should give 0x61 + */ + int getChipID(); +}; + +#endif \ No newline at end of file