Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BSEC2.4.0.0 Heat Profile duration

    BSEC2.4.0.0 Heat Profile duration

    Julien1
    New Poster

    Hi,

    I have collected data using the BME688 Development Kit with 8 BME688 sensors and then generated an algorithm for BSEC2.4.0.0 using IA Studio 2.0.0

    I used the default heat profile HP-354

    I can init BSEC Library and load algorithm file without problem but after calling bsec_sensor_control() to retrieve sensor settings, I can see that the duration of each step of heat profile are too short :

    duration: 5ms, temp: 320 C
    duration: 2ms, temp: 100 C
    duration: 10ms, temp: 100 C
    duration: 30ms, temp: 100 C
    duration: 5ms, temp: 200 C
    duration: 5ms, temp: 200 C
    duration: 5ms, temp: 200 C
    duration: 5ms, temp: 320 C
    duration: 5ms, temp: 320 C
    duration: 5ms, temp: 320 C
    duration total: 77ms

    For each Step the Temperature looks correct but the duration is too short, for a total duration of 77m instead of ~10,8s

    What am I doing wrong ?

     

     

     

     

     

     

    7 REPLIES 7

    BSTRobin
    Community Moderator
    Community Moderator

    Hi Julien1,

    Did you run official example code or the code written by yourself?

    Hi,

    I modified the bsec_iot_example code delivered with the BSEC2.4.0.0 release from 23.01.2022

    Below are my init and bsec calls functions:

    int bme68x_bsec2_lib_intf_init(struct bme68x_dev* bme68x_sensor, struct bme68x_device* bme68x_i2c_dev, store_bsec2_state _st, load_bsec2_state _ld)
    {
        st = _st;
        ld = _ld;

        return_values_init ret = {BME68X_OK, BSEC_OK};

        bme68x_sensor->intf_ptr = (void*)bme68x_i2c_dev;
        bme68x_sensor->chip_id = 0x76;
        bme68x_sensor->intf = BME68X_I2C_INTF;
        bme68x_sensor->amb_temp = 25;
        bme68x_sensor->read = bme68x_bsec2_lib_intf_read;
        bme68x_sensor->write = bme68x_bsec2_lib_intf_write;
        bme68x_sensor->delay_us = bme68x_bsec2_lib_intf_delay_usec;

        /* Initialize bme68x API */
        ret.bme68x_status = bme68x_init(bme68x_sensor);
        if (ret.bme68x_status != BME68X_OK)
        {
            return -1;
        }
       
        /* Initialize BSEC library */
        ret.bsec_status = bsec_init();
        if (ret.bsec_status != BSEC_OK)
        {
            return -1;
        }
       
        /* 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)
            {
                return -1;
            }
        }
        /* Load previous library state, if available */
        bsec_state_len = state_load(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 -1;
            }
        }
       
        /* Call to the function which sets the library with subscription information */
        #ifdef GAS_SCAN_MODE
        ret.bsec_status = bme68x_bsec_update_subscription(BSEC_SAMPLE_RATE_SCAN); // SCAN for Gas estimate
        #else
        ret.bsec_status = bme68x_bsec_update_subscription(BSEC_SAMPLE_RATE_LP); // Low Power (or ULP) for IAQ
        #endif
        if (ret.bsec_status != BSEC_OK)
        {
            return -1;
        }

        memset(&sensor_settings, 0, sizeof(sensor_settings));
        opMode = sensor_settings.op_mode;
        sensor_settings.next_call = 0;

        return 0;
    }
     
     
     
     
     
    void handle_bsec_calls(struct bme68x_dev* bme68x_sensor, struct bme68x_data* data, uint32_t save_intvl)
    {
        int8_t ret_val;
        bsec_library_return_t bsec_status = BSEC_OK;

        /* get the timestamp in nanoseconds before calling bsec_sensor_control() */
        time_stamp = get_timestamp_us() * 1000;

        printk("time_stamp: %lld, next_call: %lld, diff: %lld\n",
        time_stamp/1000000, sensor_settings.next_call/1000000, (time_stamp - sensor_settings.next_call) / 1000000 );

        if(time_stamp > sensor_settings.next_call)
        {  
            /* Retrieve sensor settings to be used in this time instant by calling bsec_sensor_control */
            bsec_status = bsec_sensor_control(time_stamp, &sensor_settings);
            if (bsec_status != BSEC_OK)
            {
                if (bsec_status < BSEC_OK)
                {
                    printf("ERROR: bsec_sensor_control: %d\n", bsec_status);            
                }
                else
                {
                    printf("WARNING: bsec_sensor_control: %d\n", bsec_status);
                }
            }
            else
            {
                int dur_tot = 0;
                for (int i = 0; i < sensor_settings.heater_profile_len; i++)
                {
                    printk("duration: %dms, temp: %d C\n", sensor_settings.heater_duration_profile[i], sensor_settings.heater_temperature_profile[i]);
                    dur_tot += sensor_settings.heater_duration_profile[i];
                }
                printk("duration total: %dms\n", dur_tot);
            }

            switch (sensor_settings.op_mode)
            {
            case BME68X_FORCED_MODE:
                setBme68xConfigForced(&sensor_settings, bme68x_sensor);
                break;
            case BME68X_PARALLEL_MODE:
                if (opMode != sensor_settings.op_mode)
                {
                    setBme68xConfigParallel(&sensor_settings, bme68x_sensor);
                }
                break;
            case BME68X_SLEEP_MODE:
                if (opMode != sensor_settings.op_mode)
                {
                    ret_val = bme68x_set_op_mode(BME68X_SLEEP_MODE, bme68x_sensor);
                    if ((ret_val == BME68X_OK) && (opMode != BME68X_SLEEP_MODE))
                    {
                        opMode = BME68X_SLEEP_MODE;
                    }
                }
                break;
            }
                   
            if (sensor_settings.trigger_measurement && sensor_settings.op_mode != BME68X_SLEEP_MODE)
            {
                nFields = 0;
                bme68x_get_data(lastOpMode, &sensor_data[0], &nFields, bme68x_sensor);
                iFields = 0;
                if(nFields)
                {
                    do
                    {
                        nFieldsLeft = getData(data);
                        /* check for valid gas data */
                        if (data->status & BME68X_GASM_VALID_MSK)
                        {
                            if (!processData(time_stamp, data, sensor_settings.process_data))
                            {
                                return;
                            }
                        }
                    }while(nFieldsLeft);
                }
            }
                   
            /* Increment sample counter */
            n_samples++;
               
            /* Retrieve and store state if the passed save_intvl */
            if (n_samples >= save_intvl)
            {
                bsec_status = bsec_get_state(0, bsec_state, sizeof(bsec_state), work_buffer, sizeof(work_buffer), &bsec_state_len);
                if (bsec_status == BSEC_OK)
                {
                    state_save(bsec_state, bsec_state_len);
                }
                n_samples = 0;
            }  
        }
    }
     
     
     
     
     
     

    Update: 

    handle_bsec_calls() is called every ~3 seconds

    I get a gas estimate output wit accuracy = 3 every ~150 seconds, is it a normal behavior ?

     

     

     

     

     

     

    Hi,

    Could you give me feedback on this ?

    How can I verify that the heat profile duration is correct ?

    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