Merge c4248581e2 into b83c2629b9
This commit is contained in:
commit
059bcd6e23
13 changed files with 1248 additions and 0 deletions
52
examples/sht3x/README.md
Normal file
52
examples/sht3x/README.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# 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 | | BME680 |
|
||||
| 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 GPIO16 (SCL) and GPIO14 (SDA) for the second bus to connect to the second SHT3x sensor's I2C interface.
|
||||
|
||||
```
|
||||
+------------------------+ +----------+
|
||||
| ESP8266 Bus 0 | | BME680_1 |
|
||||
| GPIO 5 (SCL) ------> SCL |
|
||||
| GPIO 4 (SDA) ------- SDA |
|
||||
| | +----------+
|
||||
| Bus 1 | | BME680_2 |
|
||||
| GPIO 12 (SCL) ------> SCL |
|
||||
| GPIO 14 (SDA) ------- SDA |
|
||||
+------------------------+ +----------+
|
||||
```
|
||||
|
||||
## Example description
|
||||
|
||||
### _shtx_callback_one_sensor_
|
||||
|
||||
This example shows how to use a **callback function** to get the results of periodic measurements of only **one sensor** with a period of 1000 ms. It includes some simple error handling.
|
||||
|
||||
### _shtx_callback_two_sensors_
|
||||
|
||||
This example shows how to use a **callback function** to get the results of periodic measurements of **two sensors** with **different measurement periods** of 1000 ms and 5000 ms, respectively. The sensors are connected to **two different buses**. There is no error handling in this example.
|
||||
|
||||
### _shtx_task_one_sensor_
|
||||
|
||||
This example shows how to use a **task** in conjunction with function **_sht3x_get_values_** to get the results of periodic measurements of only **one sensor** with a period of 1000 ms. The task uses function **_vTaskDelay_** to realize a periodic exudation of function **_sht3x_get_values_** with same rate as periodic measurements. There is no error handling in this example.
|
||||
|
||||
### _shtx_timer_one_sensor_
|
||||
|
||||
This example shows how to use a **software timer** and **timer callback function** in conjunction with function **_sht3x_get_values_** to get the results of periodic measurements of only **one sensor** with a period of 1000 ms. The timer callback function executes function **_sht3x_get_values_** to get the results of periodic measurements. The timer is started with same period as periodic measurements. Thus, the timer callback function is executed at same rate as periodic measurements. There is no error handling in this example.
|
||||
3
examples/sht3x/sht3x_callback_one_sensor/Makefile
Normal file
3
examples/sht3x/sht3x_callback_one_sensor/Makefile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=SHT3x_Reader
|
||||
EXTRA_COMPONENTS = extras/i2c extras/sht3x
|
||||
include ../../../common.mk
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* Simple example with one sensor using SHT3x driver using callback function
|
||||
* to get the results.
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
// include SHT3x driver
|
||||
|
||||
#include "sht3x/sht3x.h"
|
||||
|
||||
// define I2C interface at which SHTx3 sensor is connected
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN GPIO_ID_PIN((5))
|
||||
#define I2C_SDA_PIN GPIO_ID_PIN((4))
|
||||
|
||||
#define SHT3x_ADDR 0x45
|
||||
|
||||
static uint32_t sensor;
|
||||
|
||||
/**
|
||||
* Everything you need is a callback function that can handle
|
||||
* callbacks from the background measurement task of the
|
||||
* SHT3x driver. This function is called periodically
|
||||
* and delivers the actual and average sensor value sets for
|
||||
* given sensor.
|
||||
*/
|
||||
static void my_callback_function (uint32_t sensor,
|
||||
sht3x_value_set_t actual,
|
||||
sht3x_value_set_t average)
|
||||
{
|
||||
printf("%.3f Sensor %d: %.2f (%.2f) C, %.2f (%.2f) F, %.2f (%.2f) \n",
|
||||
(double)sdk_system_get_time()*1e-3, sensor,
|
||||
actual.temperature_c, average.temperature_c,
|
||||
actual.temperature_f, average.temperature_f,
|
||||
actual.humidity, average.humidity);
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Set UART Parameter
|
||||
uart_set_baud(0, 115200);
|
||||
|
||||
// Give the UART some time to settle
|
||||
sdk_os_delay_us(500);
|
||||
|
||||
// Init I2C bus interface at which SHT3x sensor is connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// Init SHT3x driver
|
||||
if (!sht3x_init())
|
||||
{
|
||||
// error message
|
||||
return;
|
||||
}
|
||||
|
||||
// Create sensors
|
||||
if ((sensor = sht3x_create_sensor (I2C_BUS, SHT3x_ADDR)) < 0)
|
||||
{
|
||||
// error message
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the callback function
|
||||
if (!sht3x_set_callback_function (sensor, &my_callback_function))
|
||||
{
|
||||
// error message
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
// Optional: Set the period of measurements (default 1000 ms)
|
||||
if (!sht3x_set_measurement_period (sensor, 1000))
|
||||
{
|
||||
// error message
|
||||
return;
|
||||
}
|
||||
|
||||
// Optional: Set the weight for expontial moving average (default 0.2)
|
||||
if (!sht3x_set_average_weight (sensor, 0.2))
|
||||
{
|
||||
// error message
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
// That's it.
|
||||
}
|
||||
3
examples/sht3x/sht3x_callback_two_sensors/Makefile
Normal file
3
examples/sht3x/sht3x_callback_two_sensors/Makefile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=SHT3x_Reader
|
||||
EXTRA_COMPONENTS = extras/i2c extras/sht3x
|
||||
include ../../../common.mk
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* Simple example with two sensors connected to two different I2C interfaces
|
||||
* using SHT3x driver using callback function to get the results.
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.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((12))
|
||||
#define I2C_2_SDA_PIN GPIO_ID_PIN((14))
|
||||
|
||||
#define SHT3x_ADDR_1 0x44
|
||||
#define SHT3x_ADDR_2 0x45
|
||||
|
||||
static uint32_t sensor1;
|
||||
static uint32_t sensor2;
|
||||
|
||||
/**
|
||||
* Everything you need is a callback function that can handle
|
||||
* callbacks from the background measurement task of the
|
||||
* SHT3x driver. This function is called periodically
|
||||
* and delivers the actual and average sensor values for
|
||||
* given sensor.
|
||||
*/
|
||||
static void my_callback_function (uint32_t sensor,
|
||||
sht3x_value_set_t actual,
|
||||
sht3x_value_set_t average)
|
||||
{
|
||||
printf("%.3f Sensor %d: %.2f (%.2f) C, %.2f (%.2f) F, %.2f (%.2f) \n",
|
||||
(double)sdk_system_get_time()*1e-3, sensor,
|
||||
actual.temperature_c, average.temperature_c,
|
||||
actual.temperature_f, average.temperature_f,
|
||||
actual.humidity, average.humidity);
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Please note: Return values are not considered for readability reasons.
|
||||
// All functions return a boolean that allows effecitve 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);
|
||||
|
||||
// Init SHT3x driver (parameter is the number of SHT3x sensors used)
|
||||
sht3x_init();
|
||||
|
||||
// Create sensors
|
||||
sensor1 = sht3x_create_sensor (I2C_2_BUS, SHT3x_ADDR_1);
|
||||
sensor2 = sht3x_create_sensor (I2C_1_BUS, SHT3x_ADDR_2);
|
||||
|
||||
// Set the callback function
|
||||
sht3x_set_callback_function (sensor1, &my_callback_function);
|
||||
sht3x_set_callback_function (sensor2, &my_callback_function);
|
||||
|
||||
// Optional: Set the period of measurements (default 1000 ms)
|
||||
sht3x_set_measurement_period (sensor1, 1000);
|
||||
sht3x_set_measurement_period (sensor2, 5000);
|
||||
|
||||
// Optional: Set the weight for expontial moving average (default 0.2)
|
||||
sht3x_set_average_weight (sensor1, 0.15);
|
||||
sht3x_set_average_weight (sensor2, 0.25);
|
||||
|
||||
// That's it.
|
||||
}
|
||||
3
examples/sht3x/sht3x_task_one_sensor/Makefile
Normal file
3
examples/sht3x/sht3x_task_one_sensor/Makefile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=SHT3x_Reader
|
||||
EXTRA_COMPONENTS = extras/i2c extras/sht3x
|
||||
include ../../../common.mk
|
||||
81
examples/sht3x/sht3x_task_one_sensor/sht3x_task_one_sensor.c
Normal file
81
examples/sht3x/sht3x_task_one_sensor/sht3x_task_one_sensor.c
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* Simple example with one sensor using SHT3x driver in periodic mode
|
||||
* and a user task.
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
// include SHT3x driver
|
||||
|
||||
#include "sht3x/sht3x.h"
|
||||
|
||||
// define I2C interface at which SHTx3 sensor is connected
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN GPIO_ID_PIN((5))
|
||||
#define I2C_SDA_PIN GPIO_ID_PIN((4))
|
||||
|
||||
#define SHT3x_ADDR 0x45
|
||||
|
||||
static uint32_t sensor;
|
||||
|
||||
/**
|
||||
* Task that executes function sht3x_get_values to get last
|
||||
* actual and average sensor values for given sensor.
|
||||
*/
|
||||
void my_user_task(void *pvParameters)
|
||||
{
|
||||
sht3x_value_set_t actual;
|
||||
sht3x_value_set_t average;
|
||||
|
||||
while (1)
|
||||
{
|
||||
sht3x_get_values(sensor, &actual, &average);
|
||||
|
||||
printf("%.3f Sensor %d: %.2f (%.2f) C, %.2f (%.2f) F, %.2f (%.2f) \n",
|
||||
(double)sdk_system_get_time()*1e-3, sensor,
|
||||
actual.temperature_c, average.temperature_c,
|
||||
actual.temperature_f, average.temperature_f,
|
||||
actual.humidity, average.humidity);
|
||||
|
||||
// Delay value has to be equal or greater than the period of measurment
|
||||
// task
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Please note: Return values are not considered for readability reasons.
|
||||
// All functions return a boolean that allows effecitve 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 interface at which SHT3x sensor is connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// Init SHT3x driver
|
||||
sht3x_init();
|
||||
|
||||
// Create sensors
|
||||
sensor = sht3x_create_sensor (I2C_BUS, SHT3x_ADDR);
|
||||
|
||||
// Optional: Set the period of measurements (default 1000 ms)
|
||||
// sht3x_set_measurement_period (sensor, 1000);
|
||||
|
||||
// Optional: Set the weight for expontial moving average (default 0.2)
|
||||
// sht3x_set_average_weight (sensor, 0.2);
|
||||
|
||||
// Create a task for getting results
|
||||
xTaskCreate(my_user_task, "my_user_task", 256, NULL, 2, NULL);
|
||||
|
||||
// That's it.
|
||||
}
|
||||
3
examples/sht3x/sht3x_timer_one_sensor/Makefile
Normal file
3
examples/sht3x/sht3x_timer_one_sensor/Makefile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=SHT3x_Reader
|
||||
EXTRA_COMPONENTS = extras/i2c extras/sht3x
|
||||
include ../../../common.mk
|
||||
80
examples/sht3x/sht3x_timer_one_sensor/sht3x_periodic_timer.c
Normal file
80
examples/sht3x/sht3x_timer_one_sensor/sht3x_periodic_timer.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* Simple example with one sensor using SHT3x driver using function
|
||||
* sht3x_get_values triggered by software timers to get the results.
|
||||
*/
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "timers.h"
|
||||
|
||||
// include SHT3x driver
|
||||
|
||||
#include "sht3x/sht3x.h"
|
||||
|
||||
// define I2C interface at which SHTx3 sensor is connected
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN GPIO_ID_PIN((5))
|
||||
#define I2C_SDA_PIN GPIO_ID_PIN((4))
|
||||
|
||||
#define SHT3x_ADDR 0x45
|
||||
|
||||
static TimerHandle_t timerHandle;
|
||||
static uint32_t sensor;
|
||||
|
||||
/**
|
||||
* Timer callback function that executes function sht3x_get_values to get last
|
||||
* actual and average sensor values for given sensor.
|
||||
*/
|
||||
static void my_sensor_timer_cb(TimerHandle_t xTimer)
|
||||
{
|
||||
sht3x_value_set_t actual;
|
||||
sht3x_value_set_t average;
|
||||
|
||||
sht3x_get_values(sensor, &actual, &average);
|
||||
|
||||
printf("%.3f Sensor %d: %.2f (%.2f) C, %.2f (%.2f) F, %.2f (%.2f) \n",
|
||||
(double)sdk_system_get_time()*1e-3, sensor,
|
||||
actual.temperature_c, average.temperature_c,
|
||||
actual.temperature_f, average.temperature_f,
|
||||
actual.humidity, average.humidity);
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Please note: Return values are not considered for readability reasons.
|
||||
// All functions return a boolean that allows effecitve 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 interface at which SHT3x sensor is connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// Init SHT3x driver
|
||||
sht3x_init();
|
||||
|
||||
// Create sensors
|
||||
sensor = sht3x_create_sensor (I2C_BUS, SHT3x_ADDR);
|
||||
|
||||
// Optional: Set the period of measurements (default 1000 ms)
|
||||
// sht3x_set_measurement_period (sensor, 1000);
|
||||
|
||||
// Optional: Set the weight for expontial moving average (default 0.2)
|
||||
// sht3x_set_average_weight (sensor, 0.2);
|
||||
|
||||
// Create and start a timer that calls sht3x_i2c_timer_cb every 1000 ms
|
||||
// Timer value has to be equal or greater than the period of measurment
|
||||
// task above
|
||||
|
||||
if ((timerHandle = xTimerCreate("SHT3x Trigger", 1000/portTICK_PERIOD_MS,
|
||||
pdTRUE, NULL, my_sensor_timer_cb)))
|
||||
xTimerStart(timerHandle, 0);
|
||||
|
||||
// That's it.
|
||||
}
|
||||
218
extras/sht3x/README.md
Normal file
218
extras/sht3x/README.md
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
# Driver for **SHT3x** digital temperature and humidity sensor
|
||||
|
||||
This driver is written for usage with the ESP8266 and FreeRTOS using the I2C interface driver ([esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos) and [esp-open-rtos-driver-i2c](https://github.com/kanflo/esp-open-rtos-driver-i2c)).
|
||||
|
||||
Please note: The driver supports multiple sensors connected to different I2C interfaces and different addresses.
|
||||
|
||||
## About the sensor
|
||||
|
||||
SHT3x is a digital temperature and humidity sensor that uses an I2C interface with up to 1 MHz communication speed. It can operate with **three levels of repeatability** (low, medium and high) and in two different modes, the **single shot data acquisition mode** and the **periodic data acquisition mode**.
|
||||
|
||||
### Single shot data acquisition mode
|
||||
|
||||
In this mode, a measurement command triggers the **acquisition of one data pair**. Each data pair consists of temperature and humidity as 16-bit decimal values.
|
||||
|
||||
The repeatability affects the measurement time as well as the power consumption of the sensor. The measurement takes 3 ms with low repeatability, 5 ms with medium repeatability and 13.5 ms with high repeatability. That is, the measurement produces a noticeable delay in execution.
|
||||
|
||||
While the sensor measures at the lowest repeatability, the average current consumption is 800 μA. That is, the higher the repeatability level, the longer the measurement takes and the higher the power consumption. The sensor consumes only 0.2 μA in standby mode.
|
||||
|
||||
### Periodic data acquisition mode
|
||||
|
||||
In this mode, one issued measurement command yields a stream of data pairs. Each data pair again consists of temperature and humidity as 16-bit decimal values. As soon as the measurement command has been sent to the sensor, it performs measurements **periodically at a rate of 0.5, 1, 2, 4 or 10 measurements per second (mps)**. The data pairs can be read with a fetch command at the same rate.
|
||||
|
||||
As in the *single shot data acquisition mode*, the repeatability setting affects both the measurement time and the current consumption of the sensor, see above.
|
||||
|
||||
## How the driver works
|
||||
|
||||
In order to avoid blocking of user tasks during measurements due to their duration, separate **background tasks** are used for each sensor to **carry out the measurements**. These background tasks are created automatically when a user task calls function **_sht3x_create_sensor_** to initialize a connected SHT3x sensor. For each connected sensor, one background task is created. The background tasks realize the measurement procedures which are executed periodically at a rate that can be defined by the user for each sensor separately using function **_sht3x_set_measurement_period_** (default period is 1000 ms).
|
||||
|
||||
### Measurement method
|
||||
|
||||
Since the predefined rates of *periodic data acquisition mode* of the sensor itself are normally not compatible with user requirements, the **periodic measurements are realized by the background task using the _single shot data acquisition mode_** at the highest level of repeatability. Because of the sensor power characteristics, *single shot data acquisition mode* is more power efficient than using the *periodic data acquisition mode* in most use cases.
|
||||
|
||||
However, using the *single shot data acquisition mode* produces a delay of 20 ms for each measurement. This is just the time needed from issuing the measurement command until measured sensor data are available and can be read. Since this delay is realized using **_vTaskDelay_** function in the background tasks, **neither the system nor any user task is blocked during the measurements**.
|
||||
|
||||
Since each measurement produces a delay of 20 ms, the **minimum period** that can be defined with function **_sht3x_set_measurement_period_** is 20 ms. Therefore, a maximum measurement rate of 50 mps could be reached.
|
||||
|
||||
### Measured data
|
||||
|
||||
At each measurement, **actual sensor values** for temperature as well as humidity are determined as floating point values from the measured data pairs. Temperature is given in °C as well as in °F. Humidity is given in percent.
|
||||
|
||||
If average value computation is enabled (default), the background task also computes successively at each measurement the **average sensor values** based on these *actual sensor values* using the exponential moving average
|
||||
|
||||
Average[k] = W * Actual + (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. The coefficient W (smoothing factor) can be defined by the user task using function **_sht3x_set_average_weight_**. The default value of W is 0.2. The average value computation can be enabled or disabled using function **_sht3x_enable_average_computation_**.
|
||||
|
||||
If average computation is disabled, *average sensor values* correspond to the *actual sensor values*.
|
||||
|
||||
### Getting results.
|
||||
|
||||
As soon as a measurement is completed, the actual sensor values * and * average sensor values * can be read by user tasks. There are two ways to do this:
|
||||
|
||||
- define a **callback function** or
|
||||
- call the function **_sht3x_get_values_** explicitly.
|
||||
|
||||
#### Using callback function
|
||||
|
||||
For each connected SHT3 sensor, the user task can register a callback function using function **_sht3x_set_callback_function_**. If a callback function is registered, it is called by the background task after each measurement to pass *actual sensor values* and *average sensor values* to user tasks. Thus, the user gets the results of the measurements automatically with same rate as the periodic measurements are executed.
|
||||
|
||||
Using the callback function is the easiest way to get the results.
|
||||
|
||||
#### Using function **_sht3x_get_values_**
|
||||
|
||||
If there is no callback function registered, the user task has to call function **_sht3x_get_values_** to get *actual sensor values* and *average sensor values*. These values are stored in data structures that are specified as pointer parameters. Using NULL pointers for the parameters, the user task can decide which results are not interesting.
|
||||
|
||||
To ensure that the values are up-to-date, the rate of periodic measurement in background task should be at least the same or higher as the rate of using function **_sht3x_get_values_**. That is, the period of measurements in background task set with function **_sht3x_set_measurement_period_** has to be less or equal than the rate of using function **_sht3x_get_values_**.
|
||||
|
||||
If average computation is disabled, *average sensor values* are just the same as *actual sensor values*.
|
||||
|
||||
Please note: The minimum measurement period can be 20 ms.
|
||||
|
||||
## Usage
|
||||
|
||||
Before using the SHT3x driver, function **_i2c_init_** needs to be called to setup each I2C interface.
|
||||
|
||||
```
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN GPIO_ID_PIN((5))
|
||||
#define I2C_SDA_PIN GPIO_ID_PIN((4))
|
||||
|
||||
#define SHT3x_ADDR 0x45
|
||||
|
||||
...
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K))
|
||||
...
|
||||
```
|
||||
|
||||
Next, the SHT3x driver itself has to be initialized using function **_sht3x_init_**.
|
||||
|
||||
```
|
||||
sht3x_init();
|
||||
```
|
||||
|
||||
If SHT3x driver initialization was successful, function **_sht3x_create_sensor_** has to be called for each sensor to initialize the sensor connected to a certain bus with given slave address, to check its availability and to start the background task for measurements.
|
||||
|
||||
```
|
||||
sensor = sht3x_create_sensor (I2C_BUS, SHT3x_ADDR);
|
||||
```
|
||||
|
||||
On success this function returns the *ID* of a sensor descriptor between 0 and **_SHT3x_MAX_SENSORS_** or -1 otherwise. This *ID* is used to identify the sensor in all other functions used later.
|
||||
|
||||
If you want to use a callback function to get the measurement results, it has to be defined like following.
|
||||
|
||||
```
|
||||
static void my_callback_function (uint32_t sensor,
|
||||
sht3x_value_set_t actual,
|
||||
sht3x_value_set_t average)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
You have to register this callback function using **_sht3x_set_callback_function_**.
|
||||
|
||||
```
|
||||
sht3x_set_callback_function (sensor, &my_callback_function);
|
||||
```
|
||||
|
||||
Optionally, you could set the measurement period using function **_sht3x_set_measurement_period_** or the weight (smoothing factor) for exponential moving average computation using function **_sht3x_set_average_weight_**.
|
||||
|
||||
```
|
||||
sht3x_set_measurement_period (sensor, 1000);
|
||||
sht3x_set_average_weight (sensor, 0.2);
|
||||
```
|
||||
|
||||
All functions return a boolean that allows effective error handling.
|
||||
|
||||
## Full Example
|
||||
|
||||
```
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
// include SHT3x driver
|
||||
|
||||
#include "sht3x/sht3x.h"
|
||||
|
||||
// define I2C interface at which SHTx3 sensor is connected
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN GPIO_ID_PIN((5))
|
||||
#define I2C_SDA_PIN GPIO_ID_PIN((4))
|
||||
|
||||
#define SHT3x_ADDR 0x45
|
||||
|
||||
static uint32_t sensor;
|
||||
|
||||
static void my_callback_function (uint32_t sensor,
|
||||
sht3x_value_set_t actual,
|
||||
sht3x_value_set_t average)
|
||||
{
|
||||
printf("%.3f Sensor %d: %.2f (%.2f) C, %.2f (%.2f) F, %.2f (%.2f) \n",
|
||||
(double)sdk_system_get_time()*1e-3, sensor,
|
||||
actual.temperature_c, average.temperature_c,
|
||||
actual.temperature_f, average.temperature_f,
|
||||
actual.humidity, average.humidity);
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Set UART Parameter
|
||||
uart_set_baud(0, 115200);
|
||||
|
||||
// Give the UART some time to settle
|
||||
sdk_os_delay_us(500);
|
||||
|
||||
// Init I2C bus interface at which SHT3x sensor is connected
|
||||
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K);
|
||||
|
||||
// Init SHT3x driver
|
||||
if (!sht3x_init())
|
||||
{
|
||||
// error message
|
||||
return;
|
||||
}
|
||||
|
||||
// Create sensors
|
||||
if ((sensor = sht3x_create_sensor (I2C_BUS, SHT3x_ADDR)) < 0)
|
||||
{
|
||||
// error message
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the callback function
|
||||
if (!sht3x_set_callback_function (sensor, &my_callback_function))
|
||||
{
|
||||
// error message
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
// Optional: Set the period of measurements (default 1000 ms)
|
||||
if (!sht3x_set_measurement_period (sensor, 1000))
|
||||
{
|
||||
// error message
|
||||
return;
|
||||
}
|
||||
|
||||
// Optional: Set the weight for exponential moving average (default 0.2)
|
||||
if (!sht3x_set_average_weight (sensor, 0.2))
|
||||
{
|
||||
// error message
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
// That's it.
|
||||
}
|
||||
```
|
||||
|
||||
## Further Examples
|
||||
|
||||
For further examples see [examples directory](../../examples/sht3x/README.md)
|
||||
|
||||
|
||||
|
||||
9
extras/sht3x/component.mk
Normal file
9
extras/sht3x/component.mk
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Component makefile for extras/sht3x
|
||||
|
||||
# expected anyone using SHT3x driver includes it as 'sht3x/sht3x.h'
|
||||
INC_DIRS += $(sht3x_ROOT)..
|
||||
|
||||
# args for passing into compile rule generation
|
||||
sht3x_SRC_DIR = $(sht3x_ROOT)
|
||||
|
||||
$(eval $(call component_compile_rules,sht3x))
|
||||
361
extras/sht3x/sht3x.c
Normal file
361
extras/sht3x/sht3x.c
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Driver for Sensirion SHT3x digital temperature and humity sensor
|
||||
* connected to I2C
|
||||
*
|
||||
* Part of esp-open-rtos
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "sht3x.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "espressif/sdk_private.h"
|
||||
|
||||
#define SHT3x_BG_TASK_PRIORITY 9
|
||||
|
||||
#define SHT3x_STATUS_CMD 0xF32D
|
||||
#define SHT3x_CLEAR_STATUS_CMD 0x3041
|
||||
#define SHT3x_RESET_CMD 0x30A2
|
||||
#define SHT3x_MEASURE_ONE_SHOT_CMD 0x2C06
|
||||
#define SHT3x_MEASURE_PERIODIC_1_CMD 0x2130
|
||||
#define SHT3x_MEASURE_PERIODIC_2_CMD 0x2236
|
||||
#define SHT3x_MEASURE_PERIODIC_4_CMD 0x2434
|
||||
#define SHT3x_MEASURE_PERIODIC_10_CMD 0x2737
|
||||
#define SHT3x_FETCH_DATA_CMD 0xE000
|
||||
|
||||
#ifdef SHT3x_DEBUG
|
||||
#define debug(s, ...) printf("%s: " s "\n", "SHT3x", ## __VA_ARGS__)
|
||||
#else
|
||||
#define debug(s, ...)
|
||||
#endif
|
||||
|
||||
|
||||
sht3x_sensor_t sht3x_sensors[SHT3x_MAX_SENSORS];
|
||||
|
||||
|
||||
static bool sht3x_send_command(uint32_t id, uint16_t cmd)
|
||||
{
|
||||
uint8_t data[2] = { cmd / 256, cmd % 256 };
|
||||
|
||||
debug("%s: Send MSB command byte %0x", __FUNCTION__, data[0]);
|
||||
debug("%s: Send LSB command byte %0x", __FUNCTION__, data[1]);
|
||||
|
||||
int error = i2c_slave_write(sht3x_sensors[id].bus, sht3x_sensors[id].addr, 0, data, 2);
|
||||
|
||||
if (error)
|
||||
{
|
||||
printf("%s: Error %d on write command %0x to i2c slave on bus %d with addr %0x.\n",
|
||||
__FUNCTION__, error, cmd, sht3x_sensors[id].bus, sht3x_sensors[id].addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool sht3x_read_data(uint32_t id, uint8_t *data, uint32_t len)
|
||||
{
|
||||
int error = i2c_slave_read(sht3x_sensors[id].bus, sht3x_sensors[id].addr, 0, data, len);
|
||||
|
||||
if (error)
|
||||
{
|
||||
printf("%s: Error %d on read %d byte from i2c slave on bus %d with addr %0x.\n",
|
||||
__FUNCTION__, error, len, sht3x_sensors[id].bus, sht3x_sensors[id].addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
# ifdef SHT3x_DEBUG
|
||||
printf("SHT3x: %s: Read following bytes: ", __FUNCTION__);
|
||||
for (int i=0; i < len; i++)
|
||||
printf("%0x ", data[i]);
|
||||
printf("\n");
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool sht3x_is_available (uint32_t sensor)
|
||||
{
|
||||
uint8_t data[3];
|
||||
|
||||
if (!sht3x_send_command(sensor, SHT3x_STATUS_CMD))
|
||||
{
|
||||
debug("Called from %s", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sht3x_read_data(sensor, data, 3))
|
||||
{
|
||||
debug("Called from %s", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool sht3x_valid_sensor (uint32_t sensor, const char* function)
|
||||
{
|
||||
if (sensor < 0 || sensor > SHT3x_MAX_SENSORS)
|
||||
{
|
||||
debug("%s: Wrong sensor id %d.", function, sensor);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sht3x_sensors[sensor].active)
|
||||
{
|
||||
debug("%s: Sensor with id %d is not active.", function, sensor);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void sht3x_compute_values (uint8_t id, uint8_t* data)
|
||||
{
|
||||
sht3x_value_set_t act;
|
||||
sht3x_value_set_t avg = sht3x_sensors[id].average;
|
||||
float w = sht3x_sensors[id].average_weight;
|
||||
|
||||
act.temperature_c = ((((data[0] * 256.0) + data[1]) * 175) / 65535.0) - 45;
|
||||
act.temperature_f = ((((data[0] * 256.0) + data[1]) * 347) / 65535.0) - 49;
|
||||
act.humidity = ((((data[3] * 256.0) + data[4]) * 100) / 65535.0);
|
||||
|
||||
if (sht3x_sensors[id].average_first_measurement || !sht3x_sensors[id].average_computation)
|
||||
{
|
||||
sht3x_sensors[id].average_first_measurement = false;
|
||||
|
||||
avg = act;
|
||||
}
|
||||
else
|
||||
{
|
||||
avg.temperature_c = w * act.temperature_c + (1-w) * avg.temperature_c;
|
||||
avg.temperature_f = w * act.temperature_f + (1-w) * avg.temperature_f;
|
||||
avg.humidity = w * act.humidity + (1-w) * avg.humidity;
|
||||
}
|
||||
|
||||
sht3x_sensors[id].actual = act;
|
||||
sht3x_sensors[id].average = avg;
|
||||
}
|
||||
|
||||
|
||||
static void sht3x_background_task (void *pvParameters)
|
||||
{
|
||||
uint8_t data[6];
|
||||
uint32_t sensor = (uint32_t)pvParameters;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// debug("%.3f Sensor %d: %s", (double)sdk_system_get_time()*1e-3, sensor, __FUNCTION__);
|
||||
|
||||
if (sht3x_valid_sensor(sensor, __FUNCTION__) &&
|
||||
sht3x_send_command(sensor, SHT3x_MEASURE_ONE_SHOT_CMD))
|
||||
{
|
||||
vTaskDelay (20 / portTICK_PERIOD_MS);
|
||||
|
||||
if (sht3x_read_data(sensor, data, 6))
|
||||
{
|
||||
sht3x_compute_values(sensor, data);
|
||||
|
||||
// debug("%.2f C, %.2f F, %.2f",
|
||||
// sht3x_sensors[sensor].actual.temperature_c,
|
||||
// sht3x_sensors[sensor].actual.temperature_f,
|
||||
// sht3x_sensors[sensor].actual.humidity);
|
||||
|
||||
if (sht3x_sensors[sensor].cb_function)
|
||||
sht3x_sensors[sensor].cb_function(sensor,
|
||||
sht3x_sensors[sensor].actual,
|
||||
sht3x_sensors[sensor].average);
|
||||
|
||||
}
|
||||
else
|
||||
debug("Called from %s", __FUNCTION__);
|
||||
|
||||
vTaskDelay((sht3x_sensors[sensor].period-20) / portTICK_PERIOD_MS);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug("Called from %s", __FUNCTION__);
|
||||
|
||||
vTaskDelay(sht3x_sensors[sensor].period / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool sht3x_init()
|
||||
{
|
||||
for (int id=0; id < SHT3x_MAX_SENSORS; id++)
|
||||
sht3x_sensors[id].active = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint32_t sht3x_create_sensor(uint8_t bus, uint8_t addr)
|
||||
{
|
||||
static uint32_t id;
|
||||
static char bg_task_name[20];
|
||||
|
||||
// search for first free sensor data structure
|
||||
for (id=0; id < SHT3x_MAX_SENSORS; id++)
|
||||
{
|
||||
debug("%s: id=%d active=%d", __FUNCTION__, id, sht3x_sensors[id].active);
|
||||
if (!sht3x_sensors[id].active)
|
||||
break;
|
||||
}
|
||||
debug("%s: id=%d", __FUNCTION__, id);
|
||||
|
||||
if (id == SHT3x_MAX_SENSORS)
|
||||
{
|
||||
debug("%s: No more sensor data structures available.", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// init sensor data structure
|
||||
sht3x_sensors[id].bus = bus;
|
||||
sht3x_sensors[id].addr = addr;
|
||||
sht3x_sensors[id].period = 1000;
|
||||
sht3x_sensors[id].average_computation = true;
|
||||
sht3x_sensors[id].average_first_measurement = true;
|
||||
sht3x_sensors[id].average_weight = 0.2;
|
||||
sht3x_sensors[id].cb_function = NULL;
|
||||
sht3x_sensors[id].bg_task = NULL;
|
||||
|
||||
// check whether sensor is available
|
||||
if (!sht3x_is_available(id))
|
||||
return -1;
|
||||
|
||||
// clear sensor status register
|
||||
if (!sht3x_send_command(id, SHT3x_CLEAR_STATUS_CMD))
|
||||
{
|
||||
debug("Called from %s", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf (bg_task_name, 20, "sht3x_bg_task_%d", id);
|
||||
|
||||
if (xTaskCreate (sht3x_background_task, bg_task_name, 256, (void*)id,
|
||||
SHT3x_BG_TASK_PRIORITY,
|
||||
&sht3x_sensors[id].bg_task) != pdPASS)
|
||||
{
|
||||
vTaskDelete(sht3x_sensors[id].bg_task);
|
||||
printf("%s: Could not create task %s\n", __FUNCTION__, bg_task_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
sht3x_sensors[id].active = true;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
bool sht3x_delete_sensor(uint32_t sensor)
|
||||
{
|
||||
if (!sht3x_valid_sensor(sensor, __FUNCTION__))
|
||||
return false;
|
||||
|
||||
sht3x_sensors[sensor].active = false;
|
||||
|
||||
if (sht3x_sensors[sensor].bg_task)
|
||||
vTaskDelete(sht3x_sensors[sensor].bg_task);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool sht3x_set_measurement_period (uint32_t sensor, uint32_t period)
|
||||
{
|
||||
if (!sht3x_valid_sensor(sensor, __FUNCTION__))
|
||||
return false;
|
||||
|
||||
if (period < 20)
|
||||
debug("%s: Period of %d ms is less than the minimum period of 20 ms for sensor with id %d.", __FUNCTION__, period, sensor);
|
||||
|
||||
sht3x_sensors[sensor].period = period;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool sht3x_set_callback_function (uint32_t sensor, sht3x_cb_function_t user_function)
|
||||
{
|
||||
if (!sht3x_valid_sensor(sensor, __FUNCTION__))
|
||||
return false;
|
||||
|
||||
sht3x_sensors[sensor].cb_function = user_function;
|
||||
|
||||
debug("%s: Set callback mode done.", __FUNCTION__);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool sht3x_get_values(uint32_t sensor, sht3x_value_set_t *actual, sht3x_value_set_t *average)
|
||||
{
|
||||
if (!sht3x_valid_sensor(sensor, __FUNCTION__))
|
||||
return false;
|
||||
|
||||
if (actual) *actual = sht3x_sensors[sensor].actual;
|
||||
if (average) *average = sht3x_sensors[sensor].average;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool sht3x_enable_average_computation (uint32_t sensor, bool enabled)
|
||||
{
|
||||
sht3x_sensors[sensor].average_computation = enabled;
|
||||
sht3x_sensors[sensor].average_first_measurement = enabled;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool sht3x_set_average_weight (uint32_t sensor, float weight)
|
||||
{
|
||||
sht3x_sensors[sensor].average_first_measurement = true;
|
||||
sht3x_sensors[sensor].average_weight = weight;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
258
extras/sht3x/sht3x.h
Normal file
258
extras/sht3x/sht3x.h
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver for Sensirion SHT3x digital temperature and humity sensor
|
||||
* connected to I2C
|
||||
*
|
||||
* Part of esp-open-rtos
|
||||
*/
|
||||
|
||||
#ifndef DRIVER_SHT3x_H_
|
||||
#define DRIVER_SHT3x_H_
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#include "i2c/i2c.h"
|
||||
|
||||
// Uncomment to enable debug output
|
||||
// #define SHT3x_DEBUG
|
||||
|
||||
// Change this if you need more than 3 SHT3x sensors
|
||||
#define SHT3x_MAX_SENSORS 3
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief actual or average value set type
|
||||
*/
|
||||
typedef struct {
|
||||
float temperature_c; // temperature in degree Celcius
|
||||
float temperature_f; // temperature in degree Fahrenheit
|
||||
float humidity; // humidity in percent
|
||||
} sht3x_value_set_t;
|
||||
|
||||
/**
|
||||
* @brief callback unction type to pass result of measurement to user tasks
|
||||
*/
|
||||
typedef void (*sht3x_cb_function_t)(uint32_t sensor,
|
||||
sht3x_value_set_t actual,
|
||||
sht3x_value_set_t average);
|
||||
|
||||
/**
|
||||
* @brief SHT3x sensor device data structure type
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
bool active;
|
||||
|
||||
uint8_t bus;
|
||||
uint8_t addr;
|
||||
|
||||
uint32_t period;
|
||||
|
||||
sht3x_value_set_t actual;
|
||||
sht3x_value_set_t average;
|
||||
|
||||
bool average_computation;
|
||||
bool average_first_measurement;
|
||||
float average_weight;
|
||||
|
||||
sht3x_cb_function_t cb_function;
|
||||
TaskHandle_t bg_task;
|
||||
|
||||
} sht3x_sensor_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize the SHT3x 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 sht3x_init ();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize a SHT3x sensor
|
||||
*
|
||||
* This function initializes the SHT3x sensor connected to a certain
|
||||
* bus with given slave address and checks its availability.
|
||||
*
|
||||
* Furthermore, it starts a background task for measurements with
|
||||
* the sensor. The background task carries out the measurements periodically
|
||||
* using SHT3x'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
|
||||
* *sht3x_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 *sht3x_set_average_weight*.
|
||||
*
|
||||
* If a callback method has been registered with function
|
||||
* *sht3x_set_callback_function*, it is called after each measurement
|
||||
* to pass measurement results to user tasks. Otherwise, user tasks have to
|
||||
* use function *sht3x_get_values* explicitly to get the results.
|
||||
*
|
||||
* @param bus I2C bus at which SHT3x sensor is connected
|
||||
* @param addr I2C addr of the SHT3x sensor
|
||||
*
|
||||
* @return ID of the sensor (0 or greater on success or -1 on error)
|
||||
*/
|
||||
uint32_t sht3x_create_sensor (uint8_t bus, uint8_t addr);
|
||||
|
||||
|
||||
/**
|
||||
* @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 sht3x_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 sht3x_set_callback_function (uint32_t sensor,
|
||||
sht3x_cb_function_t user_function);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Deletes the SHT3x sensor given by its ID
|
||||
*
|
||||
* @param sensor ID of the sensor
|
||||
*
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool sht3x_delete_sensor (uint32_t sensor);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get 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 *sht3x_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 sht3x_get_values (uint32_t sensor,
|
||||
sht3x_value_set_t *actual,
|
||||
sht3x_value_set_t *average);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable (default) or disable average value computation
|
||||
*
|
||||
* In case, the average value computation is disabled, average sensor values
|
||||
* correspond to the actual sensor values.
|
||||
*
|
||||
* @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 sht3x_enable_average_computation (uint32_t sensor, bool enabled);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set 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 sht3x_set_average_weight (uint32_t sensor, float weight);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DRIVER_SHT3x_H_ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue