- Changed macro FLOATING_POINT_REPRESENTATION to BME280_FLOAT_ENABLE

- Changed member id to dev_id in struct bme280_dev
- Changed member interface to intf in struct bme280_dev
- Changed variable length array in bme280_set_regs to fixed length array to allow a max of 10 registers to be written.
- Fixed bug with shifting in parse_sensor_data
- Changed macro MACHINE_64_BIT to BME280_64BIT_ENABLE
- Updated example in the README.md file and added function pointer templates
This commit is contained in:
Bosch Sensortec 2017-07-20 10:50:05 +02:00
parent 4dbd10a74b
commit 236dccdee1
5 changed files with 252 additions and 104 deletions

205
README.md
View File

@ -7,9 +7,9 @@ The sensor driver package includes bme280.c, bme280.h and bme280_defs.h files.
## Version
File | Version | Date
-----|---------|-----
bme280.c | 3.2.0 | 21 Mar 2017
bme280.h | 3.2.0 | 21 Mar 2017
bme280_defs.h | 3.2.0 | 21 Mar 2017
bme280.c | 3.3.0 | 13 Jul 2017
bme280.h | 3.3.0 | 13 Jul 2017
bme280_defs.h | 3.3.0 | 13 Jul 2017
## Integration details
* Integrate bme280.h, bme280_defs.h and bme280.c file in to the project.
@ -40,8 +40,8 @@ struct bme280_dev dev;
int8_t rslt = BME280_OK;
/* Sensor_0 interface over SPI with native chip select line */
dev.id = 0;
dev.interface = BME280_SPI_INTF;
dev.dev_id = 0;
dev.intf = BME280_SPI_INTF;
dev.read = user_spi_read;
dev.write = user_spi_write;
dev.delay_ms = user_delay_ms;
@ -53,8 +53,8 @@ rslt = bme280_init(&dev);
struct bme280_dev dev;
int8_t rslt = BME280_OK;
dev.id = BME280_I2C_ADDR_PRIM;
dev.interface = BME280_I2C_INTF;
dev.dev_id = BME280_I2C_ADDR_PRIM;
dev.intf = BME280_I2C_INTF;
dev.read = user_i2c_read;
dev.write = user_i2c_write;
dev.delay_ms = user_delay_ms;
@ -65,39 +65,42 @@ Regarding compensation functions for temperature,pressure and humidity we have t
1) Double precision floating point version
2) Integer version
By default, integer version is used in the API. If user needs double version, user has to
enable FLOATING_POINT_REPRESENTATION macro in bme280_defs.h file.
By default, integer version is used in the API. If the user needs the floating point version, the user has to uncomment BME280_FLOAT_ENABLE macro in bme280_defs.h file or add that to the compiler flags.
In integer compensation functions, we also have below two implementations for pressure.
1) For 32 bit machine.
2) For 64 bit machine.
By default, 64 bit variant is used in the API. If user wants 32 bit variant, user can disable the
macro MACHINE_64_BIT in bme280_defs.h file.
By default, 64 bit variant is used in the API. If the user wants 32 bit variant, the user can disable the
macro BME280_64BIT_ENABLE in bme280_defs.h file.
### Get sensor data
#### Get sensor data in forced mode
### Stream sensor data
#### Stream sensor data in forced mode
``` c
int8_t get_sensor_data_forced_mode(struct bme280_dev *dev)
int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)
{
int8_t rslt;
uint8_t settings_sel;
struct bme280_data comp_data;
/* Continuously get the sensor data */
while (1) {
dev->settings.osr_h = BME280_OVERSAMPLING_4X;
dev->settings.osr_p = BME280_OVERSAMPLING_4X;
dev->settings.osr_t = BME280_OVERSAMPLING_4X;
/* Recommended mode of operation: Indoor navigation */
dev->settings.osr_h = BME280_OVERSAMPLING_1X;
dev->settings.osr_p = BME280_OVERSAMPLING_16X;
dev->settings.osr_t = BME280_OVERSAMPLING_2X;
dev->settings.filter = BME280_FILTER_COEFF_16;
settings_sel = BME280_OSR_PRESS_SEL|BME280_OSR_TEMP_SEL|BME280_OSR_HUM_SEL;
settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;
rslt = bme280_set_sensor_settings(settings_sel, dev);
printf("Temperature, Pressure, Humidity\r\n");
/* Continuously stream sensor data */
while (1) {
rslt = bme280_set_sensor_mode(BME280_FORCED_MODE, dev);
/* Give some delay for the sensor to go into force mode */
dev->delay_ms(5);
rslt = bme280_get_sensor_data(BME280_PRESS | BME280_HUM | BME280_TEMP, &comp_data, dev);
/* Wait for the measurement to complete and print data @25Hz */
dev->delay_ms(40);
rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
print_sensor_data(&comp_data);
}
return rslt;
@ -105,34 +108,41 @@ int8_t get_sensor_data_forced_mode(struct bme280_dev *dev)
void print_sensor_data(struct bme280_data *comp_data)
{
#ifdef FLOATING_POINT_REPRESENTATION
printf("%0.2f\t\t%0.2f\t\t%0.2f\t\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);
#ifdef BME280_FLOAT_ENABLE
printf("%0.2f, %0.2f, %0.2f\r\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);
#else
printf("%ld\t\t%ld\t\t%ld\t\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);
printf("%ld, %ld, %ld\r\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);
#endif
}
```
##### Get sensor data in normal mode
##### Stream sensor data in normal mode
``` c
int8_t get_sensor_data_normal_mode(struct bme280_dev *dev)
int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev)
{
int8_t rslt;
uint8_t settings_sel;
struct bme280_data comp_data;
dev->settings.osr_h = BME280_OVERSAMPLING_4X;
dev->settings.osr_p = BME280_OVERSAMPLING_4X;
dev->settings.osr_t = BME280_OVERSAMPLING_4X;
/* Recommended mode of operation: Indoor navigation */
dev->settings.osr_h = BME280_OVERSAMPLING_1X;
dev->settings.osr_p = BME280_OVERSAMPLING_16X;
dev->settings.osr_t = BME280_OVERSAMPLING_2X;
dev->settings.filter = BME280_FILTER_COEFF_16;
dev->settings.standby_time = BME280_STANDBY_TIME_62_5_MS;
settings_sel = BME280_OSR_PRESS_SEL|BME280_OSR_TEMP_SEL|BME280_OSR_HUM_SEL;
settings_sel = BME280_OSR_PRESS_SEL;
settings_sel |= BME280_OSR_TEMP_SEL;
settings_sel |= BME280_OSR_HUM_SEL;
settings_sel |= BME280_STANDBY_SEL;
settings_sel |= BME280_FILTER_SEL;
rslt = bme280_set_sensor_settings(settings_sel, dev);
rslt = bme280_set_sensor_mode(BME280_NORMAL_MODE, dev);
/* Give some delay for the sensor to go into normal mode */
dev->delay_ms(5);
printf("Temperature, Pressure, Humidity\r\n");
while (1) {
rslt = bme280_get_sensor_data(BME280_PRESS | BME280_HUM | BME280_TEMP, &comp_data, dev);
/* Delay while the sensor completes a measurement */
dev->delay_ms(70);
rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
print_sensor_data(&comp_data);
}
@ -141,12 +151,129 @@ int8_t get_sensor_data_normal_mode(struct bme280_dev *dev)
void print_sensor_data(struct bme280_data *comp_data)
{
#ifdef FLOATING_POINT_REPRESENTATION
printf("%0.2f\t\t%0.2f\t\t%0.2f\t\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);
#ifdef BME280_FLOAT_ENABLE
printf("%0.2f, %0.2f, %0.2f\r\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);
#else
printf("%ld\t\t%ld\t\t%ld\t\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);
printf("%ld, %ld, %ld\r\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);
#endif
}
```
### Templates for function pointers
``` c
void user_delay_ms(uint32_t period)
{
/*
* Return control or wait,
* for a period amount of milliseconds
*/
}
int8_t user_spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
/*
* The parameter dev_id can be used as a variable to select which Chip Select pin has
* to be set low to activate the relevant device on the SPI bus
*/
/*
* Data on the bus should be like
* |----------------+---------------------+-------------|
* | MOSI | MISO | Chip Select |
* |----------------+---------------------|-------------|
* | (don't care) | (don't care) | HIGH |
* | (reg_addr) | (don't care) | LOW |
* | (don't care) | (reg_data[0]) | LOW |
* | (....) | (....) | LOW |
* | (don't care) | (reg_data[len - 1]) | LOW |
* | (don't care) | (don't care) | HIGH |
* |----------------+---------------------|-------------|
*/
return rslt;
}
int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
/*
* The parameter dev_id can be used as a variable to select which Chip Select pin has
* to be set low to activate the relevant device on the SPI bus
*/
/*
* Data on the bus should be like
* |---------------------+--------------+-------------|
* | MOSI | MISO | Chip Select |
* |---------------------+--------------|-------------|
* | (don't care) | (don't care) | HIGH |
* | (reg_addr) | (don't care) | LOW |
* | (reg_data[0]) | (don't care) | LOW |
* | (....) | (....) | LOW |
* | (reg_data[len - 1]) | (don't care) | LOW |
* | (don't care) | (don't care) | HIGH |
* |---------------------+--------------|-------------|
*/
return rslt;
}
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
/*
* The parameter dev_id can be used as a variable to store the I2C address of the device
*/
/*
* Data on the bus should be like
* |------------+---------------------|
* | I2C action | Data |
* |------------+---------------------|
* | Start | - |
* | Write | (reg_addr) |
* | Stop | - |
* | Start | - |
* | Read | (reg_data[0]) |
* | Read | (....) |
* | Read | (reg_data[len - 1]) |
* | Stop | - |
* |------------+---------------------|
*/
return rslt;
}
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
/*
* The parameter dev_id can be used as a variable to store the I2C address of the device
*/
/*
* Data on the bus should be like
* |------------+---------------------|
* | I2C action | Data |
* |------------+---------------------|
* | Start | - |
* | Write | (reg_addr) |
* | Write | (reg_data[0]) |
* | Write | (....) |
* | Write | (reg_data[len - 1]) |
* | Stop | - |
* |------------+---------------------|
*/
return rslt;
}
```
## Copyright (C) 2016 - 2017 Bosch Sensortec GmbH

