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 need to create a device structure. User can do this by creating an instance of the structure bme280_dev. After creating the device strcuture, user need 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 version
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.
- For 32 bit machine.
- For 64 bit machine.
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.
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, 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, which it is by default, the unit is 100 * Pascal
If this macro is disabled, 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 required between consecutive measurement based upon the sensor enabled
* and the 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(70, 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;
}