Bosch Sensortec Community

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

    BME 680 IAQ not computed

    BME 680 IAQ not computed

    hugo
    Member

    Hello,

    I'm porting BSEQ to nrf52, cortex M4F. The library has fine SPI configuration. I import config from generic_33v_3s_28d, I init setup at BSEC_SAMPLE_RATE_LP.
    All the init is fine. Every function works fine and returns BSEC_OK. All measurement are fine at 3seconds+-2ms.
    I'm based on bseq_integration demo. I get good temperature/humidity/pressure...but not IAQ/SIAQ/CO2_eq...etc...
    Values are  read fine, including gas resistance.
    But IAQ stays at 25 even after an hour of test.
    I can't debug check what's happening in bme680_bsec_process_data, but it returns BSEC_OK too.

    I'm quite lost, what should I check to go further?

    8 REPLIES 8

    Vincent
    Community Moderator
    Community Moderator

    Please provide your source code here first for double check again. 

    Also may need you to give us the data log (input to the lib) for at least 20  minutes then we can check the data quality at the same time.  

    Thank you. I hoped to learn how to fish, not getting just a fish. Anyway, you can get some log  before and after bme680_bsec_process_data. Time is uint64_t, but my printf is not able to display such number (as floats),as bosch has the great idea to count timestamp in ns (yummy for 32bit processors)
    This is code for logs attached:

    printf("bsec_inputs total: %d\r\n",num_bsec_inputs);
    for(uint8_t i=0;i<5;i++)
    printf("bsec_inputs %d :%d %d %d %d\r\n",
    i,
    (int32_t)bsec_inputs[i].time_stamp,
    (int32_t)bsec_inputs[i].signal*100,
    (int32_t)bsec_inputs[i].signal_dimensions,
    (int32_t)bsec_inputs[i].sensor_id);
    printf("\r\n");
    /* Time to invoke BSEC to perform the actual processing */
    bme680_bsec_process_data(bsec_inputs, num_bsec_inputs, output_ready);

    I would have prefered to fill a struct instead of getting function prototype, anyway, it works well:

    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)
    {
    printf("%d %d %d %d %d %d %d %d %d %d %d %d %d \r\n",
    (int32_t) timestamp,
    (int32_t) iaq*100,
    (int32_t) iaq_accuracy,
    (int32_t)temperature,
    (int32_t)humidity,
    (int32_t)pressure,
    (int32_t)raw_temperature,
    (int32_t)raw_humidity,
    (int32_t)gas,
    (int32_t)bsec_status,
    (int32_t)static_iaq,
    (int32_t)co2_equivalent,
    (int32_t)breath_voc_equivalent);
    printf("\r\n");
    }

    I have attached logs  for few minutes.

    Here the init, with no error found:

    bsec_iot_init(BSEC_SAMPLE_RATE_LP, 0,user_spi_write,user_spi_read, user_delay_ms, state_load, config_load);

    calling

    return_values_init bsec_iot_init(float sample_rate, float temperature_offset, bme680_com_fptr_t bus_write,
    bme680_com_fptr_t bus_read, sleep_fct sleep, state_load_fct state_load, config_load_fct config_load)
    {
    return_values_init ret = {BME680_OK, BSEC_OK};
    bsec_library_return_t bsec_status = BSEC_OK;

    uint8_t bsec_state[BSEC_MAX_STATE_BLOB_SIZE] = {0};
    uint8_t bsec_config[BSEC_MAX_PROPERTY_BLOB_SIZE] = {0};
    uint8_t work_buffer[BSEC_MAX_WORKBUFFER_SIZE] = {0};
    int bsec_state_len, bsec_config_len;
    ...

    Init spi
    ...

    /* Initialize BSEC library */
    ret.bsec_status = bsec_init();
    if (ret.bsec_status != BSEC_OK)
    {
    NRF_LOG_ERROR("bsec_init: %d",ret.bme680_status);
    return ret;
    }
    else
    NRF_LOG_INFO("bsec_init !");

    /* Load library config, if available */
    bsec_config_len = config_load(bsec_config, sizeof(bsec_config));
    if (bsec_config_len != 0)
    {
    ret.bsec_status = bsec_set_configuration(bsec_config, bsec_config_len, work_buffer, sizeof(work_buffer));
    if (ret.bsec_status != BSEC_OK)
    {
    NRF_LOG_ERROR("bsec_set_configuration: %d",ret.bme680_status);
    return ret;
    }
    else
    NRF_LOG_INFO("bsec_set_configuration !");
    }

    /* Load previous library state, if available */

    bsec_state_len = state_load(0,bsec_state, sizeof(bsec_state));
    if (bsec_state_len != 0)
    {
    ret.bsec_status = bsec_set_state(bsec_state, bsec_state_len, work_buffer, sizeof(work_buffer));
    if (ret.bsec_status != BSEC_OK)
    {
    return ret;
    }
    else
    NRF_LOG_INFO("bsec_set_state !");
    }


    /* Set temperature offset */
    bme680_temperature_offset_g = temperature_offset;

    /* Call to the function which sets the library with subscription information */
    ret.bsec_status = bme680_bsec_update_subscription(sample_rate);
    if (ret.bsec_status != BSEC_OK)
    {
    NRF_LOG_ERROR("bme680_bsec_update_subscription: %d",ret.bme680_status);
    return ret;
    }
    else
    NRF_LOG_INFO("bme680_bsec_update_subscription !");

    NRF_LOG_INFO("bsec_init success");
    return ret;

    Calling this funciton:

    static bsec_library_return_t bme680_bsec_update_subscription(float sample_rate)
    {
    bsec_sensor_configuration_t requested_virtual_sensors[NUM_USED_OUTPUTS];
    uint8_t n_requested_virtual_sensors = NUM_USED_OUTPUTS;

    bsec_sensor_configuration_t required_sensor_settings[BSEC_MAX_PHYSICAL_SENSOR];
    uint8_t n_required_sensor_settings = BSEC_MAX_PHYSICAL_SENSOR;

    bsec_library_return_t status = BSEC_OK;

    /* note: Virtual sensors as desired to be added here */
    requested_virtual_sensors[0].sensor_id = BSEC_OUTPUT_IAQ;
    requested_virtual_sensors[0].sample_rate = sample_rate;
    requested_virtual_sensors[1].sensor_id = BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE;
    requested_virtual_sensors[1].sample_rate = sample_rate;
    requested_virtual_sensors[2].sensor_id = BSEC_OUTPUT_RAW_PRESSURE;
    requested_virtual_sensors[2].sample_rate = sample_rate;
    requested_virtual_sensors[3].sensor_id = BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY;
    requested_virtual_sensors[3].sample_rate = sample_rate;
    requested_virtual_sensors[4].sensor_id = BSEC_OUTPUT_RAW_GAS;
    requested_virtual_sensors[4].sample_rate = sample_rate;
    requested_virtual_sensors[5].sensor_id = BSEC_OUTPUT_RAW_TEMPERATURE;
    requested_virtual_sensors[5].sample_rate = sample_rate;
    requested_virtual_sensors[6].sensor_id = BSEC_OUTPUT_RAW_HUMIDITY;
    requested_virtual_sensors[6].sample_rate = sample_rate;
    requested_virtual_sensors[7].sensor_id = BSEC_OUTPUT_STATIC_IAQ;
    requested_virtual_sensors[7].sample_rate = sample_rate;

    /* Call bsec_update_subscription() to enable/disable the requested virtual sensors */
    status = bsec_update_subscription(requested_virtual_sensors, n_requested_virtual_sensors, required_sensor_settings,
    &n_required_sensor_settings);

    return status;
    }

    Minhwan
    Community Moderator
    Community Moderator

    Hello,

     

    I checked your data log, and then your data unit is something wrong. 

    I could get proper IAQ value after I devided 100 each to pressure, humidity and temperature except gas resistance. 

    Could you try to devide 100 to each value and run it? For example, temp value should be 24 ,not 2400. 

    Please let me know if you have any questions. 

    Thanks, 

    Input values + IAQ are displayed multiplied by 100 (cf code). As I can't print float, and to check float really don't move, I print them them as integer multiplied first by 100. But I did multiplied raw values by 100 after converting, that's solved in my new logs. You can also see that accuracy is always 0 (the value just after iaq=2500 )

    So there is no problem of temperature and of units. There is a problem of IAQ computation 🙂 Problem is somewhere else: either  computation is wrong, either library init is wrong. I also copied initialisation, on my previous post. As I can't check computation and where it fails, it's harder to check what's wrong with my init.

    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