BME680 driver interface changes

- function bme680_force_measurement returns now a boolean
- function bme680_is_measuring returns now boolean
- function bme680_get_measurement_duration added
- heating profiles implemented
- example for heating profiles added
This commit is contained in:
Gunar Schorcht 2017-10-27 17:15:50 +02:00
parent 1bd9364ebb
commit 5b90f0ef58
9 changed files with 831 additions and 422 deletions

View file

@ -19,6 +19,7 @@ For examples using BME680 sensor as I2C slave, just use GPIO5 (SCL) and GPIO4 (S
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 |
@ -26,6 +27,7 @@ For examples that are using SPI, BME680 sensor has to be connected to SPI bus 1.
| GPIO 14 (SCK) >-----> SCK |
| GPIO 2 (CS) >-----> CS |
+-------------------------+ +----------+
```
The example with two sensors use the combination of I2C and SPI.
@ -33,8 +35,12 @@ The example with two sensors use the combination of I2C and SPI.
__*bme680_one_sensor*__
In this simple example, only **one sensor** connected either to **I2C** or to **SPI** is used. Constant **SPI_USED** defines which interface is used.
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*__
Simple example with two sensors, one sensor connected to **I2C** bus 0 and one sensor connected to **SPI**. It defines two different user tasks that use the sensors as well as different approaches for the implementation of waiting for measurement results, one as busy waiting using **_bme680_is_measuring_** and one as passive waiting using *vTaskDelay*.
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.

View file

@ -0,0 +1,3 @@
PROGRAM=BME680_heating_profiles
EXTRA_COMPONENTS = extras/i2c extras/bme680
include ../../../common.mk

View file

@ -0,0 +1,126 @@
/**
* 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 GPIO_ID_PIN((5))
#define I2C_SDA_PIN GPIO_ID_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);
}
}

View file

@ -56,28 +56,30 @@ static bme680_sensor_t* sensor;
void user_task(void *pvParameters)
{
bme680_values_float_t values;
int32_t duration;
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
duration = bme680_force_measurement (sensor);
if (bme680_force_measurement (sensor))
{
// passive waiting until measurement results are available
vTaskDelay (duration);
// passive waiting until measurement results are available
if (duration > 0) vTaskDelay (duration);
// busy waiting until measurement results are available
// while (bme680_is_measuring (sensor) > 0) ;
// 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);
// 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);
}
@ -93,7 +95,6 @@ void user_init(void)
/** -- MANDATORY PART -- */
#ifdef SPI_USED
// Init the sensor connected either to SPI.
sensor = bme680_init_sensor (SPI_BUS, 0, SPI_CS_GPIO);
@ -112,18 +113,19 @@ void user_init(void)
/** -- OPTIONAL PART -- */
// Changes the oversampling rates (default os_1x) to 4x oversampling
// for temperature and 2x oversampling for humidity. Pressure
// measurement is skipped in this example.
// 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 (default iir_size_3) for temperature and
// and pressure to 7.
// Change the IIR filter size for temperature and pressure to 7.
bme680_set_filter_size(sensor, iir_size_7);
// Change the heaeter profile (default 320 degree Celcius for 150 ms)
// to 200 degree Celcius for 100 ms.
bme680_set_heater_profile (sensor, 320, 150);
// 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);
}
}

View file

@ -1,8 +1,9 @@
/**
* Simple example with two sensors, one sensor connected to I2C bus 0 and
* one sensor connected to SPI. It also shows both approaches for the
* implementation of waiting for measurement results, one as busy waiting
* and one as passive waiting using *vTaskDelay*.
* 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:
*
@ -44,30 +45,33 @@ static bme680_sensor_t* sensor1;
static bme680_sensor_t* sensor2;
/*
* User task that triggers measurements of sensor1 every 5 seconds. It
* 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;
int32_t duration;
TickType_t last_wakeup = xTaskGetTickCount();
uint32_t duration = bme680_get_measurement_duration (sensor1);
while (1)
{
// trigger the sensor to start one TPHG measurement cycle
duration = bme680_force_measurement (sensor1);
if (bme680_force_measurement (sensor1))
{
// passive waiting until measurement results are available
if (duration > 0) vTaskDelay (duration);
// 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);
// 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);
@ -75,8 +79,8 @@ void user_task_sensor1(void *pvParameters)
}
/*
* User task that triggers measurements of sensor1 every 2 seconds. It
* uses *vTaskDelay* to wait for measurement results.
* 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)
{
@ -87,17 +91,18 @@ void user_task_sensor2(void *pvParameters)
while (1)
{
// trigger the sensor to start one TPHG measurement cycle
bme680_force_measurement (sensor2);
// busy waiting until measurement results are available
while (bme680_is_measuring (sensor2) > 0) ;
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);
// 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);
@ -132,18 +137,20 @@ void user_init(void)
/** -- OPTIONAL PART -- */
// Changes the oversampling rates for both sensor to different values
bme680_set_oversampling_rates(sensor1, osr_1x, osr_1x, osr_1x);
bme680_set_oversampling_rates(sensor2, osr_16x, osr_16x, osr_16x);
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 (default iir_size_3) for temperature and
// and pressure to 7.
// 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 heaeter profile (default 20 degree Celcius for 150 ms) to
// 200 degree Celcius for 100 ms.
bme680_set_heater_profile (sensor1, 200, 100);
bme680_set_heater_profile (sensor2, 200, 100);
// 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);
}
}