2019-03-13 21:15:28 +01:00
|
|
|
#if (HAS_BME)
|
2018-11-22 23:37:53 +01:00
|
|
|
|
2019-03-13 21:15:28 +01:00
|
|
|
#include "bmesensor.h"
|
2018-11-22 23:37:53 +01:00
|
|
|
|
|
|
|
// Local logging tag
|
2019-02-27 00:49:32 +01:00
|
|
|
static const char TAG[] = __FILE__;
|
2018-11-22 23:37:53 +01:00
|
|
|
|
2018-11-25 11:48:03 +01:00
|
|
|
bmeStatus_t bme_status;
|
2018-11-25 16:05:30 +01:00
|
|
|
TaskHandle_t BmeTask;
|
2018-11-26 16:12:41 +01:00
|
|
|
|
2019-03-13 21:15:28 +01:00
|
|
|
#define SEALEVELPRESSURE_HPA (1013.25)
|
|
|
|
|
|
|
|
#ifdef HAS_BME680
|
2018-12-27 17:09:40 +01:00
|
|
|
bsec_virtual_sensor_t sensorList[10] = {
|
|
|
|
BSEC_OUTPUT_RAW_TEMPERATURE,
|
|
|
|
BSEC_OUTPUT_RAW_PRESSURE,
|
|
|
|
BSEC_OUTPUT_RAW_HUMIDITY,
|
|
|
|
BSEC_OUTPUT_RAW_GAS,
|
|
|
|
BSEC_OUTPUT_IAQ,
|
|
|
|
BSEC_OUTPUT_STATIC_IAQ,
|
|
|
|
BSEC_OUTPUT_CO2_EQUIVALENT,
|
|
|
|
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
|
|
|
|
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
|
|
|
|
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
|
|
|
|
};
|
|
|
|
|
2019-01-06 19:41:42 +01:00
|
|
|
uint8_t bsecstate_buffer[BSEC_MAX_STATE_BLOB_SIZE] = {0};
|
2018-12-31 11:26:05 +01:00
|
|
|
uint16_t stateUpdateCounter = 0;
|
|
|
|
|
2019-01-06 19:41:42 +01:00
|
|
|
Bsec iaqSensor;
|
|
|
|
|
2019-03-13 21:15:28 +01:00
|
|
|
#elif defined HAS_BME280
|
|
|
|
|
|
|
|
Adafruit_BME280 bme; // I2C
|
|
|
|
// Adafruit_BME280 bme(BME_CS); // hardware SPI
|
|
|
|
// Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2018-11-25 11:48:03 +01:00
|
|
|
// initialize BME680 sensor
|
2018-11-25 12:49:49 +01:00
|
|
|
int bme_init(void) {
|
2018-12-31 15:46:52 +01:00
|
|
|
|
|
|
|
// return = 0 -> error / return = 1 -> success
|
|
|
|
|
2019-03-13 21:15:28 +01:00
|
|
|
#ifdef HAS_BME680
|
2018-12-27 17:09:40 +01:00
|
|
|
// block i2c bus access
|
2019-01-26 12:32:17 +01:00
|
|
|
if (I2C_MUTEX_LOCK()) {
|
2018-11-22 23:37:53 +01:00
|
|
|
|
2019-03-08 18:13:51 +01:00
|
|
|
Wire.begin(HAS_BME680);
|
|
|
|
iaqSensor.begin(BME680_ADDR, Wire);
|
2018-11-25 16:05:30 +01:00
|
|
|
|
2018-12-27 17:09:40 +01:00
|
|
|
ESP_LOGI(TAG, "BSEC v%d.%d.%d.%d", iaqSensor.version.major,
|
|
|
|
iaqSensor.version.minor, iaqSensor.version.major_bugfix,
|
|
|
|
iaqSensor.version.minor_bugfix);
|
2018-12-21 00:35:21 +01:00
|
|
|
|
2018-12-27 17:09:40 +01:00
|
|
|
iaqSensor.setConfig(bsec_config_iaq);
|
2018-11-22 23:37:53 +01:00
|
|
|
|
2018-12-27 17:09:40 +01:00
|
|
|
if (checkIaqSensorStatus())
|
|
|
|
ESP_LOGI(TAG, "BME680 sensor found and initialized");
|
|
|
|
else {
|
|
|
|
ESP_LOGE(TAG, "BME680 sensor not found");
|
2018-12-31 15:46:52 +01:00
|
|
|
goto error;
|
2018-12-27 17:09:40 +01:00
|
|
|
}
|
2018-11-25 11:48:03 +01:00
|
|
|
|
2018-12-31 11:26:05 +01:00
|
|
|
loadState();
|
|
|
|
|
2018-12-27 17:09:40 +01:00
|
|
|
iaqSensor.setTemperatureOffset((float)BME_TEMP_OFFSET);
|
|
|
|
iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
|
2018-11-22 23:37:53 +01:00
|
|
|
|
2018-12-27 17:09:40 +01:00
|
|
|
if (checkIaqSensorStatus())
|
|
|
|
ESP_LOGI(TAG, "BSEC subscription succesful");
|
|
|
|
else {
|
|
|
|
ESP_LOGE(TAG, "BSEC subscription error");
|
2018-12-31 15:46:52 +01:00
|
|
|
goto error;
|
2018-12-27 17:09:40 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "I2c bus busy - BME680 initialization error");
|
2018-12-31 15:46:52 +01:00
|
|
|
goto error;
|
2018-11-22 23:37:53 +01:00
|
|
|
}
|
2018-12-27 17:09:40 +01:00
|
|
|
|
2019-03-13 21:15:28 +01:00
|
|
|
#elif defined HAS_BME280
|
|
|
|
|
|
|
|
bool status;
|
|
|
|
// return = 0 -> error / return = 1 -> success
|
|
|
|
|
|
|
|
// block i2c bus access
|
|
|
|
if (I2C_MUTEX_LOCK()) {
|
|
|
|
status = bme.begin(BME280_ADDR);
|
|
|
|
if (!status) {
|
|
|
|
ESP_LOGE(TAG, "BME280 sensor not found");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
ESP_LOGI(TAG, "BME280 sensor found and initialized");
|
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "I2c bus busy - BME280 initialization error");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2019-01-26 12:32:17 +01:00
|
|
|
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
2018-12-31 15:46:52 +01:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
error:
|
2019-01-26 12:32:17 +01:00
|
|
|
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
2018-12-31 15:46:52 +01:00
|
|
|
return 0;
|
|
|
|
|
2018-12-27 17:09:40 +01:00
|
|
|
} // bme_init()
|
2018-11-22 23:37:53 +01:00
|
|
|
|
2019-03-13 21:15:28 +01:00
|
|
|
#ifdef HAS_BME680
|
|
|
|
|
2018-12-26 23:01:54 +01:00
|
|
|
// Helper function definitions
|
|
|
|
int checkIaqSensorStatus(void) {
|
|
|
|
int rslt = 1; // true = 1 = no error, false = 0 = error
|
|
|
|
|
|
|
|
if (iaqSensor.status != BSEC_OK) {
|
|
|
|
rslt = 0;
|
|
|
|
if (iaqSensor.status < BSEC_OK)
|
|
|
|
ESP_LOGE(TAG, "BSEC error %d", iaqSensor.status);
|
|
|
|
else
|
|
|
|
ESP_LOGW(TAG, "BSEC warning %d", iaqSensor.status);
|
2018-11-22 23:37:53 +01:00
|
|
|
}
|
|
|
|
|
2018-12-26 23:01:54 +01:00
|
|
|
if (iaqSensor.bme680Status != BME680_OK) {
|
|
|
|
rslt = 0;
|
|
|
|
if (iaqSensor.bme680Status < BME680_OK)
|
|
|
|
ESP_LOGE(TAG, "BME680 error %d", iaqSensor.bme680Status);
|
|
|
|
else
|
|
|
|
ESP_LOGW(TAG, "BME680 warning %d", iaqSensor.bme680Status);
|
|
|
|
}
|
2018-11-25 11:48:03 +01:00
|
|
|
|
2018-12-26 23:01:54 +01:00
|
|
|
return rslt;
|
2018-12-27 17:09:40 +01:00
|
|
|
} // checkIaqSensorStatus()
|
2019-03-13 21:15:28 +01:00
|
|
|
#endif
|
2018-11-25 11:48:03 +01:00
|
|
|
|
2018-12-26 23:01:54 +01:00
|
|
|
// loop function which reads and processes data based on sensor settings
|
|
|
|
void bme_loop(void *pvParameters) {
|
2018-11-25 20:56:14 +01:00
|
|
|
|
2018-12-26 23:01:54 +01:00
|
|
|
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
|
2018-11-25 11:48:03 +01:00
|
|
|
|
2019-03-08 18:13:51 +01:00
|
|
|
#ifdef HAS_BME680
|
2019-01-26 12:32:17 +01:00
|
|
|
while (1) {
|
|
|
|
// block i2c bus access
|
|
|
|
if (I2C_MUTEX_LOCK()) {
|
|
|
|
if (iaqSensor.run()) { // If new data is available
|
|
|
|
bme_status.raw_temperature = iaqSensor.rawTemperature;
|
|
|
|
bme_status.raw_humidity = iaqSensor.rawHumidity;
|
|
|
|
bme_status.temperature = iaqSensor.temperature;
|
|
|
|
bme_status.humidity = iaqSensor.humidity;
|
|
|
|
bme_status.pressure =
|
|
|
|
(iaqSensor.pressure / 100.0); // conversion Pa -> hPa
|
|
|
|
bme_status.iaq = iaqSensor.iaqEstimate;
|
|
|
|
bme_status.iaq_accuracy = iaqSensor.iaqAccuracy;
|
|
|
|
bme_status.gas = iaqSensor.gasResistance;
|
|
|
|
updateState();
|
|
|
|
}
|
|
|
|
I2C_MUTEX_UNLOCK();
|
2018-12-26 23:01:54 +01:00
|
|
|
}
|
2019-01-26 12:32:17 +01:00
|
|
|
}
|
2019-03-13 21:15:28 +01:00
|
|
|
#elif defined HAS_BME280
|
|
|
|
while (1) {
|
|
|
|
if (I2C_MUTEX_LOCK()) {
|
|
|
|
bme_status.temperature = bme.readTemperature();
|
|
|
|
bme_status.pressure =
|
|
|
|
(bme.readPressure() / 100.0); // conversion Pa -> hPa
|
|
|
|
// bme.readAltitude(SEALEVELPRESSURE_HPA);
|
|
|
|
bme_status.humidity = bme.readHumidity();
|
|
|
|
I2C_MUTEX_UNLOCK();
|
|
|
|
}
|
|
|
|
}
|
2018-12-26 23:01:54 +01:00
|
|
|
#endif
|
|
|
|
ESP_LOGE(TAG, "BME task ended");
|
|
|
|
vTaskDelete(BmeTask); // should never be reached
|
2018-11-22 23:37:53 +01:00
|
|
|
|
2018-12-26 23:01:54 +01:00
|
|
|
} // bme_loop()
|
2018-11-25 11:48:03 +01:00
|
|
|
|
2019-03-13 21:15:28 +01:00
|
|
|
#ifdef HAS_BME680
|
2018-12-31 11:26:05 +01:00
|
|
|
void loadState(void) {
|
2019-01-01 21:23:45 +01:00
|
|
|
if (cfg.bsecstate[BSEC_MAX_STATE_BLOB_SIZE] == BSEC_MAX_STATE_BLOB_SIZE) {
|
2018-12-31 11:26:05 +01:00
|
|
|
// Existing state in NVS stored
|
|
|
|
ESP_LOGI(TAG, "restoring BSEC state from NVRAM");
|
2018-12-31 15:46:52 +01:00
|
|
|
memcpy(bsecstate_buffer, cfg.bsecstate, BSEC_MAX_STATE_BLOB_SIZE);
|
|
|
|
iaqSensor.setState(bsecstate_buffer);
|
2018-12-31 11:26:05 +01:00
|
|
|
checkIaqSensorStatus();
|
|
|
|
} else // no state stored
|
|
|
|
ESP_LOGI(TAG,
|
|
|
|
"no BSEC state stored in NVRAM, starting sensor with defaults");
|
|
|
|
}
|
|
|
|
|
|
|
|
void updateState(void) {
|
|
|
|
bool update = false;
|
|
|
|
|
|
|
|
if (stateUpdateCounter == 0) {
|
2019-01-06 19:41:42 +01:00
|
|
|
// first state update when IAQ accuracy is >= 1
|
|
|
|
if (iaqSensor.iaqAccuracy >= 1) {
|
2018-12-31 11:26:05 +01:00
|
|
|
update = true;
|
|
|
|
stateUpdateCounter++;
|
|
|
|
}
|
|
|
|
} else {
|
2019-01-01 21:23:45 +01:00
|
|
|
|
2018-12-31 11:26:05 +01:00
|
|
|
/* Update every STATE_SAVE_PERIOD minutes */
|
|
|
|
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
|
|
|
|
update = true;
|
|
|
|
stateUpdateCounter++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (update) {
|
2018-12-31 15:46:52 +01:00
|
|
|
iaqSensor.getState(bsecstate_buffer);
|
2018-12-31 11:26:05 +01:00
|
|
|
checkIaqSensorStatus();
|
2019-01-01 14:59:00 +01:00
|
|
|
memcpy(cfg.bsecstate, bsecstate_buffer, BSEC_MAX_STATE_BLOB_SIZE);
|
2019-01-01 21:23:45 +01:00
|
|
|
cfg.bsecstate[BSEC_MAX_STATE_BLOB_SIZE] = BSEC_MAX_STATE_BLOB_SIZE;
|
2018-12-31 11:26:05 +01:00
|
|
|
ESP_LOGI(TAG, "saving BSEC state to NVRAM");
|
|
|
|
saveConfig();
|
|
|
|
}
|
|
|
|
}
|
2019-03-13 21:15:28 +01:00
|
|
|
#endif
|
2018-12-31 11:26:05 +01:00
|
|
|
|
2019-03-13 21:15:28 +01:00
|
|
|
#endif // HAS_BME
|