bsecstate load/save implemented; bugfix packed_decoder.js
This commit is contained in:
parent
184e1e7d84
commit
f26b7a545c
@ -47,8 +47,11 @@ const uint8_t bsec_config_iaq[454] = {
|
|||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 44, 1, 0, 0, 0, 0,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 44, 1, 0, 0, 0, 0,
|
||||||
239, 79, 0, 0};
|
239, 79, 0, 0};
|
||||||
|
|
||||||
|
// Helper functions declarations
|
||||||
int bme_init();
|
int bme_init();
|
||||||
void bme_loop(void *pvParameters);
|
void bme_loop(void *pvParameters);
|
||||||
int checkIaqSensorStatus(void);
|
int checkIaqSensorStatus(void);
|
||||||
|
void loadState(void);
|
||||||
|
void updateState(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -7,6 +7,10 @@
|
|||||||
#include "spislave.h"
|
#include "spislave.h"
|
||||||
#include <lmic.h>
|
#include <lmic.h>
|
||||||
|
|
||||||
|
#ifdef HAS_BME
|
||||||
|
#include "bme680mems.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
void doHousekeeping(void);
|
void doHousekeeping(void);
|
||||||
void do_timesync(void);
|
void do_timesync(void);
|
||||||
uint64_t uptime(void);
|
uint64_t uptime(void);
|
||||||
|
@ -54,6 +54,7 @@ typedef struct {
|
|||||||
uint8_t runmode; // 0=normal, 1=update
|
uint8_t runmode; // 0=normal, 1=update
|
||||||
uint8_t payloadmask; // bitswitches for payload data
|
uint8_t payloadmask; // bitswitches for payload data
|
||||||
char version[10]; // Firmware version
|
char version[10]; // Firmware version
|
||||||
|
char bsecstate[BSEC_MAX_STATE_BLOB_SIZE+1]; // init BSEC state for BME680 sensor
|
||||||
} configData_t;
|
} configData_t;
|
||||||
|
|
||||||
// Struct holding payload for data send queue
|
// Struct holding payload for data send queue
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
; ---> SELECT TARGET PLATFORM HERE! <---
|
; ---> SELECT TARGET PLATFORM HERE! <---
|
||||||
[platformio]
|
[platformio]
|
||||||
;env_default = generic
|
env_default = generic
|
||||||
;env_default = ebox
|
;env_default = ebox
|
||||||
;env_default = eboxtube
|
;env_default = eboxtube
|
||||||
;env_default = heltec
|
;env_default = heltec
|
||||||
@ -16,7 +16,7 @@
|
|||||||
;env_default = ttgov21old
|
;env_default = ttgov21old
|
||||||
;env_default = ttgov21new
|
;env_default = ttgov21new
|
||||||
;env_default = ttgobeam_old
|
;env_default = ttgobeam_old
|
||||||
env_default = ttgobeam_new
|
;env_default = ttgobeam_new
|
||||||
;env_default = lopy
|
;env_default = lopy
|
||||||
;env_default = lopy4
|
;env_default = lopy4
|
||||||
;env_default = fipy
|
;env_default = fipy
|
||||||
@ -30,10 +30,10 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng
|
|||||||
|
|
||||||
[common]
|
[common]
|
||||||
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
||||||
release_version = 1.7.03
|
release_version = 1.7.06
|
||||||
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
|
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
|
||||||
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
||||||
debug_level = 3
|
debug_level = 0
|
||||||
; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA
|
; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
;upload_protocol = custom
|
;upload_protocol = custom
|
||||||
|
@ -18,7 +18,11 @@ function Decoder(bytes, port) {
|
|||||||
if (bytes.length === 4) {
|
if (bytes.length === 4) {
|
||||||
return decode(bytes, [uint16, uint16], ['wifi', 'ble']);
|
return decode(bytes, [uint16, uint16], ['wifi', 'ble']);
|
||||||
}
|
}
|
||||||
// combined counter and gps data
|
// combined wifi counter and gps data
|
||||||
|
if (bytes.length === 15) {
|
||||||
|
return decode(bytes, [uint16, latLng, latLng, uint8, hdop, uint16], ['wifi', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']);
|
||||||
|
}
|
||||||
|
// combined wifi + ble counter and gps data
|
||||||
if (bytes.length === 17) {
|
if (bytes.length === 17) {
|
||||||
return decode(bytes, [uint16, uint16, latLng, latLng, uint8, hdop, uint16], ['wifi', 'ble', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']);
|
return decode(bytes, [uint16, uint16, latLng, latLng, uint8, hdop, uint16], ['wifi', 'ble', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,9 @@ bsec_virtual_sensor_t sensorList[10] = {
|
|||||||
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
|
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
|
||||||
|
uint16_t stateUpdateCounter = 0;
|
||||||
|
|
||||||
// initialize BME680 sensor
|
// initialize BME680 sensor
|
||||||
int bme_init(void) {
|
int bme_init(void) {
|
||||||
|
|
||||||
@ -46,6 +49,8 @@ int bme_init(void) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadState();
|
||||||
|
|
||||||
iaqSensor.setTemperatureOffset((float)BME_TEMP_OFFSET);
|
iaqSensor.setTemperatureOffset((float)BME_TEMP_OFFSET);
|
||||||
iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
|
iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
|
||||||
|
|
||||||
@ -99,7 +104,6 @@ void bme_loop(void *pvParameters) {
|
|||||||
// block i2c bus access
|
// block i2c bus access
|
||||||
if (xSemaphoreTake(I2Caccess, (DISPLAYREFRESH_MS / portTICK_PERIOD_MS)) ==
|
if (xSemaphoreTake(I2Caccess, (DISPLAYREFRESH_MS / portTICK_PERIOD_MS)) ==
|
||||||
pdTRUE) {
|
pdTRUE) {
|
||||||
|
|
||||||
if (iaqSensor.run()) { // If new data is available
|
if (iaqSensor.run()) { // If new data is available
|
||||||
bme_status.raw_temperature = iaqSensor.rawTemperature;
|
bme_status.raw_temperature = iaqSensor.rawTemperature;
|
||||||
bme_status.raw_humidity = iaqSensor.rawHumidity;
|
bme_status.raw_humidity = iaqSensor.rawHumidity;
|
||||||
@ -111,7 +115,6 @@ void bme_loop(void *pvParameters) {
|
|||||||
bme_status.iaq_accuracy = iaqSensor.iaqAccuracy;
|
bme_status.iaq_accuracy = iaqSensor.iaqAccuracy;
|
||||||
bme_status.gas = iaqSensor.gasResistance;
|
bme_status.gas = iaqSensor.gasResistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
xSemaphoreGive(I2Caccess); // release i2c bus access
|
xSemaphoreGive(I2Caccess); // release i2c bus access
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,4 +124,43 @@ void bme_loop(void *pvParameters) {
|
|||||||
|
|
||||||
} // bme_loop()
|
} // bme_loop()
|
||||||
|
|
||||||
|
void loadState(void) {
|
||||||
|
if (cfg.bsecstate[BSEC_MAX_STATE_BLOB_SIZE + 1] == BSEC_MAX_STATE_BLOB_SIZE) {
|
||||||
|
// Existing state in NVS stored
|
||||||
|
ESP_LOGI(TAG, "restoring BSEC state from NVRAM");
|
||||||
|
memcpy(bsecState, cfg.bsecstate, BSEC_MAX_STATE_BLOB_SIZE);
|
||||||
|
iaqSensor.setState(bsecState);
|
||||||
|
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) {
|
||||||
|
/* First state update when IAQ accuracy is >= 1 */
|
||||||
|
if (iaqSensor.iaqAccuracy >= 3) {
|
||||||
|
update = true;
|
||||||
|
stateUpdateCounter++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Update every STATE_SAVE_PERIOD minutes */
|
||||||
|
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
|
||||||
|
update = true;
|
||||||
|
stateUpdateCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
memcpy(bsecState, cfg.bsecstate, BSEC_MAX_STATE_BLOB_SIZE);
|
||||||
|
cfg.bsecstate[BSEC_MAX_STATE_BLOB_SIZE + 1] = BSEC_MAX_STATE_BLOB_SIZE;
|
||||||
|
iaqSensor.getState(bsecState);
|
||||||
|
checkIaqSensorStatus();
|
||||||
|
ESP_LOGI(TAG, "saving BSEC state to NVRAM");
|
||||||
|
saveConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // HAS_BME
|
#endif // HAS_BME
|
@ -32,6 +32,8 @@ void defaultConfig() {
|
|||||||
cfg.monitormode = 0; // 0=disabled, 1=enabled
|
cfg.monitormode = 0; // 0=disabled, 1=enabled
|
||||||
cfg.runmode = 0; // 0=normal, 1=update
|
cfg.runmode = 0; // 0=normal, 1=update
|
||||||
cfg.payloadmask = 0xFF; // all payload switched on
|
cfg.payloadmask = 0xFF; // all payload switched on
|
||||||
|
cfg.bsecstate[BSEC_MAX_STATE_BLOB_SIZE + 1] = {
|
||||||
|
0}; // init BSEC state for BME680 sensor
|
||||||
|
|
||||||
strncpy(cfg.version, PROGVERSION, sizeof(cfg.version) - 1);
|
strncpy(cfg.version, PROGVERSION, sizeof(cfg.version) - 1);
|
||||||
}
|
}
|
||||||
@ -78,6 +80,12 @@ void saveConfig() {
|
|||||||
int16_t flash16 = 0;
|
int16_t flash16 = 0;
|
||||||
size_t required_size;
|
size_t required_size;
|
||||||
char storedversion[10];
|
char storedversion[10];
|
||||||
|
char bsecstate[BSEC_MAX_STATE_BLOB_SIZE + 1];
|
||||||
|
|
||||||
|
if (nvs_get_str(my_handle, "bsecstate", bsecstate, &required_size) !=
|
||||||
|
ESP_OK ||
|
||||||
|
strcmp(bsecstate, cfg.bsecstate) != 0)
|
||||||
|
nvs_set_str(my_handle, "bsecstate", cfg.bsecstate);
|
||||||
|
|
||||||
if (nvs_get_str(my_handle, "version", storedversion, &required_size) !=
|
if (nvs_get_str(my_handle, "version", storedversion, &required_size) !=
|
||||||
ESP_OK ||
|
ESP_OK ||
|
||||||
@ -202,7 +210,16 @@ void loadConfig() {
|
|||||||
migrateVersion();
|
migrateVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
// overwrite defaults with valid values from NVRAM
|
// populate pre set defaults with current values from NVRAM
|
||||||
|
|
||||||
|
char bsecstate[BSEC_MAX_STATE_BLOB_SIZE + 1];
|
||||||
|
|
||||||
|
if (nvs_get_str(my_handle, "bsecstate", NULL, &required_size) == ESP_OK) {
|
||||||
|
nvs_get_str(my_handle, "bsecstate", cfg.bsecstate, &required_size);
|
||||||
|
ESP_LOGI(TAG, "bsecstate = %d",
|
||||||
|
cfg.bsecstate[BSEC_MAX_STATE_BLOB_SIZE + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
if (nvs_get_i8(my_handle, "lorasf", &flash8) == ESP_OK) {
|
if (nvs_get_i8(my_handle, "lorasf", &flash8) == ESP_OK) {
|
||||||
cfg.lorasf = flash8;
|
cfg.lorasf = flash8;
|
||||||
ESP_LOGI(TAG, "lorasf = %d", flash8);
|
ESP_LOGI(TAG, "lorasf = %d", flash8);
|
||||||
|
@ -58,6 +58,7 @@ void doHousekeeping() {
|
|||||||
// display BME sensor data if present
|
// display BME sensor data if present
|
||||||
#ifdef HAS_BME
|
#ifdef HAS_BME
|
||||||
ESP_LOGI(TAG, "BME680 Temp: %.2f°C | IAQ: %.2f", bme_status.temperature, bme_status.iaq);
|
ESP_LOGI(TAG, "BME680 Temp: %.2f°C | IAQ: %.2f", bme_status.temperature, bme_status.iaq);
|
||||||
|
updateState();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// check free heap memory
|
// check free heap memory
|
||||||
|
@ -11,18 +11,18 @@
|
|||||||
|
|
||||||
// enable only if device has these sensors, otherwise comment these lines
|
// enable only if device has these sensors, otherwise comment these lines
|
||||||
// BME680 sensor on I2C bus
|
// BME680 sensor on I2C bus
|
||||||
#define HAS_BME GPIO_NUM_21, GPIO_NUM_22 // SDA, SCL
|
//#define HAS_BME GPIO_NUM_21, GPIO_NUM_22 // SDA, SCL
|
||||||
#define BME_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND
|
//#define BME_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND
|
||||||
|
|
||||||
#define HAS_LED GPIO_NUM_14 // on board green LED
|
#define HAS_LED GPIO_NUM_14 // on board green LED
|
||||||
|
|
||||||
// user defined sensors
|
// user defined sensors
|
||||||
//#define HAS_SENSORS 1 // comment out if device has user defined sensors
|
//#define HAS_SENSORS 1 // comment out if device has user defined sensors
|
||||||
|
|
||||||
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
|
//#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
|
||||||
#define MY_OLED_SDA (21)
|
//#define MY_OLED_SDA (21)
|
||||||
#define MY_OLED_SCL (22)
|
//#define MY_OLED_SCL (22)
|
||||||
#define MY_OLED_RST U8X8_PIN_NONE
|
//#define MY_OLED_RST U8X8_PIN_NONE
|
||||||
//#define DISPLAY_FLIP 1 // use if display is rotated
|
//#define DISPLAY_FLIP 1 // use if display is rotated
|
||||||
|
|
||||||
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
||||||
|
@ -72,6 +72,8 @@
|
|||||||
|
|
||||||
// Settings for BME680 environmental sensor (if present)
|
// Settings for BME680 environmental sensor (if present)
|
||||||
#define BME_TEMP_OFFSET 5.0f // Offset sensor on chip temp <-> ambient temp [default = 5°C]
|
#define BME_TEMP_OFFSET 5.0f // Offset sensor on chip temp <-> ambient temp [default = 5°C]
|
||||||
|
#define BSEC_MAX_STATE_BLOB_SIZE 134 // size of Bosch BME680 state data blob
|
||||||
|
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // update every 360 minutes = 4 times a day
|
||||||
|
|
||||||
// OTA settings
|
// OTA settings
|
||||||
#define USE_OTA 1 // Comment out to disable OTA update
|
#define USE_OTA 1 // Comment out to disable OTA update
|
||||||
|
Loading…
Reference in New Issue
Block a user