- Floating point support added for the API

- Lower temperature cap removed in "calc_heater_res" API
 - Added typecast for overflow check in "calc_pressure" API
This commit is contained in:
Bosch Sensortec 2018-01-29 08:36:51 +01:00
parent 494b3bb26b
commit 28666dc55a
5 changed files with 276 additions and 15 deletions

View File

@ -7,9 +7,9 @@ The sensor driver package includes bme680.h, bme680.c and bme680_defs.h files
## Version ## Version
File | Version | Date File | Version | Date
--------------|---------|------------- --------------|---------|-------------
bme680.c | 3.5.5 | 20 Nov 2017 bme680.c | 3.5.6 | 19 Jan 2018
bme680.h | 3.5.5 | 20 Nov 2017 bme680.h | 3.5.6 | 19 Jan 2018
bme680_defs.h | 3.5.5 | 20 Nov 2017 bme680_defs.h | 3.5.6 | 19 Jan 2018
## Integration details ## Integration details
* Integrate bme680.h, bme680_defs.h and bme680.c file in to your project. * Integrate bme680.h, bme680_defs.h and bme680.c file in to your project.
@ -62,6 +62,16 @@ fill in the various parameters as shown below
rslt = bme680_init(&gas_sensor); rslt = bme680_init(&gas_sensor);
``` ```
Regarding compensation functions for temperature, pressure, humidity and gas we have two implementations.
- Integer version
- floating point version
By default, Integer version is used in the API
If the user needs the floating point version, the user has to un-comment BME680_FLOAT_POINT_COMPENSATION macro
in bme680_defs.h file or to add it in the compiler flags.
### Configuring the sensor ### Configuring the sensor
#### Example for configuring the sensor in forced mode #### Example for configuring the sensor in forced mode
``` c ``` c

236
bme680.c
View File

