Driver for Bosch Sensortec BME680 added (#469)
* Driver for Bosch Sensortec BME680 added
This commit is contained in:
parent
e0410b2c5d
commit
691cf4ed62
12 changed files with 3081 additions and 0 deletions
46
examples/bme680/README.md
Normal file
46
examples/bme680/README.md
Normal file
|
@ -0,0 +1,46 @@
|
|||
# BME680 Driver Examples
|
||||
|
||||
These examples demonstrate the usage of the BME680 driver with only one and multiple BME680 sensors.
|
||||
|
||||
## Hardware setup
|
||||
|
||||
There are examples that are using either I2C or SPI with one or two sensors.
|
||||
|
||||
For examples using BME680 sensor as I2C slave, just use GPIO5 (SCL) and GPIO4 (SDA) to connect to the BME680 sensor's I2C interface.
|
||||
|
||||
```
|
||||
+-------------------------+ +--------+
|
||||
| ESP8266 Bus 0 | | BME680 |
|
||||
| GPIO 5 (SCL) +---->+ SCL |
|
||||
| GPIO 4 (SDA) +-----+ SDA |
|
||||
| | +--------+
|
||||
+-------------------------+
|
||||
```
|
||||
|
||||
For examples that are using SPI, BME680 sensor has to be connected to SPI bus 1. Since GPIO15 used as default CS signal of SPI bus 1 does not work correctly together with BME680, you have to connect CS to another GPIO pin, e.g., GPIO2.
|
||||
|
||||
```
|
||||
+-------------------------+ +----------+
|
||||
| ESP8266 Bus 1 | | BME680 |
|
||||
| GPIO 12 (MISO) <-----< SDO |
|
||||
| GPIO 13 (MOSI) >-----> SDI |
|
||||
| GPIO 14 (SCK) >-----> SCK |
|
||||
| GPIO 2 (CS) >-----> CS |
|
||||
+-------------------------+ +----------+
|
||||
```
|
||||
|
||||
The example with two sensors use the combination of I2C and SPI.
|
||||
|
||||
## Example description
|
||||
|
||||
__*bme680_one_sensor*__
|
||||
|
||||
This simple example uses only **one sensor** connected either to **I2C** or to **SPI**. Which of these interfaces is used is defined by constant **SPI_USED**. The user task triggers a measurement every second and uses function ```vTaskDelay``` to wait for the measurement results.
|
||||
|
||||
__*bme680_two_sensors*__
|
||||
|
||||
This example uses **two sensors**. One sensor is connected to **I2C** bus 0 and one sensor is connected to **SPI**. It defines two different user tasks, one for each sensor. It demonstrate the possible approaches to wait for measurement results, active busy waiting using ```bme680_is_measuring``` and passive waiting using *vTaskDelay*.
|
||||
|
||||
__*bme680_heating_profiles*__
|
||||
|
||||
This simple example uses one **only sensor** connected to **I2C** bus 0 and a sequence of heating profiles. The heating profile is changed with each cycle.
|
3
examples/bme680/bme680_heating_profiles/Makefile
Normal file
3
examples/bme680/bme680_heating_profiles/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=BME680_heating_profiles
|
||||
EXTRA_COMPONENTS = extras/i2c extras/bme680
|
||||
include ../../../common.mk
|
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
* Simple example with one sensor connected to I2C bus 0 and a sequence of
|
||||
* heating profiles. The heating profile is changed with each cycle.
|
||||
*
|
||||
* Harware configuration:
|
||||
*
|
||||
* I2C +-------------------------+ +----------+
|
||||
* | ESP8266 Bus 0 | | BME680 |
|
||||
* | GPIO 5 (SCL) ------> SCL |
|
||||
* | GPIO 4 (SDA) ------- SDA |
|
||||
* +-------------------------+ +----------+
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
// include communication interface driver
|
||||
#include "i2c/i2c.h"
|
||||
|
||||
// include BME680 driver
|
||||
#include "bme680/bme680.h"
|
||||
|
||||
// define I2C interface for BME680 sensors
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN 5
|
||||
#define I2C_SDA_PIN 4
|
||||
|
||||
static bme680_sensor_t* sensor;
|
||||
|
||||
/*
|
||||
* User task that triggers measurements of sensor every seconds. It uses
|
||||
* function *vTaskDelay* to wait for measurement results and changes the
|
||||
* heating profile in each cycle.
|
||||
*/
|
||||
void user_task(void *pvParameters)
|
||||
{
|
||||
bme680_values_float_t values;
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
uint32_t count = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (count++ < 60)
|
||||
// disable gas measurement for cycle counter < 60
|
||||
bme680_use_heater_profile (sensor, BME680_HEATER_NOT_USED);
|
||||
else
|
||||
// change heating profile in each cycle
|
||||
switch (count % 5)
|
||||
{
|
||||
case 0: bme680_use_heater_profile (sensor, 0); break;
|
||||
case 1: bme680_use_heater_profile (sensor, 1); break;
|
||||
case 2: bme680_use_heater_profile (sensor, 2); break;
|
||||
case 3: bme680_use_heater_profile (sensor, 3); break;
|
||||
case 4: bme680_use_heater_profile (sensor, 4); break;
|
||||
}
|
||||
|
||||
// measurement duration changes in each cycle
|
||||
uint32_t duration = bme680_get_measurement_duration(sensor);
|
||||
|
||||
// trigger the sensor to start one TPHG measurement cycle
|
||||
if (bme680_force_measurement (sensor))
|
||||
{
|
||||
// passive waiting until measurement results are available
|
||||
vTaskDelay (duration);
|
||||
|
||||
// get the results and do something with them
|
||||
if (bme680_get_results_float (sensor, &values))
|
||||
printf("%.3f BME680 Sensor: %.2f °C, %.2f %%, %.2f hPa, %.2f Ohm\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
values.temperature, values.humidity,
|
||||
values.pressure, values.gas_resistance);
|
||||
}
|
||||
// passive waiting until 1 second is over
|
||||
vTaskDelayUntil(&last_wakeup, 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Set UART Parameter
|
||||
uart_set_baud(0, 115200);
|
||||
// Give the UART some time to settle
|
||||
sdk_os_delay_us(500);
|
||||
|
||||
/** -- MANDATORY PART -- */
|
||||
|
||||
#ifdef SPI_USED
|
||||
// Init the sensor connected either to SPI.
|
||||
sensor = bme680_init_sensor (SPI_BUS, 0, SPI_CS_GPIO);
|
||||
#else
|
||||
// Init all I2C bus interfaces at which BME680 sensors are connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// Init the sensor connected either to I2C.
|
||||
sensor = bme680_init_sensor (I2C_BUS, BME680_I2C_ADDRESS_2, 0);
|
||||
#endif
|
||||
|
||||
if (sensor)
|
||||
{
|
||||
// Create a task that uses the sensor
|
||||
xTaskCreate(user_task, "user_task", 256, NULL, 2, NULL);
|
||||
|
||||
/** -- OPTIONAL PART -- */
|
||||
|
||||
// Changes the oversampling rates to 4x oversampling for temperature
|
||||
// and 2x oversampling for humidity. Pressure measurement is skipped.
|
||||
bme680_set_oversampling_rates(sensor, osr_4x, osr_none, osr_2x);
|
||||
|
||||
// Change the IIR filter size for temperature and pressure to 7.
|
||||
bme680_set_filter_size(sensor, iir_size_7);
|
||||
|
||||
// Define a number of different heating profiles
|
||||
bme680_set_heater_profile (sensor, 0, 200, 100);
|
||||
bme680_set_heater_profile (sensor, 1, 250, 120);
|
||||
bme680_set_heater_profile (sensor, 2, 300, 140);
|
||||
bme680_set_heater_profile (sensor, 3, 350, 160);
|
||||
bme680_set_heater_profile (sensor, 4, 400, 180);
|
||||
}
|
||||
}
|
3
examples/bme680/bme680_one_sensor/Makefile
Normal file
3
examples/bme680/bme680_one_sensor/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=BME680_One_Sensor
|
||||
EXTRA_COMPONENTS = extras/i2c extras/bme680
|
||||
include ../../../common.mk
|
131
examples/bme680/bme680_one_sensor/bme680_one_sensor.c
Normal file
131
examples/bme680/bme680_one_sensor/bme680_one_sensor.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
/**
|
||||
* Simple example with one sensor connected either to I2C bus 0 or
|
||||
* SPI bus 1.
|
||||
*
|
||||
* Harware configuration:
|
||||
*
|
||||
* I2C +-------------------------+ +----------+
|
||||
* | ESP8266 Bus 0 | | BME680 |
|
||||
* | GPIO 5 (SCL) ------> SCL |
|
||||
* | GPIO 4 (SDA) ------- SDA |
|
||||
* +-------------------------+ +----------+
|
||||
*
|
||||
* SPI +-------------------------+ +----------+
|
||||
* | ESP8266 Bus 1 | | BME680 |
|
||||
* | GPIO 12 (MISO) <-----< SDO |
|
||||
* | GPIO 13 (MOSI) >-----> SDI |
|
||||
* | GPIO 14 (SCK) >-----> SCK |
|
||||
* | GPIO 2 (CS) >-----> CS |
|
||||
* +-------------------------+ +----------+
|
||||
*/
|
||||
|
||||
// Uncomment to use SPI
|
||||
// #define SPI_USED
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
// include communication interface driver
|
||||
#include "esp/spi.h"
|
||||
#include "i2c/i2c.h"
|
||||
|
||||
// include BME680 driver
|
||||
#include "bme680/bme680.h"
|
||||
|
||||
|
||||
#ifdef SPI_USED
|
||||
// define SPI interface for BME680 sensors
|
||||
#define SPI_BUS 1
|
||||
#define SPI_CS_GPIO 2 // GPIO 15, the default CS of SPI bus 1, can't be used
|
||||
#else
|
||||
// define I2C interface for BME680 sensors
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN 5
|
||||
#define I2C_SDA_PIN 4
|
||||
#endif
|
||||
|
||||
static bme680_sensor_t* sensor;
|
||||
|
||||
/*
|
||||
* User task that triggers measurements of sensor every seconds. It uses
|
||||
* function *vTaskDelay* to wait for measurement results. Busy wating
|
||||
* alternative is shown in comments
|
||||
*/
|
||||
void user_task(void *pvParameters)
|
||||
{
|
||||
bme680_values_float_t values;
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
// as long as sensor configuration isn't changed, duration is constant
|
||||
uint32_t duration = bme680_get_measurement_duration(sensor);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// trigger the sensor to start one TPHG measurement cycle
|
||||
if (bme680_force_measurement (sensor))
|
||||
{
|
||||
// passive waiting until measurement results are available
|
||||
vTaskDelay (duration);
|
||||
|
||||
// alternatively: busy waiting until measurement results are available
|
||||
// while (bme680_is_measuring (sensor)) ;
|
||||
|
||||
// get the results and do something with them
|
||||
if (bme680_get_results_float (sensor, &values))
|
||||
printf("%.3f BME680 Sensor: %.2f °C, %.2f %%, %.2f hPa, %.2f Ohm\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
values.temperature, values.humidity,
|
||||
values.pressure, values.gas_resistance);
|
||||
}
|
||||
// passive waiting until 1 second is over
|
||||
vTaskDelayUntil(&last_wakeup, 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Set UART Parameter
|
||||
uart_set_baud(0, 115200);
|
||||
// Give the UART some time to settle
|
||||
sdk_os_delay_us(500);
|
||||
|
||||
/** -- MANDATORY PART -- */
|
||||
|
||||
#ifdef SPI_USED
|
||||
// Init the sensor connected either to SPI.
|
||||
sensor = bme680_init_sensor (SPI_BUS, 0, SPI_CS_GPIO);
|
||||
#else
|
||||
// Init all I2C bus interfaces at which BME680 sensors are connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// Init the sensor connected either to I2C.
|
||||
sensor = bme680_init_sensor (I2C_BUS, BME680_I2C_ADDRESS_2, 0);
|
||||
#endif
|
||||
|
||||
if (sensor)
|
||||
{
|
||||
// Create a task that uses the sensor
|
||||
xTaskCreate(user_task, "user_task", 256, NULL, 2, NULL);
|
||||
|
||||
/** -- OPTIONAL PART -- */
|
||||
|
||||
// Changes the oversampling rates to 4x oversampling for temperature
|
||||
// and 2x oversampling for humidity. Pressure measurement is skipped.
|
||||
bme680_set_oversampling_rates(sensor, osr_4x, osr_none, osr_2x);
|
||||
|
||||
// Change the IIR filter size for temperature and pressure to 7.
|
||||
bme680_set_filter_size(sensor, iir_size_7);
|
||||
|
||||
// Change the heater profile 0 to 200 degree Celcius for 100 ms.
|
||||
bme680_set_heater_profile (sensor, 0, 200, 100);
|
||||
bme680_use_heater_profile (sensor, 0);
|
||||
|
||||
// Set ambient temperature to 10 degree Celsius
|
||||
bme680_set_ambient_temperature (sensor, 10);
|
||||
}
|
||||
}
|
3
examples/bme680/bme680_two_sensors/Makefile
Normal file
3
examples/bme680/bme680_two_sensors/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=BME680_Tow_Sensors
|
||||
EXTRA_COMPONENTS = extras/i2c extras/bme680
|
||||
include ../../../common.mk
|
155
examples/bme680/bme680_two_sensors/bme680_two_sensors.c
Normal file
155
examples/bme680/bme680_two_sensors/bme680_two_sensors.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
* Simple example with two sensors, one sensor connected to I2C bus 0 and
|
||||
* one sensor connected to SPI. It defines two different user tasks, one for
|
||||
* each sensor. It demonstrate the possible approaches to wait for measurement
|
||||
* results, active busy waiting using ```bme680_is_measuring``` and passive
|
||||
* waiting using *vTaskDelay*.
|
||||
*
|
||||
* Harware configuration:
|
||||
*
|
||||
* +-------------------------+ +----------+
|
||||
* | ESP8266 I2C Bus 0 | | BME680_1 |
|
||||
* | GPIO 5 (SCL) ------> SCL |
|
||||
* | GPIO 4 (SDA) ------- SDA |
|
||||
* | | +----------+
|
||||
* | SPI Bus 1 | | BME680_2 |
|
||||
* | GPIO 12 (MISO) <------ SDO |
|
||||
* | GPIO 13 (MOSI) >-----> SDI |
|
||||
* | GPIO 14 (SCK) >-----> SCK |
|
||||
* | GPIO 2 (CS) >-----> CS |
|
||||
* +-------------------------+ +----------+
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
// include communication interface driver
|
||||
#include "esp/spi.h"
|
||||
#include "i2c/i2c.h"
|
||||
|
||||
// include BME680 driver
|
||||
#include "bme680/bme680.h"
|
||||
|
||||
// define I2C interface for BME680 sensor 1
|
||||
#define SPI_BUS 1
|
||||
#define SPI_CS_GPIO 2 // GPIO 15, the default CS of SPI bus 1, can't be used
|
||||
// define SPI interface for BME680 sensor 2
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN 5
|
||||
#define I2C_SDA_PIN 4
|
||||
|
||||
static bme680_sensor_t* sensor1;
|
||||
static bme680_sensor_t* sensor2;
|
||||
|
||||
/*
|
||||
* User task that triggers measurements of sensor1 every 5 seconds and
|
||||
* uses *vTaskDelay* to wait for measurement results.
|
||||
*/
|
||||
void user_task_sensor1(void *pvParameters)
|
||||
{
|
||||
bme680_values_float_t values;
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
uint32_t duration = bme680_get_measurement_duration (sensor1);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// trigger the sensor to start one TPHG measurement cycle
|
||||
if (bme680_force_measurement (sensor1))
|
||||
{
|
||||
|
||||
// passive waiting until measurement results are available
|
||||
vTaskDelay (duration);
|
||||
|
||||
// get the results and so something with them
|
||||
if (bme680_get_results_float (sensor1, &values))
|
||||
printf("%.3f BME680 Sensor1: %.2f °C, %.2f %%, %.2f hPa, %.2f Ohm\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
values.temperature, values.humidity,
|
||||
values.pressure, values.gas_resistance);
|
||||
}
|
||||
|
||||
// passive waiting until 5 seconds are over
|
||||
vTaskDelayUntil(&last_wakeup, 5000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* User task that triggers measurements of sensor1 every 2 seconds and
|
||||
* uses *bme680_is_measuring* to wait for measurement results.
|
||||
*/
|
||||
void user_task_sensor2(void *pvParameters)
|
||||
{
|
||||
bme680_values_float_t values;
|
||||
|
||||
TickType_t last_wakeup = xTaskGetTickCount();
|
||||
|
||||
while (1)
|
||||
{
|
||||
// trigger the sensor to start one TPHG measurement cycle
|
||||
if (bme680_force_measurement (sensor2))
|
||||
{
|
||||
// busy waiting until measurement results are available
|
||||
while (bme680_is_measuring (sensor2)) ;
|
||||
|
||||
// get the results and so something with them
|
||||
if (bme680_get_results_float (sensor2, &values))
|
||||
printf("%.3f BME680 Sensor2: %.2f °C, %.2f %%, %.2f hPa, %.2f Ohm\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
values.temperature, values.humidity,
|
||||
values.pressure, values.gas_resistance);
|
||||
}
|
||||
|
||||
// passive waiting until 2 seconds are over
|
||||
vTaskDelayUntil(&last_wakeup, 2000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Set UART Parameter
|
||||
uart_set_baud(0, 115200);
|
||||
// Give the UART some time to settle
|
||||
sdk_os_delay_us(500);
|
||||
|
||||
/** -- MANDATORY PART -- */
|
||||
|
||||
// Init all I2C bus interfaces at which BME680 sensors are connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// Init the sensors connected to different I2C buses with same address
|
||||
sensor1 = bme680_init_sensor (I2C_BUS, BME680_I2C_ADDRESS_2, 0);
|
||||
sensor2 = bme680_init_sensor (SPI_BUS, 0, SPI_CS_GPIO);
|
||||
|
||||
if (sensor1 && sensor2)
|
||||
{
|
||||
// Create the tasks that use the sensors
|
||||
xTaskCreate(user_task_sensor1, "user_task_sensor1", 256, NULL, 2, 0);
|
||||
xTaskCreate(user_task_sensor2, "user_task_sensor2", 256, NULL, 2, 0);
|
||||
|
||||
// That's it.
|
||||
|
||||
/** -- OPTIONAL PART -- */
|
||||
|
||||
// Changes the oversampling rates for both sensor to different values
|
||||
bme680_set_oversampling_rates(sensor1, osr_4x, osr_2x, osr_1x);
|
||||
bme680_set_oversampling_rates(sensor2, osr_8x, osr_8x, osr_8x);
|
||||
|
||||
// Change the IIR filter size for temperature and and pressure to 7.
|
||||
bme680_set_filter_size(sensor1, iir_size_7);
|
||||
bme680_set_filter_size(sensor2, iir_size_7);
|
||||
|
||||
// Change the heater profile 0 to 200 degree Celcius for 150 ms.
|
||||
bme680_set_heater_profile (sensor1, 0, 200, 150);
|
||||
bme680_set_heater_profile (sensor2, 0, 200, 150);
|
||||
|
||||
// Activate the heater profile 0
|
||||
bme680_use_heater_profile (sensor1, 0);
|
||||
bme680_use_heater_profile (sensor2, 0);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue