diff --git a/platformio.ini b/platformio.ini index c339cf992..508f3615b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -105,7 +105,7 @@ lib_deps = adafruit/Adafruit Unified Sensor@^1.1.9 adafruit/Adafruit BMP280 Library@^2.6.6 adafruit/Adafruit BME280 Library@^2.2.2 - adafruit/Adafruit BME680 Library@^2.0.1 + https://github.com/meshtastic/BSEC-Arduino-library.git#452f9a7ffa8b53e1debe2c454fe375dfad98b507 adafruit/Adafruit MCP9808 Library@^2.0.0 adafruit/Adafruit INA260 Library@^1.5.0 adafruit/Adafruit INA219@^1.2.0 diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp index f05246d52..21beedcea 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp +++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp @@ -1,8 +1,8 @@ #include "BME680Sensor.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "FSCommon.h" #include "TelemetrySensor.h" #include "configuration.h" -#include BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {} @@ -12,7 +12,15 @@ int32_t BME680Sensor::runOnce() if (!hasSensor()) { return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; } - status = bme680.begin(nodeTelemetrySensorsMap[sensorType]); + bme680.begin(nodeTelemetrySensorsMap[sensorType], Wire); + if (bme680.bsecStatus == BSEC_OK) { + bme680.setConfig(bsec_config_iaq); + loadState(); + bme680.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP); + status = 1; + } else { + status = 0; + } return initI2CSensor(); } @@ -21,11 +29,56 @@ void BME680Sensor::setup() {} bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement) { - bme680.performReading(); + bme680.run(); measurement->variant.environment_metrics.temperature = bme680.temperature; measurement->variant.environment_metrics.relative_humidity = bme680.humidity; measurement->variant.environment_metrics.barometric_pressure = bme680.pressure / 100.0F; - measurement->variant.environment_metrics.gas_resistance = bme680.gas_resistance / 1000.0; + measurement->variant.environment_metrics.gas_resistance = bme680.gasResistance / 1000.0; + updateState(); + + // Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms) return true; +} + +void BME680Sensor::loadState() +{ +#ifdef FSCom + if (File file = FSCom.open(bsecConfigFileName, FILE_O_READ)) { + file.read((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE); + file.close(); + bme680.setState(bsecState); + } else { + FSCom.remove(bsecConfigFileName); + } +#endif +} + +void BME680Sensor::updateState() +{ +#ifdef FSCom + bool update = false; + if (stateUpdateCounter == 0) { + /* First state update when IAQ accuracy is >= 3 */ + if (bme680.iaqAccuracy >= 3) { + update = true; + stateUpdateCounter++; + } + } else { + /* Update every STATE_SAVE_PERIOD minutes */ + if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) { + update = true; + stateUpdateCounter++; + } + } + + if (update) { + bme680.getState(bsecState); + if (File file = FSCom.open(bsecConfigFileName, FILE_O_WRITE)) { + file.write((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE); + file.flush(); + file.close(); + } + } +#endif } \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h index d59374803..78adad01e 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.h +++ b/src/modules/Telemetry/Sensor/BME680Sensor.h @@ -1,14 +1,38 @@ #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "TelemetrySensor.h" -#include +#include + +#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) + +const uint8_t bsec_config_iaq[] = { +#include +}; class BME680Sensor : virtual public TelemetrySensor { private: - Adafruit_BME680 bme680; + Bsec bme680; protected: virtual void setup() override; + const char *bsecConfigFileName = "/prefs/bsec.dat"; + uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0}; + uint16_t stateUpdateCounter = 0; + bsec_virtual_sensor_t sensorList[13] = {BSEC_OUTPUT_IAQ, + BSEC_OUTPUT_STATIC_IAQ, + BSEC_OUTPUT_CO2_EQUIVALENT, + BSEC_OUTPUT_BREATH_VOC_EQUIVALENT, + BSEC_OUTPUT_RAW_TEMPERATURE, + BSEC_OUTPUT_RAW_PRESSURE, + BSEC_OUTPUT_RAW_HUMIDITY, + BSEC_OUTPUT_RAW_GAS, + BSEC_OUTPUT_STABILIZATION_STATUS, + BSEC_OUTPUT_RUN_IN_STATUS, + BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE, + BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY, + BSEC_OUTPUT_GAS_PERCENTAGE}; + void loadState(); + void updateState(); public: BME680Sensor();