@ -40,8 +40,8 @@
* patent rights of the copyright holder. * patent rights of the copyright holder.
* *
* File bme680.c * File bme680.c
* @date 20 Nov 2017 * @date 19 Jan 2018
* @version 3.5.5 * @version 3.5.6
* *
*/ */
@ -107,6 +107,8 @@ static int8_t get_gas_config(struct bme680_dev *dev);
*/ */
static uint8_t calc_heater_dur(uint16_t dur); static uint8_t calc_heater_dur(uint16_t dur);
#ifndef BME680_FLOAT_POINT_COMPENSATION
/*! /*!
* @brief This internal API is used to calculate the temperature value. * @brief This internal API is used to calculate the temperature value.
* *
@ -151,13 +153,72 @@ static uint32_t calc_gas_resistance(uint16_t gas_res_adc, uint8_t gas_range, con
/*! /*!
* @brief This internal API is used to calculate the Heat Resistance value. * @brief This internal API is used to calculate the Heat Resistance value.
* *
* @param[in] dev :Structure instance of bme680_dev. * @param[in] dev : Structure instance of bme680_dev
* @param[in] temp :Contains the temporary value. * @param[in] temp : Contains the target temperature value.
* *
* @return uint8_t calculated heater resistance. * @return uint8_t calculated heater resistance.
*/ */
static uint8_t calc_heater_res(uint16_t temp, const struct bme680_dev *dev); static uint8_t calc_heater_res(uint16_t temp, const struct bme680_dev *dev);
#else
/*!
* @brief This internal API is used to calculate the
* temperature value value in float format
*
* @param[in] dev :Structure instance of bme680_dev.
* @param[in] temp_adc :Contains the temperature ADC value .
*
* @return Calculated temperature in float
*/
static float calc_temperature(uint32_t temp_adc, struct bme680_dev *dev);
/*!
* @brief This internal API is used to calculate the
* pressure value value in float format
*
* @param[in] dev :Structure instance of bme680_dev.
* @param[in] pres_adc :Contains the pressure ADC value .
*
* @return Calculated pressure in float.
*/
static float calc_pressure(uint32_t pres_adc, const struct bme680_dev *dev);
/*!
* @brief This internal API is used to calculate the
* humidity value value in float format
*
* @param[in] dev :Structure instance of bme680_dev.
* @param[in] hum_adc :Contains the humidity ADC value.
*
* @return Calculated humidity in float.
*/
static float calc_humidity(uint16_t hum_adc, const struct bme680_dev *dev);
/*!
* @brief This internal API is used to calculate the
* gas resistance value value in float format
*
* @param[in] dev :Structure instance of bme680_dev.
* @param[in] gas_res_adc :Contains the Gas Resistance ADC value.
* @param[in] gas_range :Contains the range of gas values.
*
* @return Calculated gas resistance in float.
*/
static float calc_gas_resistance(uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev);
/*!
* @brief This internal API is used to calculate the
* heater resistance value in float format
*
* @param[in] temp : Contains the target temperature value.
* @param[in] dev : Structure instance of bme680_dev.
*
* @return Calculated heater resistance in float.
*/
static float calc_heater_res(uint16_t temp, const struct bme680_dev *dev);
#endif
/*! /*!
* @brief This internal API is used to calculate the field data of sensor. * @brief This internal API is used to calculate the field data of sensor.
* *
@ -818,6 +879,8 @@ static int8_t get_gas_config(struct bme680_dev *dev)
return rslt; return rslt;
} }
#ifndef BME680_FLOAT_POINT_COMPENSATION
/*! /*!
* @brief This internal API is used to calculate the temperature value. * @brief This internal API is used to calculate the temperature value.
*/ */
@ -861,7 +924,7 @@ static uint32_t calc_pressure(uint32_t pres_adc, const struct bme680_dev *dev)
var1 = ((32768 + var1) * (int32_t)dev->calib.par_p1) >> 15; var1 = ((32768 + var1) * (int32_t)dev->calib.par_p1) >> 15;
pressure_comp = 1048576 - pres_adc; pressure_comp = 1048576 - pres_adc;
pressure_comp = (int32_t)((pressure_comp - (var2 >> 12)) * ((uint32_t)3125)); pressure_comp = (int32_t)((pressure_comp - (var2 >> 12)) * ((uint32_t)3125));
var4 = (1 << 31); var4 = (INT32_C(1) << 31);
if (pressure_comp >= var4) if (pressure_comp >= var4)
pressure_comp = ((pressure_comp / (uint32_t)var1) << 1); pressure_comp = ((pressure_comp / (uint32_t)var1) << 1);
else else
@ -949,9 +1012,7 @@ static uint8_t calc_heater_res(uint16_t temp, const struct bme680_dev *dev)
int32_t var5; int32_t var5;
int32_t heatr_res_x100; int32_t heatr_res_x100;
if (temp < 200) /* Cap temperature */ if (temp > 400) /* Cap temperature */
temp = 200;
else if (temp > 400)
temp = 400; temp = 400;
var1 = (((int32_t) dev->amb_temp * dev->calib.par_gh3) / 1000) * 256; var1 = (((int32_t) dev->amb_temp * dev->calib.par_gh3) / 1000) * 256;
@ -965,6 +1026,165 @@ static uint8_t calc_heater_res(uint16_t temp, const struct bme680_dev *dev)
return heatr_res; return heatr_res;
} }
#else
/*!
* @brief This internal API is used to calculate the
* temperature value in float format
*/
static float calc_temperature(uint32_t temp_adc, struct bme680_dev *dev)
{
float var1 = 0;
float var2 = 0;
float calc_temp = 0;
/* calculate var1 data */
var1 = ((((float)temp_adc / 16384.0f) - ((float)dev->calib.par_t1 / 1024.0f))
* ((float)dev->calib.par_t2));
/* calculate var2 data */
var2 = (((((float)temp_adc / 131072.0f) - ((float)dev->calib.par_t1 / 8192.0f)) *
(((float)temp_adc / 131072.0f) - ((float)dev->calib.par_t1 / 8192.0f))) *
((float)dev->calib.par_t3 * 16.0f));
/* t_fine value*/
dev->calib.t_fine = (var1 + var2);
/* compensated temperature data*/
calc_temp = ((dev->calib.t_fine) / 5120.0f);
return calc_temp;
}
/*!
* @brief This internal API is used to calculate the
* pressure value in float format
*/
static float calc_pressure(uint32_t pres_adc, const struct bme680_dev *dev)
{
float var1 = 0;
float var2 = 0;
float var3 = 0;
float calc_pres = 0;
var1 = (((float)dev->calib.t_fine / 2.0f) - 64000.0f);
var2 = var1 * var1 * (((float)dev->calib.par_p6) / (131072.0f));
var2 = var2 + (var1 * ((float)dev->calib.par_p5) * 2.0f);
var2 = (var2 / 4.0f) + (((float)dev->calib.par_p4) * 65536.0f);
var1 = (((((float)dev->calib.par_p3 * var1 * var1) / 16384.0f)
+ ((float)dev->calib.par_p2 * var1)) / 524288.0f);
var1 = ((1.0f + (var1 / 32768.0f)) * ((float)dev->calib.par_p1));
calc_pres = (1048576.0f - ((float)pres_adc));
/* Avoid exception caused by division by zero */
if ((int)var1 != 0) {
calc_pres = (((calc_pres - (var2 / 4096.0f)) * 6250.0f) / var1);
var1 = (((float)dev->calib.par_p9) * calc_pres * calc_pres) / 2147483648.0f;
var2 = calc_pres * (((float)dev->calib.par_p8) / 32768.0f);
var3 = ((calc_pres / 256.0f) * (calc_pres / 256.0f) * (calc_pres / 256.0f)
* (dev->calib.par_p10 / 131072.0f));
calc_pres = (calc_pres + (var1 + var2 + var3 + ((float)dev->calib.par_p7 * 128.0f)) / 16.0f);
} else {
calc_pres = 0;
}
return calc_pres;
}
/*!
* @brief This internal API is used to calculate the
* humidity value in float format
*/
static float calc_humidity(uint16_t hum_adc, const struct bme680_dev *dev)
{
float calc_hum = 0;
float var1 = 0;
float var2 = 0;
float var3 = 0;
float var4 = 0;
float temp_comp;
/* compensated temperature data*/
temp_comp = ((dev->calib.t_fine) / 5120.0f);
var1 = (float)((float)hum_adc) - (((float)dev->calib.par_h1 * 16.0f) + (((float)dev->calib.par_h3 / 2.0f)
* temp_comp));
var2 = var1 * ((float)(((float) dev->calib.par_h2 / 262144.0f) * (1.0f + (((float)dev->calib.par_h4 / 16384.0f)
* temp_comp) + (((float)dev->calib.par_h5 / 1048576.0f) * temp_comp * temp_comp))));
var3 = (float) dev->calib.par_h6 / 16384.0f;
var4 = (float) dev->calib.par_h7 / 2097152.0f;
calc_hum = var2 + ((var3 + (var4 * temp_comp)) * var2 * var2);
if (calc_hum > 100.0f)
calc_hum = 100.0f;
else if (calc_hum < 0.0f)
calc_hum = 0.0f;
return calc_hum;
}
/*!
* @brief This internal API is used to calculate the
* gas resistance value in float format
*/
static float calc_gas_resistance(uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev)
{
float calc_gas_res;
float var1 = 0;
float var2 = 0;
float var3 = 0;
const float lookup_k1_range[16] = {
0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8,
0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0};
const float lookup_k2_range[16] = {
0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8,
-0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
var1 = (1340.0f + (5.0f * dev->calib.range_sw_err));
var2 = (var1) * (1.0f + lookup_k1_range[gas_range]/100.0f);
var3 = 1.0f + (lookup_k2_range[gas_range]/100.0f);
calc_gas_res = 1.0f / (float)(var3 * (0.000000125f) * (float)(1 << gas_range) * (((((float)gas_res_adc)
- 512.0f)/var2) + 1.0f));
return calc_gas_res;
}
/*!
* @brief This internal API is used to calculate the
* heater resistance value in float format
*/
static float calc_heater_res(uint16_t temp, const struct bme680_dev *dev)
{
float var1 = 0;
float var2 = 0;
float var3 = 0;
float var4 = 0;
float var5 = 0;
float res_heat = 0;
if (temp > 400) /* Cap temperature */
temp = 400;
var1 = (((float)dev->calib.par_gh1 / (16.0f)) + 49.0f);
var2 = ((((float)dev->calib.par_gh2 / (32768.0f)) * (0.0005f)) + 0.00235f);
var3 = ((float)dev->calib.par_gh3 / (1024.0f));
var4 = (var1 * (1.0f + (var2 * (float)temp)));
var5 = (var4 + (var3 * (float)dev->amb_temp));
res_heat = (uint8_t)(3.4f * ((var5 * (4 / (4 + (float)dev->calib.res_heat_range)) *
(1/(1 + ((float) dev->calib.res_heat_val * 0.002f)))) - 25));
return res_heat;
}
#endif
/*! /*!
* @brief This internal API is used to calculate the Heat duration value. * @brief This internal API is used to calculate the Heat duration value.
*/ */

View File

@ -40,8 +40,8 @@
* patent rights of the copyright holder. * patent rights of the copyright holder.
* *
* @file bme680.h * @file bme680.h
* @date 20 Nov 2017 * @date 19 Jan 2018
* @version 3.5.5 * @version 3.5.6
* @brief * @brief
* *
*/ */

View File

@ -40,8 +40,8 @@
* patent rights of the copyright holder. * patent rights of the copyright holder.
* *
* @file bme680_defs.h * @file bme680_defs.h
* @date 20 Nov 2017 * @date 19 Jan 2018
* @version 3.5.5 * @version 3.5.6
* @brief * @brief
* *
*/ */
@ -100,6 +100,12 @@
#endif #endif
#endif #endif
/** BME680 configuration macros */
/** Enable or un-comment the macro to provide floating point data output */
#ifndef BME680_FLOAT_POINT_COMPENSATION
/* #define BME680_FLOAT_POINT_COMPENSATION */
#endif
/** BME680 General config */ /** BME680 General config */
#define BME680_POLL_PERIOD_MS UINT8_C(10) #define BME680_POLL_PERIOD_MS UINT8_C(10)
@ -367,6 +373,8 @@ struct bme680_field_data {
uint8_t gas_index; uint8_t gas_index;
/*! Measurement index to track order */ /*! Measurement index to track order */
uint8_t meas_index; uint8_t meas_index;
#ifndef BME680_FLOAT_POINT_COMPENSATION
/*! Temperature in degree celsius x100 */ /*! Temperature in degree celsius x100 */
int16_t temperature; int16_t temperature;
/*! Pressure in Pascal */ /*! Pressure in Pascal */
@ -375,6 +383,18 @@ struct bme680_field_data {
uint32_t humidity; uint32_t humidity;
/*! Gas resistance in Ohms */ /*! Gas resistance in Ohms */
uint32_t gas_resistance; uint32_t gas_resistance;
#else
/*! Temperature in degree celsius */
float temperature;
/*! Pressure in Pascal */
float pressure;
/*! Humidity in % relative humidity x1000 */
float humidity;
/*! Gas resistance in Ohms */
float gas_resistance;
#endif
}; };
/*! /*!
@ -427,8 +447,14 @@ struct bme680_calib_data {
int16_t par_p9; int16_t par_p9;
/*! Variable to store calibrated pressure data */ /*! Variable to store calibrated pressure data */
uint8_t par_p10; uint8_t par_p10;
#ifndef BME680_FLOAT_POINT_COMPENSATION
/*! Variable to store t_fine size */ /*! Variable to store t_fine size */
int32_t t_fine; int32_t t_fine;
#else
/*! Variable to store t_fine size */
float t_fine;
#endif
/*! Variable to store heater resistance range */ /*! Variable to store heater resistance range */
uint8_t res_heat_range; uint8_t res_heat_range;
/*! Variable to store heater resistance value */ /*! Variable to store heater resistance value */

View File

@ -1,6 +1,11 @@
# Change Log # Change Log
All notable changes to the BME680 Sensor API will be documented in this file. All notable changes to the BME680 Sensor API will be documented in this file.
## v3.5.6, 19 Jan 2018
### Added
- Floating point support added for the API
- Lower temperature cap removed in "calc_heater_res" APIs
## v3.5.5, 20 Nov 2017 ## v3.5.5, 20 Nov 2017
### Changed ### Changed
- Updated the buffer size in "get_calib_data" API - Updated the buffer size in "get_calib_data" API