Bosch Sensortronic's BME680 is a brand new integrated environmental sensor. It integrates temperature, pressure, humidity and gas sensors with high accuracy within a single unit.
398 lines
14 KiB
C
398 lines
14 KiB
C
/*
|
|
* Driver for Bosch Sensortec BME680 digital temperature, humity, pressure and
|
|
* gas sensor connected to I2C or SPI
|
|
*
|
|
* Part of esp-open-rtos [https://github.com/SuperHouse/esp-open-rtos]
|
|
*
|
|
* PLEASE NOTE:
|
|
* Due to the complexity of the sensor output value compputation based on many
|
|
* calibration parameters, the original Bosch Sensortec BME680 driver that is
|
|
* released as open source [https://github.com/BoschSensortec/BME680_driver]
|
|
* and integrated for internal use. Please note the license of this part, which
|
|
* is an extended BSD license and can be found in each of that source files.
|
|
*
|
|
* ---------------------------------------------------------------------------
|
|
*
|
|
* The BSD License (3-clause license)
|
|
*
|
|
* Copyright (c) 2017 Gunar Schorcht (https://github.com/gschorcht]
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its
|
|
* contributors may be used to endorse or promote products derived from this
|
|
* software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef BME680_DRV_H_
|
|
#define BME680_DRV_H_
|
|
|
|
#include "stdint.h"
|
|
#include "stdbool.h"
|
|
|
|
#include "FreeRTOS.h"
|
|
#include <task.h>
|
|
|
|
#include "i2c/i2c.h"
|
|
#include "esp/spi.h"
|
|
|
|
#include "bme680/bme680.h"
|
|
|
|
// Uncomment to enable debug output
|
|
// #define BME680_DEBUG
|
|
|
|
// Change this if you need more than 3 BME680 sensors
|
|
#define BME680_MAX_SENSORS 3
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
/**
|
|
* @brief Type for actual and average sensor values (called TPHG values)
|
|
*/
|
|
typedef struct {
|
|
float temperature; // temperature in degree Celcius
|
|
float pressure; // barometric pressure in hPascal
|
|
float humidity; // humidity in percent
|
|
float gas; // gas resistance in Ohm
|
|
} bme680_value_set_t;
|
|
|
|
/**
|
|
* @brief callback unction type to pass result of measurement to user tasks
|
|
*/
|
|
typedef void (*bme680_cb_function_t)(uint32_t sensor,
|
|
bme680_value_set_t actual,
|
|
bme680_value_set_t average);
|
|
|
|
/**
|
|
* @brief BME680 sensor device data structure type
|
|
*/
|
|
typedef struct {
|
|
|
|
bool active;
|
|
|
|
uint8_t bus; // I2C = 0, SPI = 1
|
|
uint8_t addr; // I2C = slave address, SPI = 0
|
|
uint8_t spi_cs_pin; // GPIO used as SPI CS
|
|
|
|
uint32_t period;
|
|
|
|
bme680_value_set_t actual;
|
|
bme680_value_set_t average;
|
|
|
|
bool average_computation;
|
|
bool average_first_measurement;
|
|
float average_weight;
|
|
|
|
bme680_cb_function_t cb_function;
|
|
TaskHandle_t bg_task;
|
|
|
|
struct bme680_dev dev; // internal Bosch BME680 driver data structure
|
|
|
|
} bme680_sensor_t;
|
|
|
|
|
|
/**
|
|
* @brief BME680 oversampling rate values
|
|
*/
|
|
typedef enum {
|
|
none = 0, // measurement is skipped, output values are invalid
|
|
os_1x = 1, // default oversampling rates
|
|
os_2x = 2,
|
|
os_4x = 3,
|
|
os_8x = 4,
|
|
os_16x = 5
|
|
} bme680_oversampling_t;
|
|
|
|
|
|
/**
|
|
* @brief BME680 IIR filter sizes
|
|
*/
|
|
typedef enum {
|
|
iir_size_0 = 0, // filter is not used
|
|
iir_size_1 = 1,
|
|
iir_size_3 = 2,
|
|
iir_size_7 = 3,
|
|
iir_size_15 = 4,
|
|
iir_size_31 = 5,
|
|
iir_size_63 = 6,
|
|
iir_size_127 = 7
|
|
} bme680_filter_size_t;
|
|
|
|
/**
|
|
* @brief Initialize the BME680 driver
|
|
*
|
|
* This function initializes all internal data structures. It must be called
|
|
* exactly once at the beginning.
|
|
*
|
|
* @return true on success, false on error
|
|
*/
|
|
bool bme680_init_driver ();
|
|
|
|
|
|
/**
|
|
* @brief Create and initialize a BME680 sensor
|
|
*
|
|
* This function initializes the BME680 sensor and checks its availability.
|
|
*
|
|
* Furthermore, the starts a background task for measurements with
|
|
* the sensor. The background task carries out the measurements periodically
|
|
* using BME680's single shot data acquisition mode with a default period
|
|
* of 1000 ms. This period be changed using function *set_measurment_period*.
|
|
*
|
|
* During each measurement the background task
|
|
*
|
|
* 1. determines *actual sensor values*
|
|
* 2. computes optionally *average sensor values*
|
|
* 3. calls back optionally a registered function of user task.
|
|
*
|
|
* The average value computation uses an exponential moving average
|
|
* and can be activated (default) or deactivated with function
|
|
* *bme680_enable_average_computation*. If the average value computation is
|
|
* deactivated, *average sensor values* correspond to *actual sensor values*.
|
|
* The weight (smoothing factor) used in the average value computatoin is 0.2
|
|
* by default and can be changed with function *bme680_set_average_weight*.
|
|
*
|
|
* If a callback method has been registered with function
|
|
* *bme680_set_callback_function*, it is called after each measurement
|
|
* to pass measurement results to user tasks. Otherwise, user tasks have to
|
|
* use function *bme680_get_values* explicitly to get the results.
|
|
*
|
|
* The sensor can either be connected to an I2C or SPI bus. If *addr* is
|
|
* greater than 0, it defines a valid I2C slave address and the sensor is
|
|
* connected to an I2C bus using this address. If *addr* is 0, the sensor
|
|
* is connected to a SPI bus. In both cases, the *bus* parameter specifies
|
|
* the ID of the corresponding bus. In case of SPI, parameter *cs* defines
|
|
* the GPIO used as CS signal.
|
|
*
|
|
* @param bus I2C or SPI bus at which BME680 sensor is connected
|
|
* @param addr I2C addr of the BME680 sensor or 0 for SPI
|
|
* @param cs SPI CS GPIO, ignored for I2C
|
|
*
|
|
* @return ID of the sensor (0 or greater on success or -1 on error)
|
|
*/
|
|
uint32_t bme680_create_sensor (uint8_t bus, uint8_t addr, uint8_t cs_pin);
|
|
|
|
|
|
/**
|
|
* @brief Set the period of the background measurement task for the given
|
|
* sensor
|
|
*
|
|
* Please note: The minimum period is 20 ms since each measurement takes
|
|
* about 20 ms.
|
|
*
|
|
* @param sensor ID of the sensor
|
|
* @param period Measurement period in ms (default 1000 ms)
|
|
*
|
|
* @return true on success, false on error
|
|
*/
|
|
bool bme680_set_measurement_period (uint32_t sensor, uint32_t period);
|
|
|
|
|
|
/**
|
|
* @brief Set the callback function for the background measurement task for
|
|
* the given sensor
|
|
*
|
|
* If a callback method is registered, it is called after each measurement to
|
|
* pass measurement results to user tasks. Thus, callback function is executed
|
|
* at the same rate as the measurements.
|
|
*
|
|
* @param sensor ID of the sensor
|
|
* @param function user function called after each measurement
|
|
* (NULL to delete it for the sensor)
|
|
*
|
|
* @return true on success, false on error
|
|
*/
|
|
bool bme680_set_callback_function (uint32_t sensor,
|
|
bme680_cb_function_t user_function);
|
|
|
|
|
|
/**
|
|
* @brief Deletes the BME680 sensor given by its ID
|
|
*
|
|
* @param sensor ID of the sensor
|
|
*
|
|
* @return true on success, false on error
|
|
*/
|
|
bool bme680_delete_sensor (uint32_t sensor);
|
|
|
|
|
|
/**
|
|
* @brief Get the actual and average sensor values
|
|
*
|
|
* This function returns the actual and average sensor values of the last
|
|
* measurement. The parameters *actual* and *average* are pointers to data
|
|
* structures of the type *bme680_value_set_t*, which are filled with the
|
|
* of last measurement. Use NULL for the appropriate parameter if you are
|
|
* not interested in specific results.
|
|
*
|
|
* If average value computation is deactivated, average sensor values
|
|
* correspond to the actual sensor values.
|
|
*
|
|
* Please note: Calling this function is only necessary if no callback
|
|
* function has been registered for the sensor.
|
|
*
|
|
* @param sensor ID of the sensor
|
|
* @param actual Pointer to a data structure for actual sensor values
|
|
* @param average Pointer to a data structure for average sensor values
|
|
*
|
|
* @return true on success, false on error
|
|
*/
|
|
bool bme680_get_values (uint32_t sensor,
|
|
bme680_value_set_t *actual,
|
|
bme680_value_set_t *average);
|
|
|
|
|
|
/**
|
|
* @brief Enable (default) or disable the average value computation
|
|
*
|
|
* In case, the average value computation is disabled, average sensor values
|
|
* correspond to the actual sensor values.
|
|
*
|
|
* Please note: All average sensor values are reset if parameters for
|
|
* measurement are changed using either function *bme680_set_average_weight*,
|
|
* *bme680_set_oversampling_rates*, *bme680_set_heater_profile* or
|
|
* *bme680_set_filter_size*.
|
|
*
|
|
* @param sensor id of the sensor
|
|
* @param enabled true to enable or false to disable average computation
|
|
*
|
|
* @return true on success, false on error
|
|
*/
|
|
bool bme680_enable_average_computation (uint32_t sensor, bool enabled);
|
|
|
|
|
|
/**
|
|
* @brief Set the weight (smoothing factor) for average value computation
|
|
*
|
|
* At each measurement carried out by the background task, actual sensor
|
|
* values are determined. If average value computation is enabled (default),
|
|
* exponential moving average values are computed according to following
|
|
* equation
|
|
*
|
|
* Average[k] = W * Value + (1-W) * Average [k-1]
|
|
*
|
|
* where coefficient W represents the degree of weighting decrease, a constant
|
|
* smoothing factor between 0 and 1. A higher W discounts older observations
|
|
* faster. W is 0.2 by default.
|
|
*
|
|
* @param sensor id of the sensor
|
|
* @param weight coefficient W (default is 0.2)
|
|
*
|
|
* @return true on success, false on error
|
|
*/
|
|
bool bme680_set_average_weight (uint32_t sensor, float weight);
|
|
|
|
|
|
/**
|
|
* @brief Set the oversampling rates for measurements
|
|
*
|
|
* The BME680 sensor allows to define different oversampling rates for the
|
|
* measurements of temperature, pressure and humidity, separatly. Possible
|
|
* oversampling rates defined by enumaration type are none, 1x (default),
|
|
* 2x, 4x, 8x, and 16x. In case of *none*, the corressponing measurement is
|
|
* skipped and output values are invalid.
|
|
*
|
|
* Please note: To disable the measurement of either temperature, pressure
|
|
* or humidity, set the corresponding oversamling rate to *none*.
|
|
*
|
|
* @param sensor id of the sensor
|
|
* @param ost oversampling rate for temperature measurements
|
|
* @param osp oversampling rate for pressure measurements
|
|
* @param osh oversampling rate for humidity measurements
|
|
*
|
|
* @return true on success, false on error
|
|
*/
|
|
bool bme680_set_oversampling_rates (uint32_t sensor,
|
|
bme680_oversampling_t ost,
|
|
bme680_oversampling_t osp,
|
|
bme680_oversampling_t osh);
|
|
|
|
/**
|
|
* @brief Set the heater profile for gas measurements
|
|
*
|
|
* For gas measurement the sensor integrates a heater. The paremeters for
|
|
* this heater are defined by a heater profile. Such a heater profile
|
|
* consists of a temperature setting point (the target temperature) and the
|
|
* heating duration.
|
|
*
|
|
* Even though the sensor supports up to 10 different profiles, only one
|
|
* profile is used by this driver for simplicity. The temperature setting
|
|
* point and the heating duration of this profile can be defined by this
|
|
* function. Default values are 320 degree Celcius as target temperature and
|
|
* 150 ms heating duration. If heating duration is 0 ms, the gas measurement
|
|
* is skipped and output values are invalid.
|
|
*
|
|
* Please note: To disable the measurement of gas, set the heating duration
|
|
* to 0 ms.
|
|
*
|
|
* Please note: According to the datasheet, target temperatures of between
|
|
* 200 and 400 degrees Celsius are typical and about 20 to 30 ms are necessary
|
|
* for the heater to reach the desired target temperature.
|
|
*
|
|
* @param sensor id of the sensor
|
|
* @param temperature heating temperature in degree Celcius
|
|
* @param duration heating duration in milliseconds
|
|
*
|
|
* @return true on success, false on error
|
|
*/
|
|
bool bme680_set_heater_profile (uint32_t sensor,
|
|
uint16_t temperature,
|
|
uint16_t duration);
|
|
|
|
|
|
/**
|
|
* @brief Set the size of the IIR filter
|
|
*
|
|
* The sensor integrates an internal IIR filter (low pass filter) to
|
|
* reduce short-term changes in sensor output values caused by external
|
|
* disturbances. It effectively reduces the bandwidth of the sensor output
|
|
* values.
|
|
*
|
|
* The filter can optionally be used for pressure and temperature data that
|
|
* are subject to many short-term changes. Humidity and gas inside the sensor
|
|
* does not fluctuate rapidly and does not require such a low pass filtering.
|
|
*
|
|
* This function sets the size of the filter. The default filter size is
|
|
* 3 (iir_size_3).
|
|
*
|
|
* Please note: If the size of the filter is 0, the filter is not used.
|
|
*
|
|
* @param sensor id of the sensor
|
|
* @param size IIR filter size
|
|
*
|
|
* @return true on success, false on error
|
|
*/
|
|
bool bme680_set_filter_size(uint32_t sensor, bme680_filter_size_t size);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* End of CPP guard */
|
|
|
|
#endif /* BME680_DRV_H_ */
|
|
|