Hello Robin, thank you for your answer.. next time I'll look at all the examples. But I have tried out the load and update function. After restarting the ESP32 the IAQ state goes directly to 0. It look like, it doesn't overwrite the state. I printed the eeprom data (after the four Sensor has IAQ state 3) and there were a lot of hex information. Do I anything wrong? Here is my IDE code: #include <EEPROM.h>
#include "bsec.h"
#include <Wire.h>
#define TCAADDR 0x70
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
/* Configure the BSEC library with information about the sensor
18v/33v = Voltage at Vdd. 1.8V or 3.3V
3s/300s = BSEC operating mode, BSEC_SAMPLE_RATE_LP or BSEC_SAMPLE_RATE_ULP
4d/28d = Operating age of the sensor in days
generic_18v_3s_4d
generic_18v_3s_28d
generic_18v_300s_4d
generic_18v_300s_28d
generic_33v_3s_4d
generic_33v_3s_28d
generic_33v_300s_4d
generic_33v_300s_28d
*/
const uint8_t bsec_config_iaq[] = {
#include "config/generic_33v_3s_4d/bsec_iaq.txt"
};
#define STATE_SAVE_PERIOD UINT32_C(60000) // 360 minutes - 4 times a day
#define N_SENSORS 4
// Helper functions declarations
void checkIaqSensorStatus(void);
void errLeds(void);
void loadState(void);
void updateState(void);
// Create objects of the class Bsec
Bsec iaqSensor1, iaqSensor2, iaqSensor3, iaqSensor4;
uint8_t bsecState1[BSEC_MAX_STATE_BLOB_SIZE], bsecState2[BSEC_MAX_STATE_BLOB_SIZE], bsecState3[BSEC_MAX_STATE_BLOB_SIZE], bsecState4[BSEC_MAX_STATE_BLOB_SIZE];
uint16_t stateUpdateCounter = 0;
String output;
// Entry point for the example
void setup(void) {
EEPROM.begin((N_SENSORS * BSEC_MAX_STATE_BLOB_SIZE) + 1); // 1st address for the length of one state
Serial.begin(115200);
Wire.begin();
tcaselect(0);
iaqSensor1.begin(0x77, Wire);
tcaselect(1);
iaqSensor2.begin(0x77, Wire);
tcaselect(2);
iaqSensor3.begin(0x77, Wire);
tcaselect(3);
iaqSensor4.begin(0x77, Wire);
tcaselect(0);
output = "\nBSEC library version " + String(iaqSensor1.version.major) + "." + String(iaqSensor1.version.minor) + "." + String(iaqSensor1.version.major_bugfix) + "." + String(iaqSensor1.version.minor_bugfix);
Serial.println(output);
checkIaqSensorStatus();
tcaselect(0);
iaqSensor1.setConfig(bsec_config_iaq);
tcaselect(1);
iaqSensor2.setConfig(bsec_config_iaq);
tcaselect(2);
iaqSensor3.setConfig(bsec_config_iaq);
tcaselect(3);
iaqSensor4.setConfig(bsec_config_iaq);
checkIaqSensorStatus();
loadState();
bsec_virtual_sensor_t sensorList[3] = {
BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
};
tcaselect(0);
iaqSensor1.updateSubscription(sensorList, 3, BSEC_SAMPLE_RATE_LP);
tcaselect(1);
iaqSensor2.updateSubscription(sensorList, 3, BSEC_SAMPLE_RATE_LP);
tcaselect(2);
iaqSensor3.updateSubscription(sensorList, 3, BSEC_SAMPLE_RATE_LP);
tcaselect(3);
iaqSensor4.updateSubscription(sensorList, 3, BSEC_SAMPLE_RATE_LP);
checkIaqSensorStatus();
// Print the header
output = "Sensor, Timestamp [ms], raw temperature [°C], pressure [hPa], raw relative humidity [%], gas [Ohm], IAQ, IAQ accuracy, temperature [°C], relative humidity [%]";
Serial.println(output);
}
// Function that is looped forever
void loop(void) {
unsigned long time_trigger = millis();
if (iaqSensor1.run()) { // If new data is available
output = "1, " + String("EINS: ");
output += ", " + String(iaqSensor1.iaq);
output += ", " + String(iaqSensor1.iaqAccuracy);
output += ", " + String(iaqSensor1.temperature);
output += ", " + String(iaqSensor1.humidity);
Serial.println(output);
updateState();
} else {
checkIaqSensorStatus();
}
tcaselect(1);
if (iaqSensor2.run()) { // If new data is available
output = "2, " + String("ZWEI: ");
output += ", " + String(iaqSensor2.iaq);
output += ", " + String(iaqSensor2.iaqAccuracy);
output += ", " + String(iaqSensor2.temperature);
output += ", " + String(iaqSensor2.humidity);
Serial.println(output);
updateState();
} else {
checkIaqSensorStatus();
}
tcaselect(2);
if (iaqSensor3.run()) { // If new data is available
output = "1, " + String("DREI: ");
output += ", " + String(iaqSensor3.iaq);
output += ", " + String(iaqSensor3.iaqAccuracy);
output += ", " + String(iaqSensor3.temperature);
output += ", " + String(iaqSensor3.humidity);
Serial.println(output);
updateState();
} else {
checkIaqSensorStatus();
}
tcaselect(3);
if (iaqSensor4.run()) { // If new data is available
output = "2, " + String("VIER: ");
output += ", " + String(iaqSensor4.iaq);
output += ", " + String(iaqSensor4.iaqAccuracy);
output += ", " + String(iaqSensor4.temperature);
output += ", " + String(iaqSensor4.humidity);
Serial.println(output);
updateState();
} else {
checkIaqSensorStatus();
}
}
// Helper function definitions
void checkIaqSensorStatus(void) {
tcaselect(0);
if (iaqSensor1.status != BSEC_OK) {
if (iaqSensor1.status < BSEC_OK) {
output = "BSEC1 error code : " + String(iaqSensor1.status);
Serial.println(output);
// for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BSEC warning code : " + String(iaqSensor1.status);
Serial.println(output);
}
}
if (iaqSensor1.bme680Status != BME680_OK) {
if (iaqSensor1.bme680Status < BME680_OK) {
output = "BME6801 error code : " + String(iaqSensor1.bme680Status);
Serial.println(output);
// for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BME680 warning code : " + String(iaqSensor1.bme680Status);
Serial.println(output);
}
}
iaqSensor1.status = BSEC_OK;
tcaselect(1);
if (iaqSensor2.status != BSEC_OK) {
if (iaqSensor2.status < BSEC_OK) {
output = "BSEC error code : " + String(iaqSensor2.status);
Serial.println(output);
// for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BSEC warning code : " + String(iaqSensor2.status);
Serial.println(output);
}
}
if (iaqSensor2.bme680Status != BME680_OK) {
if (iaqSensor2.bme680Status < BME680_OK) {
output = "BME680 error code : " + String(iaqSensor2.bme680Status);
Serial.println(output);
// for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BME680 warning code : " + String(iaqSensor2.bme680Status);
Serial.println(output);
}
}
iaqSensor2.status = BSEC_OK;
tcaselect(2);
if (iaqSensor3.status != BSEC_OK) {
if (iaqSensor3.status < BSEC_OK) {
output = "BSEC1 error code : " + String(iaqSensor3.status);
Serial.println(output);
// for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BSEC warning code : " + String(iaqSensor3.status);
Serial.println(output);
}
}
if (iaqSensor3.bme680Status != BME680_OK) {
if (iaqSensor3.bme680Status < BME680_OK) {
output = "BME6801 error code : " + String(iaqSensor3.bme680Status);
Serial.println(output);
// for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BME680 warning code : " + String(iaqSensor3.bme680Status);
Serial.println(output);
}
}
iaqSensor3.status = BSEC_OK;
tcaselect(3);
if (iaqSensor4.status != BSEC_OK) {
if (iaqSensor4.status < BSEC_OK) {
output = "BSEC error code : " + String(iaqSensor4.status);
Serial.println(output);
// for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BSEC warning code : " + String(iaqSensor4.status);
Serial.println(output);
}
}
if (iaqSensor4.bme680Status != BME680_OK) {
if (iaqSensor4.bme680Status < BME680_OK) {
output = "BME680 error code : " + String(iaqSensor4.bme680Status);
Serial.println(output);
for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BME680 warning code : " + String(iaqSensor4.bme680Status);
Serial.println(output);
}
}
iaqSensor4.status = BSEC_OK;
}
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++) {
bsecState1[i] = EEPROM.read(i + 1);
bsecState2[i] = EEPROM.read(i + 1 + BSEC_MAX_STATE_BLOB_SIZE);
bsecState3[i] = EEPROM.read(i + 1 + BSEC_MAX_STATE_BLOB_SIZE + BSEC_MAX_STATE_BLOB_SIZE);
bsecState4[i] = EEPROM.read(i + 1 + BSEC_MAX_STATE_BLOB_SIZE + BSEC_MAX_STATE_BLOB_SIZE + BSEC_MAX_STATE_BLOB_SIZE);
//Serial.println(String(bsecState1[i], HEX) + ", " + String(bsecState2[i], HEX) + ", " + String(bsecState3[i], HEX) + ", " + String(bsecState4[i], HEX));
}
tcaselect(0);
iaqSensor1.setState(bsecState1);
tcaselect(1);
iaqSensor2.setState(bsecState2);
tcaselect(2);
iaqSensor3.setState(bsecState3);
tcaselect(3);
iaqSensor4.setState(bsecState4);
checkIaqSensorStatus();
} else {
// Erase the EEPROM with zeroes
Serial.println("Erasing EEPROM");
for (uint16_t i = 0; i < (N_SENSORS * 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 ((iaqSensor1.iaqAccuracy >= 3) || (iaqSensor2.iaqAccuracy >= 3) || (iaqSensor3.iaqAccuracy >= 3) || (iaqSensor4.iaqAccuracy >= 3)) {
update = true;
stateUpdateCounter++;
}
} else {
/* Update every STATE_SAVE_PERIOD milliseconds */
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
update = true;
stateUpdateCounter++;
}
}
if (update) {
tcaselect(0);
iaqSensor1.getState(bsecState1);
tcaselect(1);
iaqSensor2.getState(bsecState2);
tcaselect(2);
iaqSensor3.getState(bsecState3);
tcaselect(3);
iaqSensor4.getState(bsecState4);
checkIaqSensorStatus();
Serial.println("Writing state(s) to EEPROM");
for (uint16_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) {
EEPROM.write(i + 1, bsecState1[i]);
EEPROM.write(i + 1 + BSEC_MAX_STATE_BLOB_SIZE, bsecState2[i]);
EEPROM.write(i + 1 + BSEC_MAX_STATE_BLOB_SIZE + BSEC_MAX_STATE_BLOB_SIZE, bsecState3[i]);
EEPROM.write(i + 1 + BSEC_MAX_STATE_BLOB_SIZE + BSEC_MAX_STATE_BLOB_SIZE + BSEC_MAX_STATE_BLOB_SIZE, bsecState4[i]);
// Serial.println(String(bsecState1[i], HEX) + ", " + String(bsecState2[i], HEX) + ", " + String(bsecState3[i], HEX) + ", " + String(bsecState4[i], HEX));
}
EEPROM.write(0, BSEC_MAX_STATE_BLOB_SIZE);
EEPROM.commit();
}
}
... View more