Driver for Sensirion SHT3x sensor added

This is a driver for Sensirion SHT3x temperature and humidity sensors
connected via I2C.

This commit is a rebasing and contains some interface changes based on
the review from @ourairquality.
This commit is contained in:
Gunar Schorcht 2017-10-03 13:32:43 +02:00 committed by Gunar Schorcht
parent 546cc47121
commit 803931f2e2
9 changed files with 1283 additions and 0 deletions

48
examples/sht3x/README.md Normal file
View file

@ -0,0 +1,48 @@
# SHT3x Driver Examples
These examples references two addtional drivers [i2c](https://github.com/kanflo/esp-open-rtos-driver-i2c) and [sht3x](https://github.com/gschorcht/esp-open-rtos/extras/sht3x), which are provided in the `../../extras` folder.
If you plan to use one or both of this drivers in your own projects, please check the main development pages for updated versions or reported issues.
## Hardware setup
There are examples for only one sensor and examples for two sensors.
To run examples with **one sensor**, just use GPIO5 (SCL) and GPIO4 (SDA) to connect to the SHT3x sensor's I2C interface.
```
+------------------------+ +--------+
| ESP8266 Bus 0 | | SHT3x |
| GPIO 5 (SCL) >---- > SCL |
| GPIO 4 (SDA) ------- SDA |
| | +--------+
+------------------------+
```
If you want to run examples with **two sensors**, you could do this with only one bus and different I2C addresses or with two buses and the same or different I2C addresses. In later case, use GPIO14 (SCL) and GPIO12 (SDA) for the second bus to connect to the second SHT3x sensor's I2C interface.
```
+------------------------+ +----------+
| ESP8266 Bus 0 | | SHT3x_1 |
| GPIO 5 (SCL) >-----> SCL |
| GPIO 4 (SDA) ------- SDA |
| | +----------+
| Bus 1 | | SHT3x_2 |
| GPIO 14 (SCL) >-----> SCL |
| GPIO 12 (SDA) ------- SDA |
+------------------------+ +----------+
```
## Example description
Examples show how to use the driver in single shot as well as in periodic mode.
### _sht3x_one_sensor_
The simple example show how to use the driver with one SHT3x sensor. It demonstrates two different user task implementations, one in *single shot mode* and one in *periodic mode*. In addition, it shows both approaches for the implementation of waiting for measurement results, one as busy waiting and one as passive waiting using *vTaskDelay*.
### _sht3x_two_sensors_
This simple example shows how to use the driver for two sensors. As with the example _sht3x_one_sensor_, it uses two different user task implementations and waiting approaches, in this example one for each of the tasks.

View file

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

View file

@ -0,0 +1,126 @@
/**
* Simple example with one SHT3x sensor.
*
* It shows two different user task implementations, one in *single shot mode*
* and one in *periodic mode*. In addition, it shows both approaches for the
* implementation of waiting for measurement results, one as busy waiting and
* one as passive waiting using *vTaskDelay*.
*
* The implementation that is used is defined by constant SINGLE_SHOT_MODE.
*
* Harware configuration:
*
* +------------------------+ +----------+
* | ESP8266 Bus 0 | | SHT3x |
* | GPIO 5 (SCL) ------> SCL |
* | GPIO 4 (SDA) ------- SDA |
* +------------------------+ +----------+
*/
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
// include SHT3x driver
#include "sht3x/sht3x.h"
// define I2C interfaces at which SHTx3 sensors are connected
#define I2C_BUS 0
#define I2C_SCL_PIN GPIO_ID_PIN((5))
#define I2C_SDA_PIN GPIO_ID_PIN((4))
static sht3x_sensor_t* sensor; // sensor device data structure
// #define SINGLE_SHOT_MODE
#ifdef SINGLE_SHOT_MODE
/*
* User task that triggers measurements of sensor every 5 seconds. Due to
* power efficiency reasons, it uses the SHT3x *single_shot* and *vTaskDelay*
* to wait for measurement results.
*/
void user_task (void *pvParameters)
{
sht3x_values_t values;
int32_t duration;
TickType_t last_wakeup = xTaskGetTickCount();
while (1)
{
// trigger one measurement in single shot mode
duration = sht3x_start_measurement (sensor, single_shot);
// passive waiting until measurement results are available
if (duration > 0)
vTaskDelay (duration/portTICK_PERIOD_MS);
// retrieve the values and do something with them
if (sht3x_get_results (sensor, &values))
printf("%.3f SHT3x Sensor: %.2f °C, %.2f %%\n",
(double)sdk_system_get_time()*1e-3,
values.temperature, values.humidity);
// passive waiting until 5 seconds are over
vTaskDelayUntil(&last_wakeup, 5000 / portTICK_PERIOD_MS);
}
}
#else // PERIODIC MODE
/*
* User task that fetches latest measurement results of sensor every 2
* seconds. It starts the SHT3x in periodic mode with 1 measurements per
* second (*periodic_1mps*). It uses busy waiting for first measurement
* results.
*/
void user_task (void *pvParameters)
{
sht3x_values_t values;
// start periodic measurement mode
sht3x_start_measurement (sensor, periodic_1mps);
// busy waiting until measurement results are available
while (sht3x_is_measuring (sensor) > 0) ;
TickType_t last_wakeup = xTaskGetTickCount();
while (1)
{
// retrieve the values and do something with them
if (sht3x_get_results (sensor, &values))
printf("%.3f SHT3x Sensor: %.2f °C, %.2f %%\n",
(double)sdk_system_get_time()*1e-3,
values.temperature, values.humidity);
// passive waiting until 2 seconds are over
vTaskDelayUntil(&last_wakeup, 2000 / portTICK_PERIOD_MS);
}
}
#endif
void user_init(void)
{
// Please note: Return values are not considered in this example for
// readability reasons. All functions return boolean and set an error
// code that allows effective error handling.
// Set UART Parameter
uart_set_baud(0, 115200);
// Give the UART some time to settle
sdk_os_delay_us(500);
// Init I2C bus interfaces at which SHT3x sensors are connected
// (different busses are possible)
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
// Create sensors
sensor = sht3x_init_sensor (I2C_BUS, SHT3x_ADDR_2);
// Create a user task that uses the sensor
xTaskCreate(user_task, "user_task", 256, NULL, 2, 0);
// That's it.
}

View file

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

View file

@ -0,0 +1,135 @@
/**
* Simple example with two SHT3x sensors.
*
* It shows two different user task implementations, one in *single shot mode*
* and one in *periodic mode*. In addition, it shows both approaches for the
* implementation of waiting for measurement results, one as busy waiting and
* one as passive waiting using *vTaskDelay*.
*
* Harware configuration:
*
* +------------------------+ +----------+
* | ESP8266 Bus 0 | | SHT3x_1 |
* | GPIO 5 (SCL) ------> SCL |
* | GPIO 4 (SDA) ------- SDA |
* | | +----------+
* | Bus 1 | | SHT3x_2 |
* | GPIO 14 (SCL) ------> SCL |
* | GPIO 12 (SDA) ------- SDA |
* +------------------------+ +----------+
*/
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
// include SHT3x driver
#include "sht3x/sht3x.h"
// define I2C interfaces at which SHTx3 sensors are connected
#define I2C_1_BUS 0
#define I2C_1_SCL_PIN GPIO_ID_PIN((5))
#define I2C_1_SDA_PIN GPIO_ID_PIN((4))
#define I2C_2_BUS 1
#define I2C_2_SCL_PIN GPIO_ID_PIN((14))
#define I2C_2_SDA_PIN GPIO_ID_PIN((12))
static sht3x_sensor_t* sensor1;
static sht3x_sensor_t* sensor2;
/*
* User task that triggers measurements of sensor1 every 5 seconds. Due to
* power efficiency reasons, it uses the SHT3x *single_shot* and *vTaskDelay*
* to wait for measurement results.
*/
void user_task_sensor1 (void *pvParameters)
{
sht3x_values_t values;
int32_t duration;
TickType_t last_wakeup = xTaskGetTickCount();
while (1)
{
// trigger one measurement in single shot mode
duration = sht3x_start_measurement (sensor1, single_shot);
// passive waiting until measurement results are available
if (duration > 0)
vTaskDelay (duration/portTICK_PERIOD_MS);
// retrieve the values and do something with them
if (sht3x_get_results (sensor1, &values))
printf("%.3f SHT3x Sensor1: %.2f °C, %.2f %%\n",
(double)sdk_system_get_time()*1e-3,
values.temperature, values.humidity);
// passive waiting until 5 seconds are over
vTaskDelayUntil(&last_wakeup, 5000 / portTICK_PERIOD_MS);
}
}
/*
* User task that fetches latest measurement results of sensor2 every 2
* seconds. It starts the SHT3x in periodic mode with 10 measurements per
* second (*periodic_10mps*). It uses busy waiting for first measurement
* results.
*/
void user_task_sensor2 (void *pvParameters)
{
sht3x_values_t values;
// start periodic measurement mode
sht3x_start_measurement (sensor2, periodic_10mps);
// busy waiting until measurement results are available
while (sht3x_is_measuring (sensor2) > 0);
TickType_t last_wakeup = xTaskGetTickCount();
while (1)
{
// retrieve the values and do something with them
if (sht3x_get_results (sensor2, &values))
printf("%.3f SHT3x Sensor2: %.2f °C, %.2f %%\n",
(double)sdk_system_get_time()*1e-3,
values.temperature, values.humidity);
// passive waiting until 2 seconds are over
vTaskDelayUntil(&last_wakeup, 2000 / portTICK_PERIOD_MS);
}
}
void user_init(void)
{
// Please note: Return values are not considered in this example for
// readability reasons. All functions return boolean and set an error
// code that allows effective error handling.
// Set UART Parameter
uart_set_baud(0, 115200);
// Give the UART some time to settle
sdk_os_delay_us(500);
// Init I2C bus interfaces at which SHT3x sensors are connected
// (different busses are possible)
i2c_init(I2C_1_BUS, I2C_1_SCL_PIN, I2C_1_SDA_PIN, I2C_FREQ_100K);
i2c_init(I2C_2_BUS, I2C_2_SCL_PIN, I2C_2_SDA_PIN, I2C_FREQ_100K);
// Create sensors
sensor1 = sht3x_init_sensor (I2C_1_BUS, SHT3x_ADDR_2);
sensor2 = sht3x_init_sensor (I2C_2_BUS, SHT3x_ADDR_1);
// Create 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.
}