Hello Minhwan, Thank you very much for answering me. Regarding the NVM, yes I'm using a piece of my flash memory to emulate an EEPROM. I have already tested all three modes, LP, ULP, and Normal mode (present in the latest version of the bsec library). However, currently, I'm using it in LP mode. The code is the following (you can also check it out in my GitHub😞 // Bosch Sensor BME680 #include "bsec.h" #include "config/generic_33v_3s_4d/bsec_serialized_configurations_iaq.h" // Bme680 sensor Bsec iaqSensor; // I2C uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0}; uint16_t stateUpdateCounter = 0; void setup(){ /// BME680 //// begin library and retreive the library version iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire); _printf((char*)"\nBSEC library version %u.%u.%u.%u \r\n",iaqSensor.version.major,iaqSensor.version.minor,iaqSensor.version.major_bugfix,iaqSensor.version.minor_bugfix); //// check if bme680 is connected checkIaqSensorStatus(); /// Apply configs to bsec sensor iaqSensor.setConfig(bsec_config_iaq); checkIaqSensorStatus(); /// load state from EEPROM loadState(); //// specify the desired outputs bsec_virtual_sensor_t sensorList[10] = { 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, }; //// update subscription iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP); checkIaqSensorStatus(); } void loop() { if((millis() - bmeLastReading) > BME_680_PERIOD){ bmeLastReading = millis(); if (iaqSensor.run()) { // Temperature payload = myFTOA(iaqSensor.temperature,3,10); mqttClient.beginMessage(outTopic[2], payload.length(), retained, qos, dup); mqttClient.print(payload); mqttClient.endMessage(); // Humidity payload = myFTOA(iaqSensor.humidity,3,10); mqttClient.beginMessage(outTopic[3], payload.length(), retained, qos, dup); mqttClient.print(payload); mqttClient.endMessage(); // raw Temperature payload = myFTOA(iaqSensor.rawTemperature,3,10); mqttClient.beginMessage(outTopic[11], payload.length(), retained, qos, dup); mqttClient.print(payload); mqttClient.endMessage(); // raw Humidity payload = myFTOA(iaqSensor.rawHumidity,3,10); mqttClient.beginMessage(outTopic[12], payload.length(), retained, qos, dup); mqttClient.print(payload); mqttClient.endMessage(); // Pressure payload = myFTOA(iaqSensor.pressure/100.0f,3,10); mqttClient.beginMessage(outTopic[4], payload.length(), retained, qos, dup); mqttClient.print(payload); mqttClient.endMessage(); // IAQ payload = myFTOA(iaqSensor.iaq,3,10); mqttClient.beginMessage(outTopic[5], payload.length(), retained, qos, dup); mqttClient.print(payload); mqttClient.endMessage(); // Static IAQ //payload = myFTOA(iaqSensor.staticIaq,3,10); //mqttClient.beginMessage(outTopic[6], payload.length(), retained, qos, dup); //mqttClient.print(payload); //mqttClient.endMessage(); // Static equivalent CO2 //payload = myFTOA(iaqSensor.co2Equivalent,3,10); //mqttClient.beginMessage(outTopic[7], payload.length(), retained, qos, dup); //mqttClient.print(payload); //mqttClient.endMessage(); // Static equivalent breath VOCs //payload = myFTOA(iaqSensor.breathVocEquivalent,3,10); //mqttClient.beginMessage(outTopic[8], payload.length(), retained, qos, dup); //mqttClient.print(payload); //mqttClient.endMessage(); updateState(); /* _printf((char*)"IAQ Accuracy %u \r\n",iaqSensor.iaqAccuracy); _printf((char*)"Breath Voc Accuracy %u \r\n",iaqSensor.breathVocAccuracy); _printf((char*)"Co2 Accuracy %u \r\n",iaqSensor.co2Accuracy); _printf((char*)"Static Iaq Accuracy %u \r\n",iaqSensor.staticIaqAccuracy); */ } else { checkIaqSensorStatus(); } } } // Helper function definitions void checkIaqSensorStatus(void){ if (iaqSensor.status != BSEC_OK) { if (iaqSensor.status < BSEC_OK) { _printf((char*)"BSEC error code : %d \r\n",iaqSensor.status); for (;;) errLeds(); /* Halt in case of failure */ } else { _printf((char*)"BSEC warning code : %d \r\n",iaqSensor.status); } } if (iaqSensor.bme680Status != BME680_OK) { if (iaqSensor.bme680Status < BME680_OK) { _printf((char*)"BSEC error code : %d \r\n",iaqSensor.bme680Status); for (;;) errLeds(); /* Halt in case of failure */ } else { _printf((char*)"BSEC warning code : %d \r\n",iaqSensor.bme680Status); } } } void errLeds(void){ pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); delay(100); } 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 { uint8_t isEepromErased = 1; for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) { if(EEPROM.read(i + 1) != 0){ isEepromErased = 0; break; } } if(!isEepromErased){ // 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