Bosch Sensortec Community

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

    BME680 without VOC and CO2 data

    BME680 without VOC and CO2 data

    thobastian
    New Poster

    Hello ,

    I'm in your forum, because I have problems with your BME680.

    I need datas  temperature,humidity, pressure, IAQ and voc/co2.

    The mainly problem are the data VOC and CO2. The datas are always zero.

    I use mainly your example bsec code plus WLAN and MQTT code for my esp8266.

    I use the BSEC lib v1.4.7.2

    can you help me?

    /*!
     * @file bsec_iot_example.ino
     *
     * @brief
     * Example for using of BSEC library in a fixed configuration with the BME680 sensor.
     * This works by running an endless loop in the bsec_iot_loop() function.
     */
    
    /*!
     * @addtogroup bsec_examples BSEC Examples
     * @brief BSEC usage examples
     * @{*/
    
    /**********************************************************************************************************************/
    /* header files */
    /**********************************************************************************************************************/
    
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    #include <Wire.h>
    #include <SPI.h>
    #include "bsec_integration.h"
    #include <Wire.h>
    
    const char* SSID = "*SSID NAME*";
    const char* PSK = "*PASSWORD*";
    const char* MQTT_BROKER = "192.168.178.41";
     
    WiFiClient espClient;
    PubSubClient client(espClient);
    long lastMsg = 0;
    char msg[50];
    int value = 0;
    // Hilfsvariablen für die Convertierung der Temperatur in ein String
    char tempBuffer[100];
    
    /**********************************************************************************************************************/
    /* functions */
    /**********************************************************************************************************************/
    
    /*!
     * @brief           Write operation in either Wire or SPI
     *
     * param[in]        dev_addr        Wire or SPI device address
     * param[in]        reg_addr        register address
     * param[in]        reg_data_ptr    pointer to the data to be written
     * param[in]        data_len        number of bytes to be written
     *
     * @return          result of the bus communication function
     */
    int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
    {
        Wire.beginTransmission(dev_addr);
        Wire.write(reg_addr);    /* Set register address to start writing to */
     
        /* Write the data */
        for (int index = 0; index < data_len; index++) {
            Wire.write(reg_data_ptr[index]);
        }
     
        return (int8_t)Wire.endTransmission();
    }
    
    /*!
     * @brief           Read operation in either Wire or SPI
     *
     * param[in]        dev_addr        Wire or SPI device address
     * param[in]        reg_addr        register address
     * param[out]       reg_data_ptr    pointer to the memory to be used to store the read data
     * param[in]        data_len        number of bytes to be read
     *
     * @return          result of the bus communication function
     */
    int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
    {
        int8_t comResult = 0;
        Wire.beginTransmission(dev_addr);
        Wire.write(reg_addr);                    /* Set register address to start reading from */
        comResult = Wire.endTransmission();
     
        delayMicroseconds(150);                 /* Precautionary response delay */
        Wire.requestFrom(dev_addr, (uint8_t)data_len);    /* Request data */
     
        int index = 0;
        while (Wire.available())  /* The slave device may send less than requested (burst read) */
        {
            reg_data_ptr[index] = Wire.read();
            index++;
        }
     
        return comResult;
    }
    
    /*!
     * @brief           System specific implementation of sleep function
     *
     * @param[in]       t_ms    time in milliseconds
     *
     * @return          none
     */
    void sleep(uint32_t t_ms)
    {
        delay(t_ms);
    }
    
    /*!
     * @brief           Capture the system time in microseconds
     *
     * @return          system_current_time    current system timestamp in microseconds
     */
    int64_t get_timestamp_us()
    {
        return (int64_t) millis() * 1000;
    }
    
    /*!
     * @brief           Handling of the ready outputs
     *
     * @param[in]       timestamp       time in nanoseconds
     * @param[in]       iaq             IAQ signal
     * @param[in]       iaq_accuracy    accuracy of IAQ signal
     * @param[in]       temperature     temperature signal
     * @param[in]       humidity        humidity signal
     * @param[in]       pressure        pressure signal
     * @param[in]       raw_temperature raw temperature signal
     * @param[in]       raw_humidity    raw humidity signal
     * @param[in]       gas             raw gas sensor signal
     * @param[in]       bsec_status     value returned by the bsec_do_steps() call
     *
     * @return          none
     */
    void output_ready(int64_t timestamp, float iaq, uint8_t iaq_accuracy, float temperature, float humidity,
         float pressure, float raw_temperature, float raw_humidity, float gas, bsec_library_return_t bsec_status,
         float static_iaq, float co2_equivalent, float breath_voc_equivalent)
    {
        if (!client.connected()) {
        reconnect();
        }
        client.loop();
        snprintf (msg, 50, "In Betrieb seit %ld milliseconds", millis());
        Serial.print("[");
        Serial.print(timestamp/1e6);
        Serial.print("] T: ");
        Serial.print(temperature);
        client.publish("/home/Temperatur", dtostrf(temperature, 1, 2, tempBuffer));
    // in Grad
        Serial.print("| rH: ");
        Serial.print(humidity);
        client.publish("/home/Feuchtigkeit", dtostrf(humidity, 1, 2, tempBuffer));
    // in %
    Serial.print("| IAQ: ");
        Serial.print(iaq);
        client.publish("/home/IAQ", dtostrf(iaq, 1, 2, tempBuffer));
        Serial.print(" (");
        Serial.print(iaq_accuracy);
        Serial.print("| Static IAQ: ");
        Serial.print(static_iaq);
        Serial.print("| CO2e: ");
        Serial.print(co2_equivalent);
        client.publish("/home/CO2", dtostrf(co2_equivalent, 1, 2, tempBuffer));
        Serial.print("| bVOC: ");
        Serial.println(breath_voc_equivalent);
        client.publish("/home/VOC", dtostrf(breath_voc_equivalent, 1, 2, tempBuffer));
        client.publish("/home/Luftdruck", dtostrf(pressure/100.0, 1, 2, tempBuffer));
    }
    
    /*!
     * @brief           Load previous library state from non-volatile memory
     *
     * @param[in,out]   state_buffer    buffer to hold the loaded state string
     * @param[in]       n_buffer        size of the allocated state buffer
     *
     * @return          number of bytes copied to state_buffer
     */
    uint32_t state_load(uint8_t *state_buffer, uint32_t n_buffer)
    {
        // ...
        // Load a previous library state from non-volatile memory, if available.
        //
        // Return zero if loading was unsuccessful or no state was available, 
        // otherwise return length of loaded state string.
        // ...
        return 0;
    }
    
    /*!
     * @brief           Save library state to non-volatile memory
     *
     * @param[in]       state_buffer    buffer holding the state to be stored
     * @param[in]       length          length of the state string to be stored
     *
     * @return          none
     */
    void state_save(const uint8_t *state_buffer, uint32_t length)
    {
        // ...
        // Save the string some form of non-volatile memory, if possible.
        // ...
    }
    
    /*!
     * @brief           Load library config from non-volatile memory
     *
     * @param[in,out]   config_buffer    buffer to hold the loaded state string
     * @param[in]       n_buffer        size of the allocated state buffer
     *
     * @return          number of bytes copied to config_buffer
     */
    uint32_t config_load(uint8_t *config_buffer, uint32_t n_buffer)
    {
        // ...
        // Load a library config from non-volatile memory, if available.
        //
        // Return zero if loading was unsuccessful or no config was available, 
        // otherwise return length of loaded config string.
        // ...
        return 0;
    }
    
    /*!
     * @brief       Main function which configures BSEC library and then reads and processes the data from sensor based
     *              on timer ticks
     *
     * @return      result of the processing
     */
    void setup()
    {
        return_values_init ret;
    
        /* Init I2C and serial and WLAN/MQTT communication */
        Wire.begin();
        Serial.begin(115200);
        setup_wifi();
        client.setServer(MQTT_BROKER, 1883);
        
        /* Call to the function which initializes the BSEC library 
         * Switch on low-power mode and provide no temperature offset */
        ret = bsec_iot_init(BSEC_SAMPLE_RATE_LP, 5.0f, bus_write, bus_read, sleep, state_load, config_load);
        if (ret.bme680_status)
        {
            /* Could not intialize BME680 */
            Serial.println("Error while initializing BME680");
            return;
        }
        else if (ret.bsec_status)
        {
            /* Could not intialize BSEC library */
            Serial.println("Error while initializing BSEC library");
            return;
        }
        
        /* Call to endless loop function which reads and processes data based on sensor settings */
        /* State is saved every 10.000 samples, which means every 10.000 * 3 secs = 500 minutes  */
        bsec_iot_loop(sleep, get_timestamp_us, output_ready, state_save, 10000);
    }
    
    void setup_wifi() {
        delay(10);
        Serial.println();
        Serial.print("Connecting to ");
        Serial.println(SSID);
     
        WiFi.begin(SSID, PSK);
     
        while (WiFi.status() != WL_CONNECTED) {
            delay(500);
            Serial.print(".");
        }
     
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
    }
     
    void reconnect() {
        while (!client.connected()) {
            Serial.print("Reconnecting...");
            if (!client.connect("ESP8266Client")) {
                Serial.print("failed, rc=");
                Serial.print(client.state());
                Serial.println(" retrying in 5 seconds");
                delay(5000);
            }
        }
      // Initialisierung von  Oversampling und Filter
      bme.setTemperatureOversampling(BME680_OS_8X);
      bme.setHumidityOversampling(BME680_OS_2X);
      bme.setPressureOversampling(BME680_OS_4X);
      bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
      bme.setGasHeater(320, 150); // 320*C for 150 ms
    }
    void loop()
    {
    
     }
    
    /*! @}*/

     

    3 REPLIES 3

    handytech
    Community Moderator
    Community Moderator

    Based on your code snippet, it seems that you are using our bsec_integration.c sample code. As you have found in this other thread, you will need to subscribe to the specific virtual outputs you would like to enable. In bsec_integration.c, this is done in the fuction bme680_bsec_update_subscription(). To enable the eCO2 and bVOC outputs, please make sure BSEC_OUTPUT_CO2_EQUIVALENT and BSEC_OUTPUT_BREATH_VOC_EQUIVALENT are correctly fed into bsec_update_subscription().

    A few comments after a brief overlook at your code snippet:

    • If you are following our sample code (and for most standard BSEC applications), the sensor configurations are handled automatically, therefore they should not be overwritten in reconnect(),
    • BSEC requires precise timings. As it seems you have currently selected BSEC's Low-Power mode (LP), you will need to meet the 3s sampling interval for BSEC to run properly. But in your function reconnect(), you have inserted a blocking loop with 5s delays, therefore BSEC will be significantly interrupted and you will loose in performance.

    what do you mean with "...overwritten in reconnect() ?

    I don't overwrite configurations.

    And I deleted my 5s delay.

    handytech
    Community Moderator
    Community Moderator

    In the example file bsec_integration.c , the function bme680_bsec_trigger_measurement() already handles the configuration of the different sensor settings, then triggers a measurement. Therefore it wasn't clear whether this extra piece of code could interfere with BSEC's operation.

    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