01-07-2021 05:08 PM
Hi all,
after more than 24 hours of use the sensor always returns me the value of the iaq accuracy always at 0 and iaq at 25. The other values seem to be ok. Could you help me?
Thank you
This is my actual sketch:
#include <Arduino.h>
#include <ArduinoJson.h>
#include "bsec.h"
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 180 /* Time ESP32 will go to sleep (in seconds) */
RTC_DATA_ATTR int bootCount = 0;
const char *SSID = "XXXXXX";
const char *PWD = "XXXXXXX";
const char* mqtt_server = "XXXXX";
const char* mqtt_user = "XXXXX";
const char* mqtt_pwd = "XXXXX";
WiFiClientSecure espclientSecure;
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
char msg[MSG_BUFFER_SIZE];
int value = 0;
String output;
StaticJsonDocument<500> jsonDocument;
char buffer[500];
// Create an object of the class Bsec
Bsec iaqSensor;
// env variable
String temperature;
String humidity;
String pressure;
String CO2;
String gasResistance;
String iaq;
int i;
void connectToWiFi() {
Serial.print("Connecting to ");
Serial.println(SSID);
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED) {
if ( i == 15 ){ WiFi.reconnect();}
if (i > 30){
break;
}
delay(500); i++;
}
Serial.print("Connected. IP: ");
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(9600);
// Sensor setup
Wire.begin();
iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire);
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,
};
iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
checkIaqSensorStatus();
connectToWiFi();
client.setServer(mqtt_server, 1883);
}
void loop() {
if (!client.connected()) {
connectToWiFi();
delay(5000);
reconnect();
}
setCpuFrequencyMhz(160);
++value;
snprintf (msg, MSG_BUFFER_SIZE, "Nuovi dati letti, count: #%ld", value);
Serial.print("Publish message: ");
Serial.println(msg);
iaqSensor.run();
temperature = (String)iaqSensor.temperature;
humidity = (String)iaqSensor.humidity;
iaq = (String)iaqSensor.iaq;
pressure = (String)(iaqSensor.pressure / 100);
gasResistance = (String)iaqSensor.gasResistance;
Serial.println("Umidità:"+(String)iaqSensor.humidity);
Serial.println("Temperatura:"+(String)iaqSensor.temperature);
Serial.println("IAQ:"+(String)iaqSensor.iaq);
Serial.println("Pressure:"+(String)(iaqSensor.pressure/100));
Serial.println("Gas Resistance:"+(String)iaqSensor.gasResistance);
//PubSubClient::setBufferSize(500);
setJsonValues(iaqSensor.temperature, iaqSensor.humidity, iaqSensor.gasResistance, iaqSensor.pressure, iaqSensor.iaq);
size_t n = serializeJson(jsonDocument, buffer);
client.publish("esp32/output", buffer, n);
String messageTemperature = "Temperatura:"+(String)iaqSensor.temperature;
bot.sendMessage(CHAT_ID, messageTemperature, "");
delay(3000);
client.disconnect();
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); // ESP32 wakes up every 5 seconds
Serial.println("Going to light-sleep now");
Serial.flush();
setCpuFrequencyMhz(80);
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
btStop();
esp_light_sleep_start();
}
// Helper function definitions
void checkIaqSensorStatus(void)
{
if (iaqSensor.status != BSEC_OK) {
if (iaqSensor.status < BSEC_OK) {
output = "BSEC error code : " + String(iaqSensor.status);
Serial.println(output);
for (;;)
errLeds(); /* Halt in case of failure */
Serial.println("Restarting in 10 seconds");
delay(10000);
ESP.restart();
} else {
output = "BSEC warning code : " + String(iaqSensor.status);
Serial.println(output);
}
}
if (iaqSensor.bme680Status != BME680_OK) {
if (iaqSensor.bme680Status < BME680_OK) {
output = "BME680 error code : " + String(iaqSensor.bme680Status);
Serial.println(output);
for (;;)
errLeds(); /* Halt in case of failure */
Serial.println("Restarting in 10 seconds");
delay(10000);
ESP.restart();
} else {
output = "BME680 warning code : " + String(iaqSensor.bme680Status);
Serial.println(output);
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP32Cameretta-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str(), mqtt_user, mqtt_pwd)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void add_json_object(char *tag, float value, char *unit) {
JsonObject obj = jsonDocument.createNestedObject();
obj["type"] = tag;
obj["value"] = value;
obj["unit"] = unit;
}
void setJsonValues(float temperature, float humidity, float gasResistance, float pressure, float iaq) {
jsonDocument.clear();
Serial.println("Get env");
add_json_object("temperature", temperature, "°C");
add_json_object("humidity", humidity, "%");
add_json_object("gas", gasResistance, "ohm");
add_json_object("pressure", pressure, "mBar");
add_json_object("iaq", iaq, "IAQ");
}
void errLeds(void)
{
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
delay(200);
digitalWrite(LED_BUILTIN, LOW);
delay(200);
}
Solved! Go to Solution.
01-08-2021 07:50 AM
Hi Sir:
Did you verify other example code? In this code, I didn't find this function, iaqSensor.setConfig(bsec_config_iaq), which configure the BSEC library with information about the sensor.
I recommend you to test other reference code or refer to them to modify your code.
Look the following links to know more information.
01-08-2021 04:23 PM - edited 01-08-2021 04:26 PM
Thanks for the reply.
I started with your examples to write my code. I've already added that line of code, but I still can't get an iac accuracy other than 0.
LoadState and UpdateState are necessary for iaq accuracy and iaq static values?
Here the updated sketch:
#include <Arduino.h>
#include <ArduinoJson.h>
#include <UniversalTelegramBot.h>
#include "bsec.h"
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
const uint8_t bsec_config_iaq[] = {
#include "config/generic_33v_3s_4d/bsec_iaq.txt"
};
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 600 /* Time ESP32 will go to sleep (in seconds) */
RTC_DATA_ATTR int bootCount = 0;
const char *SSID = "XXXXX";
const char *PWD = "XXXXX";
const char* mqtt_server = "XXXXXX";
const char* mqtt_user = "XXXXXX";
const char* mqtt_pwd = "XXXXX";
WiFiClientSecure espclientSecure;
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;
String output;
StaticJsonDocument<800> jsonDocument;
char buffer[800];
// Use @myidbot to find out the chat ID of an individual or a group
// Also note that you need to click "start" on a bot before it can
// message you
#define CHAT_ID "XXXXX"
// Initialize Telegram BOT
#define BOTtoken "XXXXXX" // your Bot Token (Get from Botfather)
UniversalTelegramBot bot(BOTtoken, espclientSecure);
// Create an object of the class Bsec
Bsec iaqSensor;
// env variable
String temperature;
String humidity;
String pressure;
String CO2;
String gasResistance;
String iaq;
int i;
void connectToWiFi() {
Serial.print("Connecting to ");
Serial.println(SSID);
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED) {
if ( i == 15 ){ WiFi.reconnect();}
if (i > 30){
break;
}
delay(500); i++;
}
Serial.print("Connected. IP: ");
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(9600);
#ifdef ESP8266
espclientSecure.setInsecure();
#endif
// Sensor setup
Wire.begin();
iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire);
iaqSensor.setConfig(bsec_config_iaq);
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,
};
iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
checkIaqSensorStatus();
connectToWiFi();
client.setServer(mqtt_server, XXXX);
}
void loop() {
if (!client.connected()) {
reconnect();
}
setCpuFrequencyMhz(160);
++value;
snprintf (msg, MSG_BUFFER_SIZE, "Nuovi dati letti, count: #%ld", value);
Serial.print("Publish message: ");
Serial.println(msg);
if (iaqSensor.run()) {
Serial.println("Umidità:"+(String)iaqSensor.humidity);
Serial.println("Temperatura:"+(String)iaqSensor.temperature);
Serial.println("IAQ:"+(String)iaqSensor.iaq);
Serial.println("Pressure:"+(String)(iaqSensor.pressure/100));
Serial.println("Gas Resistance:"+(String)iaqSensor.gasResistance);
Serial.print("IAQ Accuracy:" + String(iaqSensor.iaqAccuracy));
Serial.print("Static IAQ: " + String(iaqSensor.staticIaq));
Serial.print("CO2Equivalent: " + String(iaqSensor.co2Equivalent));
Serial.print("BreathVocEquivalent: " + String(iaqSensor.breathVocEquivalent));
//PubSubClient::setBufferSize(500);
setJsonValues(iaqSensor.temperature, iaqSensor.humidity, iaqSensor.gasResistance, iaqSensor.pressure, iaqSensor.iaq,iaqSensor.iaqAccuracy, iaqSensor.staticIaq, iaqSensor.co2Equivalent, iaqSensor.breathVocEquivalent);
size_t n = serializeJson(jsonDocument, buffer);
client.publish("esp32/cameretta/sensor", buffer, n);
String messageTemperature = "Temperatura:"+(String)iaqSensor.temperature;
bot.sendMessage(CHAT_ID, messageTemperature, "");
delay(3000);
client.disconnect();
startLightSleep();
}else{
checkIaqSensorStatus();
}
}
void startLightSleep(void){
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); // ESP32 wakes up every 5 seconds
Serial.println("Going to light-sleep now");
Serial.flush();
setCpuFrequencyMhz(80);
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
btStop();
esp_light_sleep_start();
}
// Helper function definitions
void checkIaqSensorStatus(void)
{
if (iaqSensor.status != BSEC_OK) {
if (iaqSensor.status < BSEC_OK) {
output = "BSEC error code : " + String(iaqSensor.status);
Serial.println(output);
bot.sendMessage(CHAT_ID, output, "");
for (;;)
errLeds(); /* Halt in case of failure */
Serial.println("Restarting in 10 seconds");
delay(10000);
ESP.restart();
} else {
output = "BSEC warning code : " + String(iaqSensor.status);
Serial.println(output);
bot.sendMessage(CHAT_ID, output, "");
}
}
if (iaqSensor.bme680Status != BME680_OK) {
if (iaqSensor.bme680Status < BME680_OK) {
output = "BME680 error code : " + String(iaqSensor.bme680Status);
Serial.println(output);
bot.sendMessage(CHAT_ID, output, "");
for (;;)
errLeds(); /* Halt in case of failure */
Serial.println("Restarting in 10 seconds");
delay(10000);
ESP.restart();
} else {
output = "BME680 warning code : " + String(iaqSensor.bme680Status);
Serial.println(output);
bot.sendMessage(CHAT_ID, output, "");
}
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP32Cameretta-";
clientId += String(random(0xffff), HEX);
if(WiFi.status() != WL_CONNECTED){
connectToWiFi();
}
// Attempt to connect
client.connect(clientId.c_str(), mqtt_user, mqtt_pwd);
if (client.connected()) {
Serial.println("connected");
bot.sendMessage(CHAT_ID, "Connected to MQTT Server", "");
// Once connected, publish an announcement...
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
String errorConnectMqtt = "failed to connect to MQTT Server try again in 5 seconds";
bot.sendMessage(CHAT_ID, errorConnectMqtt, "");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void add_json_object(char *tag, float value, char *unit) {
JsonObject obj = jsonDocument.createNestedObject();
obj["type"] = tag;
obj["value"] = value;
obj["unit"] = unit;
}
void setJsonValues(float temperature, float humidity, float gasResistance, float pressure, float iaq, int iaqAccuracy, int staticIaq, float co2Equivalent, float breathVocEquivalent ) {
jsonDocument.clear();
Serial.println("Get env");
add_json_object("temperature", temperature, "°C");
add_json_object("humidity", humidity, "%");
add_json_object("gas", gasResistance, "ohm");
add_json_object("pressure", pressure, "mBar");
add_json_object("iaq", iaq, "IAQ");
add_json_object("iaqAccuracy", iaqAccuracy, "IAQ");
add_json_object("staticIaq", staticIaq, "IAQ");
add_json_object("co2Equivalent", co2Equivalent, "ppm");
add_json_object("breathVocEquivalent", breathVocEquivalent, "ppm");
}
void errLeds(void)
{
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
delay(200);
digitalWrite(LED_BUILTIN, LOW);
delay(200);
}
01-09-2021 01:02 PM
I'm a newbie in arduino, after a code review the value of iaq accuracy goes to 1 after 100 reads (I had to disable the light sleep).
The problem is that after more than 12 hours of operation the value remains stationary at 1 and the value of the iaq is very high (more than 200) while the value of the static iaq is still at 65. How many hours does it take for the value of iaq accuracy to reach 3?
Thank you
01-11-2021 08:29 AM
Hi Sir:
If accuracy is not 3, the results is not used. Long time is important for calibration, but environmental airflow also is necessary.
You should place sensor to a good ail environment or a bad air environment. Sensor know what is bad or what is good after change airflow around sensor.
And its calibration will be finished.