Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 
    SOLVED

    IAQ Accuracy always 0

    IAQ Accuracy always 0

    jordan982
    Established Member

    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);
    }

    4 REPLIES 4

    Jet
    Occasional Contributor

    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.

        https://github.com/BoschSensortec/BSEC-Arduino-library

        https://github.com/BoschSensortec/BSEC-Arduino-library/blob/master/examples/basic_config_state/basic...

    jordan982
    Established Member

    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);
    }

    jordan982
    Established Member

     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

     

    Jet
    Occasional Contributor

    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.

       

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist