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, | ||||
|     239, 79,  0,   0}; | ||||
| 
 | ||||
| // Helper functions declarations
 | ||||
| int bme_init(); | ||||
| void bme_loop(void *pvParameters); | ||||
| int checkIaqSensorStatus(void); | ||||
| void loadState(void); | ||||
| void updateState(void); | ||||
| 
 | ||||
| #endif | ||||
| @ -7,6 +7,10 @@ | ||||
| #include "spislave.h" | ||||
| #include <lmic.h> | ||||
| 
 | ||||
| #ifdef HAS_BME | ||||
| #include "bme680mems.h" | ||||
| #endif | ||||
| 
 | ||||
| void doHousekeeping(void); | ||||
| void do_timesync(void); | ||||
| uint64_t uptime(void); | ||||
|  | ||||
| @ -54,6 +54,7 @@ typedef struct { | ||||
|   uint8_t runmode;       // 0=normal, 1=update
 | ||||
|   uint8_t payloadmask;   // bitswitches for payload data
 | ||||
|   char version[10];      // Firmware version
 | ||||
|   char bsecstate[BSEC_MAX_STATE_BLOB_SIZE+1]; // init BSEC state for BME680 sensor
 | ||||
| } configData_t; | ||||
| 
 | ||||
| // Struct holding payload for data send queue
 | ||||
| @ -87,7 +88,7 @@ extern configData_t cfg;                      // current device configuration | ||||
| extern char display_line6[], display_line7[]; // screen buffers
 | ||||
| extern uint8_t volatile channel;              // wifi channel rotation counter
 | ||||
| extern uint16_t volatile macs_total, macs_wifi, macs_ble, | ||||
|     batt_voltage;                  // display values
 | ||||
|     batt_voltage; // display values
 | ||||
| extern hw_timer_t *channelSwitch, *sendCycle, *displaytimer; | ||||
| extern SemaphoreHandle_t I2Caccess; | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ | ||||
| 
 | ||||
| ; ---> SELECT TARGET PLATFORM HERE! <--- | ||||
| [platformio] | ||||
| ;env_default = generic | ||||
| env_default = generic | ||||
| ;env_default = ebox | ||||
| ;env_default = eboxtube | ||||
| ;env_default = heltec | ||||
| @ -16,7 +16,7 @@ | ||||
| ;env_default = ttgov21old | ||||
| ;env_default = ttgov21new | ||||
| ;env_default = ttgobeam_old | ||||
| env_default = ttgobeam_new | ||||
| ;env_default = ttgobeam_new | ||||
| ;env_default = lopy | ||||
| ;env_default = lopy4 | ||||
| ;env_default = fipy | ||||
| @ -30,10 +30,10 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng | ||||
| 
 | ||||
| [common] | ||||
| ; 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! | ||||
| ; 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_protocol = esptool | ||||
| ;upload_protocol = custom | ||||
|  | ||||
| @ -18,7 +18,11 @@ function Decoder(bytes, port) { | ||||
|         if (bytes.length === 4) { | ||||
|             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) { | ||||
|             return decode(bytes, [uint16, uint16, latLng, latLng, uint8, hdop, uint16], ['wifi', 'ble', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']); | ||||
|         } | ||||
|  | ||||
| @ -23,9 +23,12 @@ bsec_virtual_sensor_t sensorList[10] = { | ||||
|     BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY, | ||||
| }; | ||||
| 
 | ||||
| uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0}; | ||||
| uint16_t stateUpdateCounter = 0; | ||||
| 
 | ||||
| // initialize BME680 sensor
 | ||||
| int bme_init(void) { | ||||
| 
 | ||||
|    | ||||
|   // block i2c bus access
 | ||||
|   if (xSemaphoreTake(I2Caccess, (DISPLAYREFRESH_MS / portTICK_PERIOD_MS)) == | ||||
|       pdTRUE) { | ||||
| @ -46,6 +49,8 @@ int bme_init(void) { | ||||
|       return 1; | ||||
|     } | ||||
| 
 | ||||
|     loadState(); | ||||
| 
 | ||||
|     iaqSensor.setTemperatureOffset((float)BME_TEMP_OFFSET); | ||||
|     iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP); | ||||
| 
 | ||||
| @ -99,7 +104,6 @@ void bme_loop(void *pvParameters) { | ||||
|     // block i2c bus access
 | ||||
|     if (xSemaphoreTake(I2Caccess, (DISPLAYREFRESH_MS / portTICK_PERIOD_MS)) == | ||||
|         pdTRUE) { | ||||
| 
 | ||||
|       if (iaqSensor.run()) { // If new data is available
 | ||||
|         bme_status.raw_temperature = iaqSensor.rawTemperature; | ||||
|         bme_status.raw_humidity = iaqSensor.rawHumidity; | ||||
| @ -111,7 +115,6 @@ void bme_loop(void *pvParameters) { | ||||
|         bme_status.iaq_accuracy = iaqSensor.iaqAccuracy; | ||||
|         bme_status.gas = iaqSensor.gasResistance; | ||||
|       } | ||||
| 
 | ||||
|       xSemaphoreGive(I2Caccess); // release i2c bus access
 | ||||
|     } | ||||
|   } | ||||
| @ -121,4 +124,43 @@ void bme_loop(void *pvParameters) { | ||||
| 
 | ||||
| } // 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
 | ||||
| @ -32,6 +32,8 @@ void defaultConfig() { | ||||
|   cfg.monitormode = 0;        // 0=disabled, 1=enabled
 | ||||
|   cfg.runmode = 0;            // 0=normal, 1=update
 | ||||
|   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); | ||||
| } | ||||
| @ -78,6 +80,12 @@ void saveConfig() { | ||||
|     int16_t flash16 = 0; | ||||
|     size_t required_size; | ||||
|     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) != | ||||
|             ESP_OK || | ||||
| @ -202,7 +210,16 @@ void loadConfig() { | ||||
|       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) { | ||||
|       cfg.lorasf = flash8; | ||||
|       ESP_LOGI(TAG, "lorasf = %d", flash8); | ||||
|  | ||||
| @ -58,6 +58,7 @@ void doHousekeeping() { | ||||
| // display BME sensor data if present
 | ||||
| #ifdef HAS_BME | ||||
|   ESP_LOGI(TAG, "BME680 Temp: %.2f°C | IAQ: %.2f", bme_status.temperature, bme_status.iaq); | ||||
|   updateState(); | ||||
| #endif | ||||
| 
 | ||||
|   // check free heap memory
 | ||||
|  | ||||
| @ -11,18 +11,18 @@ | ||||
| 
 | ||||
| // enable only if device has these sensors, otherwise comment these lines
 | ||||
| // BME680 sensor on I2C bus
 | ||||
| #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 HAS_BME GPIO_NUM_21, GPIO_NUM_22 // SDA, SCL
 | ||||
| //#define BME_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND
 | ||||
| 
 | ||||
| #define HAS_LED GPIO_NUM_14 // on board green LED
 | ||||
| 
 | ||||
| // 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 MY_OLED_SDA (21) | ||||
| #define MY_OLED_SCL (22) | ||||
| #define MY_OLED_RST U8X8_PIN_NONE | ||||
| //#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
 | ||||
| //#define MY_OLED_SDA (21)
 | ||||
| //#define MY_OLED_SCL (22)
 | ||||
| //#define MY_OLED_RST U8X8_PIN_NONE
 | ||||
| //#define DISPLAY_FLIP  1 // use if display is rotated
 | ||||
| 
 | ||||
| #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) | ||||
| #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 | ||||
| #define USE_OTA                         1       // Comment out to disable OTA update | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user