View File

@ -40,8 +40,8 @@
* patent rights of the copyright holder.
*
* File bme280.c
* Date 21 Mar 2017
* Version 3.2.0
* Date 13 Jul 2017
* Version 3.3.0
*
*/
@ -158,7 +158,7 @@ static void parse_sensor_data(const uint8_t *reg_data, struct bme280_uncomp_data
static int8_t compensate_data(uint8_t sensor_comp, const struct bme280_uncomp_data *uncomp_data,
struct bme280_data *comp_data, struct bme280_calib_data *calib_data);
#ifdef FLOATING_POINT_REPRESENTATION
#ifdef BME280_FLOAT_ENABLE
/*!
* @brief This internal API is used to compensate the raw pressure data and
* return the compensated pressure data in double data type.
@ -426,10 +426,10 @@ int8_t bme280_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const
/* Proceed if null check is fine */
if (rslt == BME280_OK) {
/* If interface selected is SPI */
if (dev->interface != BME280_I2C_INTF)
if (dev->intf != BME280_I2C_INTF)
reg_addr = reg_addr | 0x80;
/* Read the data */
rslt = dev->read(dev->id, reg_addr, reg_data, len);
rslt = dev->read(dev->dev_id, reg_addr, reg_data, len);
/* Check for communication error */
if (rslt != BME280_OK)
rslt = BME280_E_COMM_FAIL;
@ -445,7 +445,10 @@ int8_t bme280_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const
int8_t bme280_set_regs(uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len, const struct bme280_dev *dev)
{
int8_t rslt;
uint8_t temp_buff[len * 2];
uint8_t temp_buff[20]; /* Typically not to write more than 10 registers */
if(len > 10)
len = 10;
uint16_t temp_len;
uint8_t reg_addr_cnt;
@ -456,7 +459,7 @@ int8_t bme280_set_regs(uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len,
if (len != 0) {
temp_buff[0] = reg_data[0];
/* If interface selected is SPI */
if (dev->interface != BME280_I2C_INTF) {
if (dev->intf != BME280_I2C_INTF) {
for (reg_addr_cnt = 0; reg_addr_cnt < len; reg_addr_cnt++)
reg_addr[reg_addr_cnt] = reg_addr[reg_addr_cnt] & 0x7F;
}
@ -469,7 +472,7 @@ int8_t bme280_set_regs(uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len,
} else {
temp_len = len;
}
rslt = dev->write(dev->id, reg_addr[0], temp_buff, temp_len);
rslt = dev->write(dev->dev_id, reg_addr[0], temp_buff, temp_len);
/* Check for communication error */
if (rslt != BME280_OK)
rslt = BME280_E_COMM_FAIL;
@ -848,15 +851,15 @@ static void parse_sensor_data(const uint8_t *reg_data, struct bme280_uncomp_data
uint32_t data_msb;
/* Store the parsed register values for pressure data */
data_xlsb = (uint32_t)reg_data[0] << 12;
data_msb = (uint32_t)reg_data[0] << 12;
data_lsb = (uint32_t)reg_data[1] << 4;
data_msb = (uint32_t)reg_data[2] << 4;
data_xlsb = (uint32_t)reg_data[2] >> 4;
uncomp_data->pressure = data_msb | data_lsb | data_xlsb;
/* Store the parsed register values for temperature data */
data_xlsb = (uint32_t)reg_data[3] << 12;
data_msb = (uint32_t)reg_data[3] << 12;
data_lsb = (uint32_t)reg_data[4] << 4;
data_msb = (uint32_t)reg_data[5] << 4;
data_xlsb = (uint32_t)reg_data[5] >> 4;
uncomp_data->temperature = data_msb | data_lsb | data_xlsb;
/* Store the parsed register values for temperature data */
@ -900,7 +903,7 @@ static int8_t compensate_data(uint8_t sensor_comp, const struct bme280_uncomp_da
return rslt;
}
#ifdef FLOATING_POINT_REPRESENTATION
#ifdef BME280_FLOAT_ENABLE
/*!
* @brief This internal API is used to compensate the raw temperature data and
* return the compensated temperature data in double data type.
@ -1031,7 +1034,7 @@ static int32_t compensate_temperature(const struct bme280_uncomp_data *uncomp_da
return temperature;
}
#ifdef MACHINE_64_BIT
#ifdef BME280_64BIT_ENABLE
/*!
* @brief This internal API is used to compensate the raw pressure data and
* return the compensated pressure data in integer data type with higher
@ -1052,14 +1055,14 @@ static uint32_t compensate_pressure(const struct bme280_uncomp_data *uncomp_data
var2 = var1 * var1 * (int64_t)calib_data->dig_P6;
var2 = var2 + ((var1 * (int64_t)calib_data->dig_P5) * 131072);
var2 = var2 + (((int64_t)calib_data->dig_P4) * 34359738368);
var1 = ((var1 * var1 * (int64_t)calib_data->dig_P3) / 256) + ((var1 * (int64_t)calib_data->dig_P2) * 4096);
var1 = ((var1 * var1 * (int64_t)calib_data->dig_P3) / 256) + ((var1 * ((int64_t)calib_data->dig_P2) * 4096));
var3 = ((int64_t)1) * 140737488355328;
var1 = (var3 + var1) * ((int64_t)calib_data->dig_P1) / 8589934592;
/* To avoid divide by zero exception */
if (var1 != 0) {
var4 = 1048576 - uncomp_data->pressure;
var4 = (((var4 * (2147483648UL)) - var2) * 3125) / var1;
var4 = (((var4 * 2147483648) - var2) * 3125) / var1;
var1 = (((int64_t)calib_data->dig_P9) * (var4 / 8192) * (var4 / 8192)) / 33554432;
var2 = (((int64_t)calib_data->dig_P8) * var4) / 524288;
var4 = ((var4 + var1 + var2) / 256) + (((int64_t)calib_data->dig_P7) * 16);

View File

@ -40,8 +40,8 @@
* patent rights of the copyright holder.
*
* @file bme280.h
* @date 21 Mar 2017
* @version 3.2.0
* @date 13 Jul 2017
* @version 3.3.0
* @brief
*
*/

View File

@ -40,8 +40,8 @@
* patent rights of the copyright holder.
*
* @file bme280_defs.h
* @date 21 Mar 2017
* @version 3.2.0
* @date 13 Jul 2017
* @version 3.3.0
* @brief
*
*/
@ -120,8 +120,15 @@
#endif
#endif
/* #define FLOATING_POINT_REPRESENTATION */
#define MACHINE_64_BIT
#ifndef BME280_FLOAT_ENABLE
//#define BME280_FLOAT_ENABLE
#endif
#ifndef BME280_FLOAT_ENABLE
# ifndef BME280_64BIT_ENABLE
# define BME280_64BIT_ENABLE
# endif
#endif
#ifndef TRUE
#define TRUE UINT8_C(1)
@ -295,7 +302,7 @@ struct bme280_calib_data {
* @brief bme280 sensor structure which comprises of temperature, pressure and
* humidity data
*/
#ifdef FLOATING_POINT_REPRESENTATION
#ifdef BME280_FLOAT_ENABLE
struct bme280_data {
/*! Compensated pressure */
double pressure;
@ -352,9 +359,9 @@ struct bme280_dev {
/*! Chip Id */
uint8_t chip_id;
/*! Device Id */
uint8_t id;
uint8_t dev_id;
/*! SPI/I2C interface */
enum bme280_intf interface;
enum bme280_intf intf;
/*! Read function pointer */
bme280_com_fptr_t read;
/*! Write function pointer */

View File

@ -1,11 +1,22 @@
# Change Log
All notable changes to BME280 Sensor API will be documented in this file.
## v3.3.0, 13 Jul 2017
### Changed
- Changed macro FLOATING_POINT_REPRESENTATION to BME280_FLOAT_ENABLE
- Changed member id to dev_id in struct bme280_dev
- Changed member interface to intf in struct bme280_dev
- Changed variable length array in bme280_set_regs to fixed length array to allow a max of 10 registers to be written.
- Fixed bug with shifting in parse_sensor_data
- Changed macro MACHINE_64_BIT to BME280_64BIT_ENABLE
- Updated example in the README.md file and added function pointer templates
## v3.2.0, 21 Mar 2017
### Changed
- API for putting sensor into sleep mode changed.
- Pressure, Temperature out of range data clipped.
- 64 bit pressure compensation changed.
## v3.1.0, 8 Mar 2017
### Added
- Device settings APIs.