add bsec persistence

modbus
Ondřej Hruška 3 years ago
parent 3fd1c73c7b
commit 4d50891a63
  1. 13
      main/co2_sensor.c
  2. 10
      main/settings.c
  3. 2
      main/settings.h
  4. 39
      main/voc_sensor.c

@ -13,6 +13,8 @@
#include "settings.h" #include "settings.h"
#include <driver/uart.h> #include <driver/uart.h>
#include <string.h> #include <string.h>
#include <stddef.h>
#include <inttypes.h>
static const char *TAG = "co2"; static const char *TAG = "co2";
@ -77,7 +79,7 @@ static bool ppm_looks_valid(uint16_t ppm) {
} }
void co2_read_task(void *param) { void co2_read_task(void *param) {
esp_err_t rv; (void) param;
vTaskDelay(pdMS_TO_TICKS(500)); vTaskDelay(pdMS_TO_TICKS(500));
@ -91,8 +93,10 @@ void co2_read_task(void *param) {
write_saved_calib_to_sensor(); write_saved_calib_to_sensor();
const uint32_t read_cycle_time_ticks = pdMS_TO_TICKS(10 * 1000); const uint32_t read_cycle_time_ticks = 10 * 1000;
const uint32_t calib_persist_time_ticks = pdMS_TO_TICKS(6 * 3600 * 1000); const uint32_t calib_persist_time_ticks = 12 * 3600 * 1000;
_Static_assert(configTICK_RATE_HZ == 1000, "1kHz tick");
uint32_t last_calib_persist = xTaskGetTickCount(); uint32_t last_calib_persist = xTaskGetTickCount();
ESP_LOGD(TAG, "Calib persist time = %d ticks", calib_persist_time_ticks); ESP_LOGD(TAG, "Calib persist time = %d ticks", calib_persist_time_ticks);
@ -176,7 +180,8 @@ void co2_read_task(void *param) {
// CO2 measurement looks OK // CO2 measurement looks OK
uint32_t tickNow = xTaskGetTickCount(); uint32_t tickNow = xTaskGetTickCount();
if ((tickNow - last_calib_persist) > calib_persist_time_ticks) { uint32_t elapsed = tickNow - last_calib_persist;
if (elapsed > calib_persist_time_ticks) {
ESP_LOGI(TAG, "Read & persist CO2 calibration"); ESP_LOGI(TAG, "Read & persist CO2 calibration");
last_calib_persist = tickNow; last_calib_persist = tickNow;

@ -122,12 +122,16 @@ void settings_load(void)
size_t capacity = 10; size_t capacity = 10;
NVSCHECK(nvs_get_blob(storage, "co2_calib", g_Settings.co2_calib, &capacity)); NVSCHECK(nvs_get_blob(storage, "co2_calib", g_Settings.co2_calib, &capacity));
} }
{
size_t capacity = BSEC_MAX_STATE_BLOB_SIZE;
NVSCHECK(nvs_get_blob(storage, "bsec_state", g_Settings.bsec_state, &capacity));
}
} }
void settings_persist(enum settings_key_enum what) void settings_persist(enum settings_key_enum what)
{ {
esp_err_t rv; esp_err_t rv;
char name[24]; // char name[24];
#undef NVSCHECK #undef NVSCHECK
#define NVSCHECK(callback) \ #define NVSCHECK(callback) \
@ -160,6 +164,10 @@ void settings_persist(enum settings_key_enum what)
if (what==SETTINGS_ALL || what==SETTINGS_co2_calib) { if (what==SETTINGS_ALL || what==SETTINGS_co2_calib) {
NVSCHECK(nvs_set_blob(storage, "co2_calib", (void*) g_Settings.co2_calib, 5*sizeof(uint16_t))); NVSCHECK(nvs_set_blob(storage, "co2_calib", (void*) g_Settings.co2_calib, 5*sizeof(uint16_t)));
} }
if (what==SETTINGS_ALL || what==SETTINGS_bsec_state) {
NVSCHECK(nvs_set_blob(storage, "bsec_state", (void*) g_Settings.bsec_state, BSEC_MAX_STATE_BLOB_SIZE));
}
} }
uint16_t app_get_bootcount() uint16_t app_get_bootcount()

@ -10,6 +10,7 @@
#include <nvs.h> #include <nvs.h>
#include <driver/uart.h> #include <driver/uart.h>
#include <sdkconfig.h> #include <sdkconfig.h>
#include <bsec2.h>
#define CONSOLE_TELNET_PORT CONFIG_CONSOLE_TELNET_PORT #define CONSOLE_TELNET_PORT CONFIG_CONSOLE_TELNET_PORT
#define CONSOLE_PW_LEN CONFIG_CONSOLE_PW_LEN #define CONSOLE_PW_LEN CONFIG_CONSOLE_PW_LEN
@ -35,6 +36,7 @@ extern nvs_handle g_nvs_storage;
X(bool , ntp_enable , , 1 , true , bool , &) \ X(bool , ntp_enable , , 1 , true , bool , &) \
X(char , ntp_srv ,[NTP_SRV_LEN], DEF_NTP_SRV , false, none , ) \ X(char , ntp_srv ,[NTP_SRV_LEN], DEF_NTP_SRV , false, none , ) \
X(uint16_t , co2_calib ,[5], {}, false, none , ) \ X(uint16_t , co2_calib ,[5], {}, false, none , ) \
X(uint8_t , bsec_state ,[BSEC_MAX_STATE_BLOB_SIZE], {}, false, none , ) \
X(bool , dhcp_wd_enable , , 1 , true , bool , &) \ X(bool , dhcp_wd_enable , , 1 , true , bool , &) \
X(bool , dhcp_enable , , 1 , true , bool , &) \ X(bool , dhcp_enable , , 1 , true , bool , &) \
X(uint32_t , static_ip , , 0 , true , u32 , &) \ X(uint32_t , static_ip , , 0 , true , u32 , &) \

@ -23,6 +23,7 @@ static const char *TAG = "voc";
#include "bme68x_defs.h" #include "bme68x_defs.h"
#include "bsec2.h" #include "bsec2.h"
#include "periph_init.h" #include "periph_init.h"
#include "settings.h"
struct sensor_itf { struct sensor_itf {
uint8_t dev_addr; uint8_t dev_addr;
@ -30,7 +31,7 @@ struct sensor_itf {
static struct sensor_itf gas_sensor_intf = {}; static struct sensor_itf gas_sensor_intf = {};
static struct bme68x_dev gas_sensor = {}; static struct bme68x_dev gas_sensor = {};
static struct bsec2 gas_sensor_bsec = {}; static struct bsec2 hBsec = {};
void bsec2_errormsg(const char *msg) { void bsec2_errormsg(const char *msg) {
ESP_LOGE("BSEC", "%s", msg); ESP_LOGE("BSEC", "%s", msg);
@ -103,7 +104,7 @@ static esp_err_t voc_init(void) {
int8_t rslt; int8_t rslt;
gas_sensor_intf.dev_addr = BME68X_I2C_ADDR_LOW; gas_sensor_intf.dev_addr = BME68X_I2C_ADDR_LOW;
gas_sensor.intf_ptr = &gas_sensor_intf; gas_sensor.intf_ptr = &gas_sensor_intf;
gas_sensor.amb_temp = 25; // TODO set this from senseair! gas_sensor.amb_temp = 25;
gas_sensor.intf = BME68X_I2C_INTF; gas_sensor.intf = BME68X_I2C_INTF;
gas_sensor.read = user_i2c_read; gas_sensor.read = user_i2c_read;
gas_sensor.write = user_i2c_write; gas_sensor.write = user_i2c_write;
@ -243,7 +244,7 @@ void voc_read_task(void *param) {
goto abort; goto abort;
} }
int rv = bsec2_init(&gas_sensor_bsec, &gas_sensor); int rv = bsec2_init(&hBsec, &gas_sensor);
if (rv != 0) { if (rv != 0) {
ESP_LOGE(TAG, "Error in bsec init: %d", rv); ESP_LOGE(TAG, "Error in bsec init: %d", rv);
goto abort; goto abort;
@ -267,7 +268,7 @@ void voc_read_task(void *param) {
BSEC_OUTPUT_RUN_IN_STATUS, BSEC_OUTPUT_RUN_IN_STATUS,
}; };
rv = bsec2_updateSubscription(&gas_sensor_bsec, rv = bsec2_updateSubscription(&hBsec,
sensorList, sensorList,
sizeof(sensorList) / sizeof(bsecSensor), sizeof(sensorList) / sizeof(bsecSensor),
BSEC_SAMPLE_RATE_LP); BSEC_SAMPLE_RATE_LP);
@ -277,21 +278,35 @@ void voc_read_task(void *param) {
goto abort; goto abort;
} }
bsec2_attachCallback(&gas_sensor_bsec, new_data_callback); bsec2_attachCallback(&hBsec, new_data_callback);
ESP_LOGI(TAG, "BSEC library version %d.%d.%d.%d", ESP_LOGI(TAG, "BSEC library version %d.%d.%d.%d",
gas_sensor_bsec.version.major, hBsec.version.major,
gas_sensor_bsec.version.minor, hBsec.version.minor,
gas_sensor_bsec.version.major_bugfix, hBsec.version.major_bugfix,
gas_sensor_bsec.version.minor_bugfix); hBsec.version.minor_bugfix);
// TODO add bsec state persistence to NVS at some landmark intervals, e.g. 1 day const uint32_t state_persist_time_ticks = 12 * 3600 * 1000;
// TODO periodic updating of sensor ambient temp _Static_assert(configTICK_RATE_HZ == 1000, "1kHz tick");
uint32_t last_state_persist = xTaskGetTickCount();
ESP_LOGI(TAG, "Restore BSEC state");
bsec2_setState(&hBsec, g_Settings.bsec_state);
while (1) { while (1) {
rv = bsec2_run(&gas_sensor_bsec); rv = bsec2_run(&hBsec);
if (false == rv) { if (false == rv) {
ESP_LOGE(TAG, "Error in bsec run!"); ESP_LOGE(TAG, "Error in bsec run!");
} else {
uint32_t tickNow = xTaskGetTickCount();
uint32_t elapsed = tickNow - last_state_persist;
if (elapsed > state_persist_time_ticks) {
ESP_LOGI(TAG, "Read & persist BSEC state");
last_state_persist = tickNow;
if (bsec2_getState(&hBsec, g_Settings.bsec_state)) {
settings_persist(SETTINGS_bsec_state);
}
}
} }
vTaskDelay(pdMS_TO_TICKS(100)); vTaskDelay(pdMS_TO_TICKS(100));
} }

Loading…
Cancel
Save