Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BME688 no new data found

    BME688 no new data found

    Rosso9
    Established Member

    HI,

    I'm using BME688 breakout board sensor with nRF52832 microcontroller. They communicate through I2C protocol.

    For the moment, I do not want ot use the BSEC library, I want to read the datas of Temperature, Pressure and Humidity and gas.

    I downloaded the API from github and I modified the common.c file to adapt to my microcontroller in this way

    #include <stdint.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #include "bme68x.h"
    #include "bme68x_defs.h"
    #include "common.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    
    
    /******************************************************************************/
    /*!                 Macro definitions                                         */
    /*! BME68X shuttle board ID */
    #define BME68X_SHUTTLE_ID  0x93
    #define SDA_PIN 18
    #define SCL_PIN 19
    /******************************************************************************/
    /*!                Static variable definition                                 */
    static uint8_t dev_addr;
    static const nrf_drv_twi_t i2c_instance = NRF_DRV_TWI_INSTANCE(0);
    
    
    /******************************************************************************/
    /*!                User interface functions                                   */
    
    /*!
     * I2C read function map to COINES platform
     */
    
    BME68X_INTF_RET_TYPE bme68x_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
    {
    
        uint8_t dev_addr = *(uint8_t*)intf_ptr; 
        ret_code_t ret_code;
        ret_code = nrf_drv_twi_tx(&i2c_instance, dev_addr, &reg_addr,1,false);
        if(ret_code != NRF_SUCCESS)
        {
            return ret_code;
        }
    
        ret_code = nrf_drv_twi_rx(&i2c_instance, dev_addr, reg_data, len);
        if (ret_code == NRF_SUCCESS) 
            return BME68X_OK;
        else 
            return 1;
    }
    
    
    /*!
     * I2C write function map to COINES platform
     */
    BME68X_INTF_RET_TYPE bme68x_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
    {
    
        uint8_t dev_addr = *(uint8_t*)intf_ptr;
        ret_code_t ret_code;
        uint8_t send_tmp[10] = {0};
        send_tmp[0] = reg_addr;
        memcpy(send_tmp+1, reg_data, len);
        ret_code_t err_code = nrf_drv_twi_tx(&i2c_instance, dev_addr, send_tmp, len, false);
        if (ret_code == NRF_SUCCESS) return BME68X_OK;
        else return 1;
    }
    
    
    /*!
     * Delay function map to COINES platform
     */
    void bme68x_delay_us(uint32_t period, void *intf_ptr)
    {
        nrf_delay_us(period);
    }
    
    
    int8_t bme68x_interface_init(struct bme68x_dev *bme, uint8_t intf)
    {
        int8_t rslt = BME68X_OK;
        uint8_t reg_addr; 
        const uint8_t *reg_data;
        uint32_t len;
        void *intf_ptr;
    
        if (bme != NULL)
        {
            /* Bus configuration : I2C */
            if (intf == BME68X_I2C_INTF)
            {
                dev_addr = BME68X_I2C_ADDR_LOW;
                bme->read = bme68x_i2c_read;
                bme->write = bme68x_i2c_write;
                bme->intf = BME68X_I2C_INTF;
                //coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE);
               /* const nrf_drv_twi_config_t i2c_instance_config = {  .scl = SCL_PIN,
                                                                    .sda = SDA_PIN,
                                                                    .frequency = NRF_TWI_FREQ_100K,
                                                                    .interrupt_priority = 0};
                rslt = nrf_drv_twi_init(&i2c_instance, &i2c_instance_config, NULL, NULL);
                //enable TWI instance
                nrf_drv_twi_enable(&i2c_instance);
        */
            }
            //coines_set_shuttleboard_vdd_vddio_config(3300, 3300);
            nrf_delay_ms(100);
            bme->delay_us = bme68x_delay_us;
            bme->intf_ptr = &dev_addr;
            bme->amb_temp = 25; /* The ambient temperature in deg C is used for defining the heater temperature */
        }
        else
        {
            rslt = BME68X_E_NULL_PTR;
        }
    
        return rslt;
    }
    
    
    void bme68x_check_rslt(const char api_name[], int8_t rslt)
    {
        switch (rslt)
        {
            case BME68X_OK:
                printf("API name [%s]: Tutto ok\n", api_name);
                /* Do nothing */
                break;
            case BME68X_E_NULL_PTR:
                printf("API name [%s]  Error [%d] : Null pointer\r\n", api_name, rslt);
                break;
            case BME68X_E_COM_FAIL:
                printf("API name [%s]  Error [%d] : Communication failure\r\n", api_name, rslt);
                break;
            case BME68X_E_INVALID_LENGTH:
                printf("API name [%s]  Error [%d] : Incorrect length parameter\r\n", api_name, rslt);
                break;
            case BME68X_E_DEV_NOT_FOUND:
                printf("API name [%s]  Error [%d] : Device not found\r\n", api_name, rslt);
                break;
            case BME68X_E_SELF_TEST:
                printf("API name [%s]  Error [%d] : Self test error\r\n", api_name, rslt);
                break;
            case BME68X_W_NO_NEW_DATA:
                printf("API name [%s]  Warning [%d] : No new data found\r\n", api_name, rslt);
                break;
            default:
                printf("API name [%s]  Error [%d] : Unknown error code\r\n", api_name, rslt);
                break;
        }
    }
    
    /*
    void bme68x_coines_deinit(void)
    {
        fflush(stdout);
    
        coines_set_shuttleboard_vdd_vddio_config(0, 0);
        coines_delay_msec(1000);
    
        // Coines interface reset
        coines_soft_reset();
        coines_delay_msec(1000);
        coines_close_comm_intf(COINES_COMM_INTF_USB);
    }
    */

     

    Then, I try the example of forced mode

    struct bme68x_dev bme;
        int8_t rslt;
        struct bme68x_conf conf;
        struct bme68x_heatr_conf heatr_conf;
        struct bme68x_data data;
        uint32_t del_period;
        uint32_t time_ms = 0;
        uint8_t n_fields;
        uint16_t sample_count = 1;
    
        /* Interface preference is updated as a parameter
         * For I2C : BME68X_I2C_INTF
         * For SPI : BME68X_SPI_INTF
         */
        rslt = bme68x_interface_init(&bme, BME68X_I2C_INTF);
        bme68x_check_rslt("bme68x_interface_init", rslt);
    
        rslt = bme68x_init(&bme);
        bme68x_check_rslt("bme68x_init", rslt);
    
        /* Check if rslt == BME68X_OK, report or handle if otherwise */
        conf.filter = BME68X_FILTER_OFF;
        conf.odr = BME68X_ODR_NONE;
        conf.os_hum = BME68X_OS_16X;
        conf.os_pres = BME68X_OS_1X;
        conf.os_temp = BME68X_OS_2X;
        rslt = bme68x_set_conf(&conf, &bme);
        bme68x_check_rslt("bme68x_set_conf", rslt);
    
        /* Check if rslt == BME68X_OK, report or handle if otherwise */
        heatr_conf.enable = BME68X_ENABLE;
        heatr_conf.heatr_temp = 300;
        heatr_conf.heatr_dur = 100;
        rslt = bme68x_set_heatr_conf(BME68X_FORCED_MODE, &heatr_conf, &bme);
        bme68x_check_rslt("bme68x_set_heatr_conf", rslt);
    
        printf("Sample, TimeStamp(ms), Temperature(deg C), Pressure(Pa), Humidity(%%), Gas resistance(ohm), Status\n");
    
        while (sample_count <= SAMPLE_COUNT)
        {
            rslt = bme68x_set_op_mode(BME68X_FORCED_MODE, &bme);
            bme68x_check_rslt("bme68x_set_op_mode", rslt);
    
            /* Calculate delay period in microseconds */
            del_period = bme68x_get_meas_dur(BME68X_FORCED_MODE, &conf, &bme) + (heatr_conf.heatr_dur * 1000);
            bme.delay_us(del_period, bme.intf_ptr);
    
            time_ms = count*50;
    
            /* Check if rslt == BME68X_OK, report or handle if otherwise */
            rslt = bme68x_get_data(BME68X_FORCED_MODE, &data, &n_fields, &bme);
            bme68x_check_rslt("bme68x_get_data", rslt);
    
            if (n_fields)
            {
    #ifdef BME68X_USE_FPU
                printf("%u, %lu, %.2f, %.2f, %.2f, %.2f, 0x%x\n",
                       sample_count,
                       (long unsigned int)time_ms,
                       data.temperature,
                       data.pressure,
                       data.humidity,
                       data.gas_resistance,
                       data.status);
    #else
                printf("%u, %lu, %d, %lu, %lu, %lu, 0x%x\n",
                       sample_count,
                       (long unsigned int)time_ms,
                       (data.temperature / 100),
                       (long unsigned int)data.pressure,
                       (long unsigned int)(data.humidity / 1000),
                       (long unsigned int)data.gas_resistance,
                       data.status);
    #endif
                sample_count++;
            }
        }

     

    It seems all rigth, I build and the code does not gave any error, but the output is this:

    API name [bme68x_interface_init]: Tutto ok
    API name [bme68x_init]: Tutto ok
    API name [bme68x_set_conf]: Tutto ok
    API name [bme68x_set_heatr_conf]: Tutto ok
    Sample, TimeStamp(ms), Temperature(deg C), Pressure(Pa), Humidity(%), Gas resistance(ohm), Status
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: Tutto ok
    API name [bme68x_get_data] Warning [2] : No new data found (and it continues with no new data)

    I try to wait a lot, but the result does not change. I do not understand where the problem is. What can I do to solve the problem?

    Is it possible that the sensor is damaged? In that case, how can I understand it?

    Thanks for the help

    11 REPLIES 11

    BSTRobin
    Community Moderator
    Community Moderator

    Hi Rosso9,

    Could you get chip ID?
    And did all code run successfully before you call bme68x_get_data()?

    This code is in example, please compare your code if it correct?
    I2C write:
    uint16_t DevAddress = dev_addr << 1;

    I2C read:
    GTXBuffer[0] = subaddress | 0x80;

    Rosso9
    Established Member

    Hi,

    Yes I can get chip ID and it is 0x61.

    Yes, before I call bme68x_get_data() everything is ok. The output, indeed, is:

    API name [bme68x_interface_init]: All ok
    API name [bme68x_init]: All ok
    API name [bme68x_set_conf]: All ok

    chip id 0x61

    API name [bme68x_set_heatr_conf]: All ok
    Sample, TimeStamp(ms), Temperature(deg C), Pressure(Pa), Humidity(%), Gas resistance(ohm), Status
    API name [bme68x_set_op_mode]: All ok
    API name [bme68x_get_data] Warning [2] : No new data found
    API name [bme68x_set_op_mode]: All ok
    API name [bme68x_get_data] Warning [2] : No new data found

    I2C write: uint16_t DevAddress = dev_addr << 1; I try to add this line to the code but the output does not change

    I2C read: GTXBuffer[0] = subaddress | 0x80; I also try to use it, but also in this case the output does not change. (I have not used this line before because in the example you sent me, this line is in the SPI function)

     

     

    BSTRobin
    Community Moderator
    Community Moderator

    Hi Rosso9,

    You can debug read_field_data() function with single step, see that the read data is incorrect. And capture the communication waveform with the logic analyzer to see whether the actual data is correct.

    Rosso9
    Established Member

    Hi, thanks again.

    At the moment, I do not have a logic analyzer. However, I try to understood which is the problem in the function. The problem is during function bme68x_get_data, when it goes to function read_field_data.

    In function read_field_data this happens:

    - it enters in the while at line 1211 and does bme68x_get_regs correctly. It obtains the following values in buff.
    buff[0]: 12
    buff[1]: 93
    buff[2]: 236
    buff[3]: 30
    buff[4]: 134
    buff[5]: 141
    buff[6]: 0
    buff[7]: 0
    buff[8]: 0
    buff[9]: 0
    buff[10]: 0
    buff[11]: 0
    buff[12]: 0
    buff[13]: 0
    buff[14]: 0
    buff[15]: 51
    buff[16]: 0

    - then it calculates data->status: data->status = buff[0] & BME68X_NEW_DATA_MSK; The result of this operation is zero, and so it does not enter in the following if at line 1243

    (I have no modified the bme68x.c file)

    BSTRobin
    Community Moderator
    Community Moderator

    Hi Rosso9,

    The data is not normal.

    It seemed that you didn't refer to the example code completely. When I run the reference code, I couldn't reproduce your problem.

    Suggest you refer to the example code completely, and test it again.

    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