This package contains the Bosch Sensortec's BME280 pressure sensor driver (sensor API)
The sensor driver package includes bme280.c, bme280.h and bme280_defs.h files.
- Integrate bme280.h, bme280_defs.h and bme280.c file in to the project.
- Include the bme280.h file in your code like below.
#include "bme280.h"
- bme280_defs.h : This header file has the constants, macros and datatype declarations.
- bme280.h : This header file contains the declarations of the sensor driver APIs.
- bme280.c : This source file contains the definitions of the sensor driver APIs.
- SPI 4-wire
- I2C
SPI 3-wire is currently not supported in the API.
To initialize the sensor, user needs to create a device structure. User can do this by creating an instance of the structure bme280_dev. After creating the device structure, user needs to fill in the various parameters as shown below.
struct bme280_dev dev;
int8_t rslt = BME280_OK;
/* Sensor_0 interface over SPI with native chip select line */
uint8_t dev_addr = 0;
dev.intf_ptr = &dev_addr;
dev.intf = BME280_SPI_INTF;
dev.read = user_spi_read;
dev.write = user_spi_write;
dev.delay_us = user_delay_us;
rslt = bme280_init(&dev);
struct bme280_dev dev;
int8_t rslt = BME280_OK;
uint8_t dev_addr = BME280_I2C_ADDR_PRIM;
dev.intf_ptr = &dev_addr;
dev.intf = BME280_I2C_INTF;
dev.read = user_i2c_read;
dev.write = user_i2c_write;
dev.delay_us = user_delay_us;
rslt = bme280_init(&dev);
Regarding compensation functions for temperature, pressure and humidity we have two implementations.
- Double precision floating point version
- Integer versions
By default, BME280_FLOAT_ENABLE i.e. double precision floating point version is used in the API. If the user needs an integer version, the user has to define BME280_64BIT_ENABLE or BME280_32BIT_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.
- For 32 bit machine.
- For 64 bit machine.
When using integer versions the 64 bit variant is recommended to use in the API. If the user wants 32 bit variant, the user can define the macro BME280_32BIT_ENABLE in bme280_defs.h file.
The sensor data units depends on the following macros being enabled or not, (in bme280_defs.h file or as compiler macros)
- BME280_FLOAT_ENABLE
- BME280_64BIT_ENABLE
In case of the macro "BME280_FLOAT_ENABLE" enabled (default), The outputs are in double and the units are
- °C for temperature
- % relative humidity
- Pascal for pressure
In case if "BME280_FLOAT_ENABLE" is not enabled, then it is
- int32_t for temperature with the units 100 * °C
- uint32_t for humidity with the units 1024 * % relative humidity
- uint32_t for pressure
If macro "BME280_64BIT_ENABLE" is enabled, the unit is 100 * Pascal
If macro "BME280_32BIT_ENABLE" is enabled, then the unit is in Pascal
int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)
{
int8_t rslt;
uint8_t settings_sel;
uint32_t req_delay;
struct bme280_data comp_data;
/* 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 | BME280_FILTER_SEL;
rslt = bme280_set_sensor_settings(settings_sel, dev);
/* Calculate the minimum delay in microseconds required between consecutive measurements
* based upon the sensor enabled and oversampling configuration. */
req_delay = bme280_cal_meas_delay(&dev->settings);
printf("Temperature, Pressure, Humidity\r\n");
/* Continuously stream sensor data */
while (1) {
rslt = bme280_set_sensor_mode(BME280_FORCED_MODE, dev);
/* Wait for the measurement to complete and print data @25Hz */
dev->delay_us(req_delay, dev->intf_ptr);
rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
print_sensor_data(&comp_data);
}
return rslt;
}
void print_sensor_data(struct bme280_data *comp_data)
{
#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, %ld, %ld\r\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);
#endif
}
int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev)
{
int8_t rslt;
uint8_t settings_sel;
struct bme280_data comp_data;
/* 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;
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);
printf("Temperature, Pressure, Humidity\r\n");
while (1) {
/* Delay while the sensor completes a measurement */
dev->delay_us(70000, dev->intf_ptr);
rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
print_sensor_data(&comp_data);
}
return rslt;
}
void print_sensor_data(struct bme280_data *comp_data)
{
#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, %ld, %ld\r\n",comp_data->temperature, comp_data->pressure, comp_data->humidity);
#endif
}
void user_delay_us(uint32_t period, void *intf_ptr)
{
/*
* Return control or wait,
* for a period amount of microseconds
*/
}
int8_t user_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
/*
* The parameter intf_ptr 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 reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
/*
* The parameter intf_ptr 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 reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
/*
* The parameter intf_ptr 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 reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
/*
* The parameter intf_ptr 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;
}