282 lines
8.6 KiB
Markdown
282 lines
8.6 KiB
Markdown
|
# BME680 sensor API
|
||
|
|
||
|
## Introduction
|
||
|
|
||
|
This package contains the Bosch Sensortec's BME680 gas sensor API
|
||
|
|
||
|
The sensor driver package includes bme680.h, bme680.c and bme680_defs.h files
|
||
|
|
||
|
## Version
|
||
|
|
||
|
File | Version | Date
|
||
|
--------------|---------|-------------
|
||
|
bme680.c | 3.5.9 | 19 Jun 2018
|
||
|
bme680.h | 3.5.9 | 19 Jun 2018
|
||
|
bme680_defs.h | 3.5.9 | 19 Jun 2018
|
||
|
|
||
|
## Integration details
|
||
|
|
||
|
* Integrate bme680.h, bme680_defs.h and bme680.c file in to your project.
|
||
|
* Include the bme680.h file in your code like below.
|
||
|
|
||
|
``` c
|
||
|
#include "bme680.h"
|
||
|
```
|
||
|
|
||
|
## File information
|
||
|
|
||
|
* bme680_defs.h : This header file has the constants, macros and datatype declarations.
|
||
|
* bme680.h : This header file contains the declarations of the sensor driver APIs.
|
||
|
* bme680.c : This source file contains the definitions of the sensor driver APIs.
|
||
|
|
||
|
## Supported sensor interfaces
|
||
|
|
||
|
* SPI 4-wire
|
||
|
* I2C
|
||
|
|
||
|
## Usage guide
|
||
|
|
||
|
### Initializing the sensor
|
||
|
|
||
|
To initialize the sensor, you will first need to create a device structure. You
|
||
|
can do this by creating an instance of the structure bme680_dev. Then go on to
|
||
|
fill in the various parameters as shown below
|
||
|
|
||
|
#### Example for SPI 4-Wire
|
||
|
|
||
|
``` c
|
||
|
struct bme680_dev gas_sensor;
|
||
|
|
||
|
/* You may assign a chip select identifier to be handled later */
|
||
|
gas_sensor.dev_id = 0;
|
||
|
gas_sensor.intf = BME680_SPI_INTF;
|
||
|
gas_sensor.read = user_spi_read;
|
||
|
gas_sensor.write = user_spi_write;
|
||
|
gas_sensor.delay_ms = user_delay_ms;
|
||
|
/* amb_temp can be set to 25 prior to configuring the gas sensor
|
||
|
* or by performing a few temperature readings without operating the gas sensor.
|
||
|
*/
|
||
|
gas_sensor.amb_temp = 25;
|
||
|
|
||
|
int8_t rslt = BME680_OK;
|
||
|
rslt = bme680_init(&gas_sensor);
|
||
|
```
|
||
|
|
||
|
#### Example for I2C
|
||
|
|
||
|
``` c
|
||
|
struct bme680_dev gas_sensor;
|
||
|
|
||
|
gas_sensor.dev_id = BME680_I2C_ADDR_PRIMARY;
|
||
|
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;
|
||
|
/* amb_temp can be set to 25 prior to configuring the gas sensor
|
||
|
* or by performing a few temperature readings without operating the gas sensor.
|
||
|
*/
|
||
|
gas_sensor.amb_temp = 25;
|
||
|
|
||
|
|
||
|
int8_t rslt = BME680_OK;
|
||
|
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
|
||
|
|
||
|
#### Example for configuring the sensor in forced mode
|
||
|
|
||
|
``` c
|
||
|
uint8_t set_required_settings;
|
||
|
|
||
|
/* 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);
|
||
|
|
||
|
|
||
|
```
|
||
|
|
||
|
### Reading sensor data
|
||
|
|
||
|
#### Example for reading all sensor data
|
||
|
|
||
|
``` c
|
||
|
/* Get the total measurement duration so as to sleep or wait till the
|
||
|
* measurement is complete */
|
||
|
uint16_t meas_period;
|
||
|
bme680_get_profile_dur(&meas_period, &gas_sensor);
|
||
|
|
||
|
struct bme680_field_data data;
|
||
|
|
||
|
while(1)
|
||
|
{
|
||
|
user_delay_ms(meas_period); /* Delay till the measurement is ready */
|
||
|
|
||
|
rslt = bme680_get_sensor_data(&data, &gas_sensor);
|
||
|
|
||
|
printf("T: %.2f degC, P: %.2f hPa, H %.2f %%rH ", data.temperature / 100.0f,
|
||
|
data.pressure / 100.0f, data.humidity / 1000.0f );
|
||
|
/* Avoid using measurements from an unstable heating setup */
|
||
|
if(data.status & BME680_GASM_VALID_MSK)
|
||
|
printf(", G: %d ohms", data.gas_resistance);
|
||
|
|
||
|
printf("\r\n");
|
||
|
|
||
|
/* Trigger the next measurement if you would like to read data out continuously */
|
||
|
if (gas_sensor.power_mode == BME680_FORCED_MODE) {
|
||
|
rslt = bme680_set_sensor_mode(&gas_sensor);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### 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) 2017 - 2018 Bosch Sensortec GmbH
|