Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    Interfacing BME680 to STM32F769IDiscovery

    Interfacing BME680 to STM32F769IDiscovery

    VinayakMH
    Member

    Dear BOSCH Community, 

    I am working on interfacing BME680 sensor to STM32F769-IDiscovery microcontroller board. 

    I got the following output. (May be garbage / raw values). Kindly help me in getting the correct values. And i have posted my stm code also. Kindly go thought that and help me in getting the right values.

    Thank you.

    GAS RESISTANCE :1965753.865000
    TEMPERATURE : -48
    PRESSURE : 134225243
    HUMIDITY: -338783365

    This is my code:

    #include <stdio.h>
    #include "main.h"
    #include "retarget.h"
    #include "bme680.h"
    #include "bme680_defs.h"
    #include "math.h"

    struct bme680_dev gas_sensor;

    int8_t rslt = BME680_OK;

    I2C_HandleTypeDef hi2c1;

    UART_HandleTypeDef huart1;

    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_I2C1_Init(void);
    static void MX_USART1_UART_Init(void);

    int8_t user_i2c_read (uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len)
    {
    HAL_StatusTypeDef err;
    int result = 0;
    uint8_t reg[1]={reg_addr};
    err = HAL_I2C_Master_Transmit(&hi2c1, dev_id, reg, 1,HAL_MAX_DELAY);
    HAL_Delay(10);
    result = HAL_I2C_Master_Receive(&hi2c1, dev_id, data, len, HAL_MAX_DELAY);
    HAL_Delay(10);

    return result;

    }

    int8_t user_i2c_write (uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len)
    {
    int result=0;

    uint8_t reg[]={reg_addr,*data};
    result = HAL_I2C_Master_Transmit(&hi2c1, dev_id, reg, len, HAL_MAX_DELAY);
    HAL_Delay(10);

    return result;
    }

    void user_delay_ms (uint32_t period)
    {
    HAL_Delay(period);
    }
    int8_t bme680_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t lenr)
    {
    static uint8_t cmd[30];
    cmd[0] = reg_addr ;
    HAL_I2C_Master_Transmit(&hi2c1, dev_id, cmd, 1,HAL_MAX_DELAY);
    HAL_Delay(10);
    return HAL_I2C_Master_Receive(&hi2c1, dev_id, cmd, lenr, HAL_MAX_DELAY);

    }

    int8_t bme680_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t lenr)
    {
    static uint8_t cmd[2];
    cmd[0] = reg_addr ;
    cmd[1] = (uint8_t )*data ;


    return HAL_I2C_Master_Transmit(&hi2c1, dev_id, cmd, lenr,HAL_MAX_DELAY);
    }

    void init_bme (void)
    {
    uint8_t set_required_settings;
    int8_t rslt = BME680_OK;


    /* 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);
    }

    int main(void)
    {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_I2C1_Init();
    MX_USART1_UART_Init();
    RetargetInit(&huart1);

    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();
    printf("Chip_id : %x :%d\r\n",gas_sensor.chip_id,rslt);
    if(rslt!=0)
    {
    while(1);
    }
    uint8_t data1[1]= {140};
    uint8_t reg_addr[1]={0x2B};
    uint8_t rega[1]={0x72};
    uint8_t regs[1]={0x74};
    bme680_set_regs(reg_addr, data1 , 2, &gas_sensor);
    bme680_set_regs(rega, data1, 1, &gas_sensor);
    bme680_set_regs(regs, data1, 2, &gas_sensor);
    HAL_Delay(500);

    uint16_t meas_period;
    bme680_get_profile_dur(&meas_period, &gas_sensor);
    struct bme680_field_data data;

    while (1)
    {
    /* USER CODE END WHILE */
    user_delay_ms(meas_period); /* Delay till the measurement is ready */

    rslt = bme680_get_sensor_data(&data, &gas_sensor);

    HAL_Delay(100);
    printf( "TEMPERATURE : %d\r\n", data.temperature);
    HAL_Delay(500);
    printf( "PRESSURE : %ld\r\n", data.pressure);
    HAL_Delay(500);
    printf( "HUMIDITY: %ld \r\n", data.humidity);
    HAL_Delay(1500);
    printf( "GAS RESISTANCE :%f \r\n", (data.gas_resistance /1000.0));
    //nrf_delay_ms(500);


    if (data.status & BME680_GASM_VALID_MSK){

    printf( "GAS RESISTANCE :%ld \r\n", data.gas_resistance);

    HAL_Delay(1000);
    uint32_t comp_gas = log(data.gas_resistance) + 0.04 * (log(data.gas_resistance)/data.humidity) * data.humidity;

    printf( "GAS IAQ : %ld \r\n", comp_gas);
    }


    if (gas_sensor.power_mode == BME680_FORCED_MODE)
    {
    rslt = bme680_set_sensor_mode(&gas_sensor);
    }

    }
    }

    void SystemClock_Config(void)
    {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

    __HAL_RCC_PWR_CLK_ENABLE();
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
    Error_Handler();
    }
    /** Initializes the CPU, AHB and APB buses clocks
    */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
    |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
    {
    Error_Handler();
    }
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C1;
    PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
    PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
    Error_Handler();
    }
    }

    /**
    * @brief I2C1 Initialization Function
    * @param None
    * @retval None
    */
    static void MX_I2C1_Init(void)
    {

    /* USER CODE BEGIN I2C1_Init 0 */

    /* USER CODE END I2C1_Init 0 */

    /* USER CODE BEGIN I2C1_Init 1 */

    /* USER CODE END I2C1_Init 1 */
    hi2c1.Instance = I2C1;
    hi2c1.Init.Timing = 0x00303D5B;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    if (HAL_I2C_Init(&hi2c1) != HAL_OK)
    {
    Error_Handler();
    }
    /** Configure Analogue filter
    */
    if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
    {
    Error_Handler();
    }
    /** Configure Digital filter
    */
    if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
    {
    Error_Handler();
    }

    }

    static void MX_USART1_UART_Init(void)
    {

    /* USER CODE BEGIN USART1_Init 0 */

    /* USER CODE END USART1_Init 0 */

    /* USER CODE BEGIN USART1_Init 1 */

    /* USER CODE END USART1_Init 1 */
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
    Error_Handler();
    }
    }

    /**
    * @brief GPIO Initialization Function
    * @param None
    * @retval None
    */
    static void MX_GPIO_Init(void)
    {

    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

    }

    /* USER CODE BEGIN 4 */

    /* USER CODE END 4 */

    /**
    * @brief This function is executed in case of error occurrence.
    * @retval None
    */
    void Error_Handler(void)
    {
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */
    __disable_irq();
    while (1)
    {
    }
    /* USER CODE END Error_Handler_Debug */
    }

    #ifdef USE_FULL_ASSERT
    /**
    * @brief Reports the name of the source file and the source line number
    * where the assert_param error has occurred.
    * @param file: pointer to the source file name
    * @param line: assert_param error line source number
    * @retval None
    */
    void assert_failed(uint8_t *file, uint32_t line)
    {
    /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */

    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

     

     

    1 REPLY 1

    BSTRobin
    Community Moderator
    Community Moderator

    Hello ,

    In "https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/How-to-interface-STM32F769I-DISCO-to-BME...", we have provided reference code on STM32. Could you compare reference code with your code first?

    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