Bosch Sensortec Community

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

    Error reading BME680 with a NORDIC DK

    Error reading BME680 with a NORDIC DK

    arnaud
    Member

    Hello everyone, I have an error when I read BME680 the values never change and humidity is at 100 % but the read fonction return a zero which means everything ok. I don't know why it's not working I guess it's in my read and write functions but I don't find my mistake.

    Here is my code : thank you for your time and have a good day.

     

    NB : NRF_LOG is used for display like Serial.print in arduino. 

    err = nrf_drv_twi_rx(&m_twi, dev_id, tampon, len); : this function is like the Wire.request(tampon, len ) on arduino.

    nrf_drv_twi_tx(&m_twi, dev_id, reg, len+1, false); : this function is like the Wire.begintransmission(dev_id) then wire.write(reg);

    /**
     * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     * @defgroup tw_scanner main.c
     * @{
     * @ingroup nrf_twi_example
     * @brief TWI Sensor Example main file.
     *
     * This file contains the source code for a sample application using TWI.
     *
     */
    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"

    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    #include "bme680.h"
     
     

    struct bme680_dev gas_sensor;
    int8_t rslt = BME680_OK;
    /* TWI instance ID. */
    #if TWI0_ENABLED
    #define TWI_INSTANCE_ID     0
    #elif TWI1_ENABLED
    #define TWI_INSTANCE_ID     1
    #endif
    int compteur = 0;
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    int8_t user_i2c_read (uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len)
    {
      ret_code_t err;
      uint8_t tampon[30]={0};
      NRF_LOG_INFO("read");
      NRF_LOG_FLUSH();
      int size=0, result = 0, j=0;
      uint8_t reg[1]={reg_addr};
      nrf_drv_twi_tx(&m_twi, dev_id, reg, 1,false);
      err = nrf_drv_twi_rx(&m_twi, dev_id, tampon, len);
      NRF_LOG_INFO("read : len %d :",len);
      NRF_LOG_FLUSH();
      if(err==0)
       {size=1;
     for(int i = 0 ;i<30;i++)
      {
        if(tampon[i]!=0) size=i+1;
    //    NRF_LOG_INFO("tampon : %d",tampon[i]);
    //      NRF_LOG_FLUSH();
       }
       }
       else
       size=0;
    //       NRF_LOG_INFO("len %d",len);
    //    NRF_LOG_FLUSH();
    //    NRF_LOG_INFO("size %d",size);
    //    NRF_LOG_FLUSH();
    if(size >14  ) size=len;
    NRF_LOG_INFO("read : wire.available %d :",size);
      NRF_LOG_FLUSH();
      if(len<=size)
        { for (int i=0;i<len;i++)
        {
          data[i]=tampon[i];
          NRF_LOG_INFO("%d",data[i]);
          NRF_LOG_FLUSH();
        }
         }
       else
       {result=5;}
       
     
    return result;
     
    }
    /**
     * Write the content into the register targeted register for a specified device
     *
     * Parameter :
     *    dev_id : the I2C adress of the device
     *    reg_addr : the adresse of the targeted register
     *    *data : pointer to the data to write
     *    len : number in byte of the data
     *
     * Return:  Error code
     */
    int8_t user_i2c_write (uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len)
    {
    NRF_LOG_INFO("write");
      NRF_LOG_FLUSH();
        int result=0;
      uint8_t reg[]={reg_addr,*data};
      nrf_drv_twi_tx(&m_twi, dev_id, reg, len+1, false);
      return result;

    }
    /**
     * function to wait the time
     *
     * Parameter :
     *    period : time that will be waited in millisecond
     */
    void user_delay_ms (uint32_t period)
    {
      nrf_delay_ms(period);
    }
    /**
     * @brief TWI initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
        const nrf_drv_twi_config_t twi_config = {
           .scl                = ARDUINO_13_PIN ,
           .sda                = ARDUINO_12_PIN ,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
        APP_ERROR_CHECK(err_code);
        nrf_drv_twi_enable(&m_twi);
    }
     
    /**
     * @brief Function for initialising bme 680 in forced mode.
     */
    void init_bme (void)
    {
    uint8_t set_required_settings;
        /* Set the temperature, pressure and humidity settings */
        gas_sensor.tph_sett.os_hum = BME680_OS_2X;
        gas_sensor.tph_sett.os_pres = BME680_OS_4X;
        gas_sensor.tph_sett.os_temp = BME680_OS_8X;
        gas_sensor.tph_sett.filter = BME680_FILTER_SIZE_3;
        /* Set the remaining gas sensor settings and link the heating profile */
        gas_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
        /* Create a ramp heat waveform in 3 steps */
        gas_sensor.gas_sett.heatr_temp = 320; /* degree Celsius */
        gas_sensor.gas_sett.heatr_dur = 150; /* milliseconds */
        /* Select the power mode */
        /* Must be set before writing the sensor configuration */
        gas_sensor.power_mode = BME680_FORCED_MODE;
        /* Set the required sensor settings needed */
        set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL
            | BME680_GAS_SENSOR_SEL;
        /* Set the desired sensor configuration */
        rslt = bme680_set_sensor_settings(set_required_settings,&gas_sensor);
        /* Set the power mode */
        rslt = bme680_set_sensor_mode(&gas_sensor);
    }
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        ret_code_t err_code;
     
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        NRF_LOG_INFO("TWI scanner started.");
        NRF_LOG_FLUSH();
        twi_init();
        gas_sensor.dev_id = BME680_I2C_ADDR_SECONDARY;
        gas_sensor.intf = BME680_I2C_INTF;
        gas_sensor.read = user_i2c_read;
        gas_sensor.write = user_i2c_write;
        gas_sensor.delay_ms = user_delay_ms;
        gas_sensor.amb_temp = 25;
        rslt = bme680_init(&gas_sensor);
        init_bme();
        NRF_LOG_INFO("Rslt : %d",rslt);
        NRF_LOG_FLUSH();
        if(rslt!=0)
        {
        NRF_LOG_INFO("no BME680 detected");
        NRF_LOG_FLUSH();
        while(1);
        }
       
     
        while (true)
        {
            // put your main code here, to run repeatedly:
      uint16_t meas_period;
      bme680_get_profile_dur(&meas_period, &gas_sensor);
     
     
      struct bme680_field_data data;
       
        while(1){
      nrf_delay_ms(meas_period);
      rslt = bme680_get_sensor_data(&data, &gas_sensor);
      NRF_LOG_INFO("RSLT READ %d",rslt);
     NRF_LOG_FLUSH();
       NRF_LOG_INFO("%d",data.temperature);
     NRF_LOG_FLUSH();
     NRF_LOG_ERROR( "Température :  " NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(data.temperature /100.0));
     NRF_LOG_FLUSH();
     NRF_LOG_ERROR( "Pression :  " NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(data.pressure /100.0));
     NRF_LOG_FLUSH();
     NRF_LOG_ERROR( "Humidity :  " NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(data.humidity /1000.0));
     NRF_LOG_FLUSH();
      /* Avoid using measurements from an unstable heating setup */
     
      if (data.status & BME680_GASM_VALID_MSK)
      {
        NRF_LOG_INFO("G: ");
        NRF_LOG_INFO("%d",data.gas_resistance);
        NRF_LOG_INFO("Kohms");
        NRF_LOG_FLUSH();
      }
     
      /* Trigger the next measurement if you would like to read data out continuously */
      if (gas_sensor.power_mode == BME680_FORCED_MODE) {
        rslt = bme680_set_sensor_mode(&gas_sensor);
        }
     while(1);
        }
          
          
        }
    }
    /** @} */
    9 REPLIES 9

    Vincent
    Community Moderator
    Community Moderator

    I saw the following value in your log:

    <info> app: read : reg addr : 116
    <info> app: read : len 1 :
    <info> app: read : wire.available 1 :
    <info> app: 0

    <info> app: read : reg addr : 114
    <info> app: read : len 1 :
    <info> app: read : wire.available 1 :
    <info> app: 0

    If my understanding is correct,  it means the register 0x72 and 0x74 are both read as 0.  this means the temperature, pressure and humidity measurement are skipped.  it is not match the values in the code you written here. 

    I will suggest you check the interface write function (especially burst write) again.  you can try to write into register and read back to confirm it. 

    I thing the write function is working because I write with set_reg and then read with get_reg and the value was correct. I don't know why the value of the registers are 0. Here is the serial of a third MCU which read the data on the serial bus at the Sensor address : You cand find in attachement the serial of this MCU. There are small difference between Nordic and arduino ? could it be the error ? 

    Thank you. 

     

    Vincent
    Community Moderator
    Community Moderator

    If you already verified the register value after write to it and it is match the value you written.

    Then i will suggest you to check VDD / VDDIO line of sensor.   Only power on reset can reset the register value to 0 if there is no SW reset or another register write happen. 

    I do see a bit difference in your provided log,  but  i can't make quick judge if it is the root cause with those screen shots.

    I added these lines before enter in the loop :

    uint8_t dat[1]={140};
    uint8_t reg[1]={0x74};
    uint8_t rega[1]={0x72};
    bme680_set_regs(reg, dat, 1, &gas_sensor);
    bme680_set_regs(rega, dat, 1, &gas_sensor);
     

    And now the sensor works. 

     

    Vincent
    Community Moderator
    Community Moderator

    I'm glad to see the sensor is working. 

    But the register 0x72 and 0x74 should be written in function bme680_set_sensor_settings which is already in your init_bme function. 

    looks like the execution of this function have some issue.

    maybe you can look into the function to find the root cause.

    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