07-08-2021 01:06 PM
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****/
07-09-2021 03:07 AM
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?