07-10-2020 09:10 PM
Hello,
So been trying to increase the sleep time of the esp32 to 20minutes. I wrote an algorithm to trick the sensor into recieving measurement triggers at 3 second intervals it worked on ESP-IDF but for some reason it is not working on Arduino.
I use a marker to calibrate it, the accuracy reaches 3 but as soon as I remove the marker, the air quality starts going down and then it just stays at 25 and the accuracy goes down to 2. There is no way that my room has 25 air quality index because its very hot. I also have an off the shelf sensor at home that shows the airquality to be 109. So clearly there is an issue here.
Only when im breathing on the sensor the air quality index would increase and accuracy would go to 3 but then as soon as I move away it would drop. Seems like a sensitivity issue? But this algorithm works perfectly fine on ESP-IDF.
Below is the code please advise.
#include <Arduino.h>
#include <EEPROM.h>
#include "cJSON.h"
//-----------------BME libraries and functions---------------
#include <bsec.h>
const uint8_t bsec_config_iaq[] = {
#include "config/generic_33v_3s_4d/bsec_iaq.txt"
};
Bsec sensor;
RTC_DATA_ATTR uint8_t sensor_state[BSEC_MAX_STATE_BLOB_SIZE] = {0};
RTC_DATA_ATTR static uintmax_t timestampDS = 0;
int timeToSleepAdd = 3*1000;
bsec_virtual_sensor_t sensor_list[5] = {
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_STATIC_IAQ,
BSEC_OUTPUT_CO2_EQUIVALENT,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
};
int64_t GetTimestamp() {
int64_t timeret;
if (timestampDS == 0) {
struct timeval tv;
gettimeofday(&tv, NULL);
timeret = (tv.tv_sec * 1000LL) + tv.tv_usec / 1000LL;
timestampDS = timeret;
return timeret;
} else {
timestampDS = timestampDS + timeToSleepAdd;
return timestampDS;
}
}
bool CheckSensor() {
if (sensor.status < BSEC_OK) {
Serial.println("BSEC error, status");
return false;;
} else if (sensor.status > BSEC_OK) {
Serial.println("BSEC warning, status ");
}
if (sensor.bme680Status < BME680_OK) {
Serial.println("Sensor error, bme680_status ");
return false;
} else if (sensor.bme680Status > BME680_OK) {
Serial.println("Sensor warning, status ");
}
return true;
}
//-----------------BME libraries and functions---------------
//-----------------Sleep and Timeout settings----------------
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 1200
//-----------------Sleep and Timeout settings----------------
void setup() {
EEPROM.begin(BSEC_MAX_STATE_BLOB_SIZE + 1);
Serial.begin(115200);
Wire.begin(13, 16);
//-------------BME Setup----------------------
sensor.begin(BME680_I2C_ADDR_PRIMARY, Wire);
sensor.setConfig(bsec_config_iaq);
loadState();
sensor.updateSubscription(sensor_list, 5, BSEC_SAMPLE_RATE_LP);
sensor.status = BSEC_OK;
cJSON *root = cJSON_CreateObject();
if (sensor.run(GetTimestamp())) {
cJSON_AddItemToObject(root, "name", cJSON_CreateString(devName));
cJSON_AddNumberToObject(root, "temperature", sensor.temperature);
cJSON_AddNumberToObject(root, "humidity", sensor.humidity + 3);
cJSON_AddNumberToObject(root, "pressure", sensor.pressure / 1000);
cJSON_AddNumberToObject(root, "co2", sensor.co2Equivalent);
cJSON_AddNumberToObject(root, "airquality", sensor.staticIaq);
cJSON_AddNumberToObject(root, "accuracy", sensor.staticIaqAccuracy);
dataToSend = cJSON_PrintUnformatted(root);
updateState();
}
//-------------BME Setup----------------------
cJSON_Delete(root);
free(dataToSend);
}
void loop() {
}
void updateState(void)
{
sensor.getState(sensor_state);
for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE ; i++) {
EEPROM.write(i + 1, sensor_state[i]);
}
EEPROM.write(0, BSEC_MAX_STATE_BLOB_SIZE);
EEPROM.commit();
}
void loadState(void)
{
if (EEPROM.read(0) == BSEC_MAX_STATE_BLOB_SIZE) {
for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) {
sensor_state[i] = EEPROM.read(i + 1);
}
sensor.setState(sensor_state);
} else {
for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE + 1; i++)
EEPROM.write(i, 0);
EEPROM.commit();
}
}
void gotoSleep() {
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
esp_deep_sleep_start();
}
Solved! Go to Solution.
07-10-2020 11:12 PM
the IAQ output as 25 with accuracy level down to 2 is more like a calculation overflow happened inside BSEC.
if it is from different platform, you may need to check the data type difference on those two platform.
One more thing: if you don't enable this sleep funcion, just keep original 3s interval, do you still see this issue or not?
07-11-2020 01:09 AM
Thank you for the reply vincent.
How would I solve the calculation overflow?
What do you mean by if its from a different platform?
No thats the default code and it's given that it would work fine (and it does). Im trying to not run it at 3second interval.
07-14-2020 01:38 AM - edited 07-14-2020 01:40 AM
The same code works on ESP32 IDE with correct value output. but failed on Arduino with wrong value output.
That is the reason i guess there is platform issue to cause calculation over flow and want to understand if you use 3s interval the Arduino platform works fine or not.
07-15-2020 01:24 AM
After further discussion with the algorithm team, 20 minutes interval may cause the lib to enter run in status then you will get 25 as IAQ output.
Our BSEC is currently not support this time interval now.
So, please try with standard 3s interval first.