So Vincent, first of all thank you for clarifying which config file to use for this setup! I got curious the last days and tried the basic_config_state_ULP_LP.ino example provided on Github. This is the example I initially used to set up two subscription rates for my own project. To my surprise the Github example shows the same behaviour as my own, meaning that the error must be somewhere either in the BSEC framework or in the sensor API (this is what i presume but can't confirm). I did an other example to confirm my observations for which I attach the code and logfile to this post. I initialize and start the BME680 with T/P/H/Gas measurements in UPL mode. At second 3500 I change the subscription rates for T/P/H to LP. After the last ULP interval (seconds 3300 -> 3600) has ended output values are returned, as expected, in 3s intervals for T/P/H BUT also for the Gas sensor. Also from this point on the overall sensor temperature rises drastically until about 2.5°C above the before measured values (see figure attached or logfile). To me it seems as if the sensor suddenly experiences a much higher heat dissipation, like the gas heater was enabled at much higher frequency than usual. Unfortunately I don't have enough experience to trace back this behavior to either the BSEC framework or the sensor API. Any thoughts on that? Thanks and BR, Ben #include <EEPROM.h>
#include "bsec.h"
const uint8_t bsec_config_iaq[] = {
#include "config/generic_33v_300s_4d/bsec_iaq.txt"
};
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // 360 minutes - 4 times a day
void checkIaqSensorStatus(void);
void loadState(void);
void updateState(void);
Bsec iaqSensor;
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
uint16_t stateUpdateCounter = 0;
uint8_t setLP = 0;
bsec_virtual_sensor_t sensorList_LP[3] = {
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
};
void setup() {
EEPROM.begin(BSEC_MAX_STATE_BLOB_SIZE + 1); // 1st address for the length
Wire.begin();
Serial.begin(115200);
iaqSensor.begin(BME680_I2C_ADDR_PRIMARY, Wire);
Serial.println("BSEC library version " + String(iaqSensor.version.major) + "." + String(iaqSensor.version.minor) + "." + String(iaqSensor.version.major_bugfix) + "." + String(iaqSensor.version.minor_bugfix));
checkIaqSensorStatus();
iaqSensor.setConfig(bsec_config_iaq);
checkIaqSensorStatus();
loadState();
bsec_virtual_sensor_t sensorList_ULP[8] = {
BSEC_OUTPUT_STABILIZATION_STATUS,
BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_CO2_EQUIVALENT,
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY
};
iaqSensor.updateSubscription(sensorList_ULP, 8, BSEC_SAMPLE_RATE_ULP);
checkIaqSensorStatus();
Serial.println("Running main program");
}
void loop() {
if(iaqSensor.run()){
updateState();
Serial.print(String((uint16_t)(millis()/1000)) + "s");
Serial.print(" BSECstate: " + String(iaqSensor.status));
// Serial.print(" IAQacc: " + String(iaqSensor.iaqAccuracy));
Serial.print(" riStat: " + String(iaqSensor.runInStatus));
Serial.print(" stabStat: " + String(iaqSensor.stabStatus));
Serial.print(" IAQ: " + String(iaqSensor.iaq) + "(" + String(iaqSensor.iaqAccuracy) + ")");
Serial.print(" CO2: " + String(iaqSensor.co2Equivalent) + "(" + String(iaqSensor.co2Accuracy) + ")");
Serial.print(" bVOC: " + String(iaqSensor.breathVocEquivalent) + "(" + String(iaqSensor.breathVocAccuracy) + ")");
Serial.print(" p: " + String(iaqSensor.pressure));
Serial.print(" t: " + String(iaqSensor.temperature));
Serial.println(" h: " + String(iaqSensor.humidity));
}
else {
checkIaqSensorStatus();
}
if((millis()/1000) == 3500 && setLP == 0){
iaqSensor.updateSubscription(sensorList_LP, 3, BSEC_SAMPLE_RATE_LP);
setLP = 1;
Serial.println("LP sensors configured");
}
}
void checkIaqSensorStatus(void)
{
if (iaqSensor.status != BSEC_OK) {
if (iaqSensor.status < BSEC_OK) {
//output = "BSEC error code : " + String(iaqSensor.status);
Serial.println("BSEC error code : " + String(iaqSensor.status));
while(1);
} else {
//output = "BSEC warning code : " + String(iaqSensor.status);
Serial.println("BSEC warning code : " + String(iaqSensor.status));
}
}
if (iaqSensor.bme680Status != BME680_OK) {
if (iaqSensor.bme680Status < BME680_OK) {
//output = "BME680 error code : " + String(iaqSensor.bme680Status);
Serial.println("BME680 error code : " + String(iaqSensor.bme680Status));
while(1);
} else {
//output = "BME680 warning code : " + String(iaqSensor.bme680Status);
Serial.println("BME680 warning code : " + String(iaqSensor.bme680Status));
}
}
iaqSensor.status = BSEC_OK;
}
void loadState(void)
{
if (EEPROM.read(0) == BSEC_MAX_STATE_BLOB_SIZE) {
// Existing state in EEPROM
Serial.println("Reading state from EEPROM");
for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) {
bsecState[i] = EEPROM.read(i + 1);
Serial.println(bsecState[i], HEX);
}
iaqSensor.setState(bsecState);
checkIaqSensorStatus();
} else {
// Erase the EEPROM with zeroes
Serial.println("Erasing EEPROM");
for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE + 1; i++)
EEPROM.write(i, 0);
EEPROM.commit();
}
}
void updateState(void)
{
bool update = false;
/* Set a trigger to save the state. Here, the state is saved every STATE_SAVE_PERIOD with the first state being saved once the algorithm achieves full calibration, i.e. iaqAccuracy = 3 */
if (stateUpdateCounter == 0) {
if (iaqSensor.iaqAccuracy >= 3) {
update = true;
stateUpdateCounter++;
}
} else {
/* Update every STATE_SAVE_PERIOD milliseconds */
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
update = true;
stateUpdateCounter++;
}
}
if (update) {
iaqSensor.getState(bsecState);
checkIaqSensorStatus();
Serial.println("Writing state to EEPROM");
for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE ; i++) {
EEPROM.write(i + 1, bsecState[i]);
Serial.println(bsecState[i], HEX);
}
EEPROM.write(0, BSEC_MAX_STATE_BLOB_SIZE);
EEPROM.commit();
}
}
... View more