I attached my minimal reproducer and log for 30 minutes (log.cpp - .cpp because forum doesn't accept .txt files as attachment). But it looks like I found why calibration didn't happen. In the real code I synchronize time with the server and I had a race condition between sensor initialization and time sync. Therefore for there was a huge gap in time between the very first and all subsequent measurements. After fixing this race sensor increased accuracy from 0 to 1 but getting further takes significantly longer so I'm still waiting. I'll post if it doesn't get to accuracy 3. #include <Arduino.h>
#include <bsec.h>
#include <bsec_serialized_configurations_iaq.h>
#include <sys/time.h>
#define LOG(fmt, ...) (Serial.printf("%09llu: " fmt "\n", GetTimestamp(), ##__VA_ARGS__))
Bsec sensor;
RTC_DATA_ATTR uint8_t sensor_state[BSEC_MAX_STATE_BLOB_SIZE] = {0};
RTC_DATA_ATTR int64_t sensor_state_time = 0;
bsec_virtual_sensor_t sensor_list[] = {
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,
};
int64_t GetTimestamp() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000LL + (tv.tv_usec / 1000LL));
}
bool CheckSensor() {
if (sensor.status < BSEC_OK) {
LOG("BSEC error, status %d!", sensor.status);
return false;;
} else if (sensor.status > BSEC_OK) {
LOG("BSEC warning, status %d!", sensor.status);
}
if (sensor.bme680Status < BME680_OK) {
LOG("Sensor error, bme680_status %d!", sensor.bme680Status);
return false;
} else if (sensor.bme680Status > BME680_OK){
LOG("Sensor warning, status %d!", sensor.bme680Status);
}
return true;
}
void DumpState(const char* name, const uint8_t* state) {
LOG("%s:", name);
for (int i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) {
Serial.printf("%02x ", state[i]);
if (i % 16 == 15) {
Serial.print("\n");
}
}
Serial.print("\n");
}
void setup() {
Serial.begin(115200);
sensor.begin(BME680_I2C_ADDR_SECONDARY, Wire);
if (!CheckSensor()) {
LOG("Failed to init BME680, check wiring!");
return;
}
LOG("BSEC version %d.%d.%d.%d", sensor.version.major, sensor.version.minor, sensor.version.major_bugfix, sensor.version.minor_bugfix);
sensor.setConfig(bsec_config_iaq);
if (!CheckSensor()) {
LOG("Failed to set config!");
return;
}
if (sensor_state_time) {
DumpState("setState", sensor_state);
sensor.setState(sensor_state);
if (!CheckSensor()) {
LOG("Failed to set state!");
return;
} else {
LOG("Successfully set state from %lld", sensor_state_time);
}
} else {
LOG("Saved state missing");
}
sensor.updateSubscription(sensor_list, sizeof(sensor_list)/sizeof(sensor_list[0]), BSEC_SAMPLE_RATE_ULP);
if (!CheckSensor()) {
LOG("Failed to update subscription!");
return;
}
LOG("Sensor init done");
}
void loop() {
if (sensor.run()) {
LOG("Temperature raw %.2f compensated %.2f", sensor.rawTemperature, sensor.temperature);
LOG("Humidity raw %.2f compensated %.2f", sensor.rawHumidity, sensor.humidity);
LOG("Pressure %.2f kPa", sensor.pressure/1000);
LOG("IAQ %.0f accuracy %d", sensor.iaqEstimate, sensor.iaqAccuracy);
LOG("Static IAQ %.0f accuracy %d", sensor.staticIaq, sensor.staticIaqAccuracy);
LOG("Gas resistance %.2f kOhm", sensor.gasResistance/1000);
sensor_state_time = GetTimestamp();
sensor.getState(sensor_state);
DumpState("getState", sensor_state);
LOG("Saved state to RTC memroy at %lld", sensor_state_time);
CheckSensor();
uint64_t time_ms = 300 * 1000 * 1000ull - esp_timer_get_time();
LOG("Deep sleep for %llu ms!", time_ms/1000);
esp_sleep_enable_timer_wakeup(time_ms);
esp_deep_sleep_start();
}
}
... View more