本文主要是介绍【ESP-IDF5.x】 ESP32/ESP8266驱动SHT3x温湿度传感器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
更多更新的文章详见我的个人博客:【前往】
环境
- 软件环境
- VScode
- ESP-IDF5.x
- 硬件环境
- esp32 / esp8266
- sht3x温湿度传感器
SHT3x周围电路连接如下
下面是SHT3x与ESP32-S3的引脚接线示例,ESP32或者ESP8266根据开发板的I2C引脚进行接线
引脚 | 接线 |
---|---|
VDD | 3.3/5V |
ADDR | GND |
SDA | 4 |
SCL | 5 |
说明
代码示例见:https://github.com/MGod-monkey/sht3x-esp-idf5x
将上面的代码下载到本地并通过VScode打开,需要先选择自己芯片的平台,然后编译
驱动sht3x的代码封装在components\sht3x\sht3x.h
,每个函数的说明如下:
-
sht3x_init_sensor
- 初始化一个 SHT3x 传感器。
- 创建一个描述传感器的数据结构并初始化传感器设备。
- 参数:
bus
: 传感器连接的 I2C 总线。addr
: 传感器的 I2C 从设备地址。
- 返回值:指向传感器数据结构的指针,初始化失败时返回 NULL。
-
sht3x_measure
- 高级测量函数,执行一次测量。
- 包含三个步骤:
- 以高可靠性启动一次单次测量。
- 使用
vTaskDelay
等待测量结果可用。 - 返回浮点类型的传感器测量值。
- 参数:
dev
: 指向传感器设备数据结构的指针。temperature
: 返回的温度值(摄氏度)。humidity
: 返回的湿度值(百分比)。
- 返回值:成功时返回
true
,失败时返回false
。
-
sht3x_start_measurement
- 启动单次测量或周期性测量。
- 可以选择单次测量模式或周期性测量模式,以及设置测量的重复性。
- 参数:
dev
: 指向传感器设备数据结构的指针。mode
: 测量模式(单次或周期性),参见sht3x_mode_t
类型。repeat
: 测量的重复性,参见sht3x_repeat_t
类型。
- 返回值:成功时返回
true
,失败时返回false
。
-
sht3x_get_measurement_duration
- 获取测量所需的 RTOS tick 数。
- 返回给定重复性下执行一次测量所需的时间。
- 用户任务可以直接使用此函数返回的持续时间来等待测量结果。
- 参数:
repeat
: 测量的重复性,参见sht3x_repeat_t
类型。
- 返回值:测量持续时间,单位为 RTOS ticks。
-
sht3x_get_raw_data
- 从传感器读取测量结果并存储为原始数据。
- 读取温度和压力的测量结果,检查 CRC 校验码并存储在字节数组中。
- 参数:
dev
: 指向传感器设备数据结构的指针。raw_data
: 存储原始数据的字节数组。
- 返回值:成功时返回
true
,失败时返回false
。
-
sht3x_compute_values
- 从原始数据计算出传感器的温度和湿度值。
- 参数:
raw_data
: 包含原始数据的字节数组。temperature
: 返回的温度值(摄氏度)。humidity
: 返回的湿度值(百分比)。
- 返回值:成功时返回
true
,失败时返回false
。
-
sht3x_get_results
- 获取传感器测量结果并返回传感器值。
- 该函数结合了
sht3x_read_raw_data
和sht3x_compute_values
函数,读取原始数据并计算出传感器的温度和湿度值。 - 参数:
dev
: 指向传感器设备数据结构的指针。temperature
: 返回的温度值(摄氏度)。humidity
: 返回的湿度值(百分比)。
- 返回值:成功时返回
true
,失败时返回false
。
获取SHT3x温湿度传感器的示例代码如下:
-
测量模式选择:SINGLE_SHOT_HIGH_LEVEL、SINGLE_SHOT_LOW_LEVEL或周期模式
// #define SINGLE_SHOT_LOW_LEVEL // #define SINGLE_SHOT_HIGH_LEVEL#if defined(SINGLE_SHOT_HIGH_LEVEL) void user_task (void *pvParameters) {float temperature;float humidity;TickType_t last_wakeup = xTaskGetTickCount();while (1) {// perform one measurement and do something with the resultsif (sht3x_measure (sensor, &temperature, &humidity))printf("%.3f SHT3x Sensor: %.2f °C, %.2f %%\n", (double)sdk_system_get_time()*1e-3, temperature, humidity);// wait until 5 seconds are overvTaskDelayUntil(&last_wakeup, 5000 / portTICK_PERIOD_MS);} } #elif defined(SINGLE_SHOT_LOW_LEVEL) void user_task (void *pvParameters) {float temperature;float humidity;TickType_t last_wakeup = xTaskGetTickCount();// get the measurement duration for high repeatability;uint8_t duration = sht3x_get_measurement_duration(sht3x_high);while (1) {// Trigger one measurement in single shot mode with high repeatability.sht3x_start_measurement (sensor, sht3x_single_shot, sht3x_high);// Wait until measurement is ready (constant time of at least 30 ms// or the duration returned from *sht3x_get_measurement_duration*).vTaskDelay (duration);// retrieve the values and do something with themif (sht3x_get_results (sensor, &temperature, &humidity))printf("%.3f SHT3x Sensor: %.2f °C, %.2f %%\n", (double)sdk_system_get_time()*1e-3, temperature, humidity);// wait until 5 seconds are overvTaskDelayUntil(&last_wakeup, 5000 / portTICK_PERIOD_MS);} } #else // PERIODIC MODE void user_task (void *pvParameters) {float temperature;float humidity;// Start periodic measurements with 1 measurement per second.sht3x_start_measurement (sensor, sht3x_periodic_1mps, sht3x_high);// Wait until first measurement is ready (constant time of at least 30 ms// or the duration returned from *sht3x_get_measurement_duration*).vTaskDelay (sht3x_get_measurement_duration(sht3x_high));TickType_t last_wakeup = xTaskGetTickCount();while (1) {// Get the values and do something with them.if (sht3x_get_results (sensor, &temperature, &humidity))printf("%.3f SHT3x Sensor: %.2f °C, %.2f %%\n", (double)sdk_system_get_time()*1e-3, temperature, humidity);// Wait until 2 seconds (cycle time) are over.vTaskDelayUntil(&last_wakeup, 2000 / portTICK_PERIOD_MS);} } #endif
-
单次测量模式
-
在单次测量模式下,一条测量命令会触发精确采集一个数据对。每个数据对包括 16 位十进制的温度和湿度值。由于测量持续时间长达 15 毫秒,因此测量过程被分成多个步骤,以避免在测量过程中阻塞用户任务:
-
使用函数 sht3x_start_measurement 触发传感器,执行一次测量。
-
使用函数 vTaskDelay 等待测量持续时间,直到获得测量结果。使用至少 30 毫秒的恒定持续时间或函数 sht3x_get_measurement_duration 返回的以 RTOS ticks 为单位的持续时间进行等待。
-
使用函数 sht3x_get_results 或函数 sht3x_get_raw_data 获取浮点传感器值或原始数据。
-
-
在单次模式下,每次需要新的传感器值时,用户任务都必须执行所有步骤。
-
为方便起见,一个高级函数 sht3x_measure(sht3x_measure)只需一个函数即可完成上述三个步骤的测量。该函数是使用传感器的最简单方法。它最适合不想控制传感器细节的用户。
这种模式的优点是,传感器可以在连续测量之间切换到睡眠模式,从而更加节能。当测量速率小于每秒1次测量时,这种模式尤其有用。-
周期模式
-
在这种模式下,发出的一条测量命令会产生一个数据对流。每个数据对由 16 位十进制的温度和湿度值组成。测量命令一经发送至传感器,传感器就会自动以每秒 0.5、1、2、4 或 10 次的测量速率定期执行测量。数据对可以以相同或更低的速率获取。与单次测量模式一样,测量过程分为以下几个步骤:
-
使用函数 sht3x_start_measurement,以给定的速率触发传感器,开始周期性测量。
-
使用函数 vTaskDelay 等待测量持续时间,直到获得第一个结果。使用至少 30 毫秒的恒定持续时间或函数 sht3x_get_measurement_duration 返回的以 RTOS ticks 为单位的持续时间进行等待。
-
-
-
使用函数 sht3x_get_results 或函数 sht3x_get_raw_data 获取浮点传感器值或原始数据。
与单次测量模式不同的是,步骤1和2只需执行一次。一旦开始测量,用户任务只需定期获取数据即可,但传感器在整个过程中一直保持活跃状态,因此能耗较高
注:获取测量结果的速率不得大于传感器的周期性测量速率。为避免因传感器的定时容差造成冲突,应小于该速率。
-
初试化I2C并读取SHT3x温湿度的值
注:如果SHT3x的ADDR引脚接的不是GND,而是VCC,则需要将地址改为SHT3x_ADDR_2
#define I2C_MASTER_SCL_IO GPIO_NUM_5 /*!< GPIO number used for I2C master clock */ #define I2C_MASTER_SDA_IO GPIO_NUM_4 /*!< GPIO number used for I2C master data */ #define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */ #define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */ #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define I2C_MASTER_TIMEOUT_MS 1000 /*!< I2C master timeout in milliseconds */void app_main(void) {// Set UART Parameter.uart_set_baud(0, 115200);// Give the UART some time to settlevTaskDelay(1);// Init I2C bus interfaces at which SHT3x sensors are connectedint i2c_master_port = I2C_MASTER_NUM;i2c_config_t conf = {.mode = I2C_MODE_MASTER,.sda_io_num = I2C_MASTER_SDA_IO,.scl_io_num = I2C_MASTER_SCL_IO,.sda_pullup_en = GPIO_PULLUP_ENABLE,.scl_pullup_en = GPIO_PULLUP_ENABLE,.master.clk_speed = I2C_MASTER_FREQ_HZ,};i2c_param_config(i2c_master_port, &conf);i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);// Create the sensors, multiple sensors are possible.if ((sensor = sht3x_init_sensor(I2C_MASTER_NUM, SHT3x_ADDR_1))){// Create a user task that uses the sensors.xTaskCreate(user_task, "user_task", TASK_STACK_DEPTH, NULL, 2, 0);}elseprintf("Could not initialize SHT3x sensor\n"); }
如果串口输出的结果为Could not initialize SHT3x sensor
,可以通过下面的程序来扫描I2C设备来确保SHT3x是否连接正常
#include "driver/i2c.h"
#include <stdio.h>#define I2C_MASTER_SCL_IO GPIO_NUM_5 /*!< GPIO number used for I2C master clock */
#define I2C_MASTER_SDA_IO GPIO_NUM_4 /*!< GPIO number used for I2C master data */
#define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_TIMEOUT_MS 1000 /*!< I2C master timeout in milliseconds */void i2c_scanner()
{i2c_config_t conf = {.mode = I2C_MODE_MASTER,.sda_io_num = I2C_MASTER_SDA_IO,.scl_io_num = I2C_MASTER_SCL_IO,.sda_pullup_en = GPIO_PULLUP_ENABLE,.scl_pullup_en = GPIO_PULLUP_ENABLE,.master.clk_speed = I2C_MASTER_FREQ_HZ,};i2c_param_config(I2C_MASTER_NUM, &conf);i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);printf("I2C scanner. Scanning...\n");for (int address = 1; address < 127; address++) {i2c_cmd_handle_t cmd = i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, true);i2c_master_stop(cmd);esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);i2c_cmd_link_delete(cmd);if (ret == ESP_OK) {printf("I2C device found at address 0x%02x\n", address);}}printf("Scan completed.\n");
}void app_main(void)
{i2c_scanner();
}
输出结果中I2C地址有0x44或者0x45则说明SHT3x连接正常
最终的结果如下:
这篇关于【ESP-IDF5.x】 ESP32/ESP8266驱动SHT3x温湿度传感器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!