【ESP-IDF5.x】 ESP32/ESP8266驱动SHT3x温湿度传感器
【ESP-IDF5.x】 ESP32/ESP8266驱动SHT3x温湿度传感器
MGodmonkey环境
- 软件环境
- VScode
- ESP-IDF5.x
- 硬件环境
- esp32 / esp8266
- sht3x温湿度传感器
SHT3x周围电路连接如下
下面是SHT3x与ESP32-S3的引脚接线示例,ESP32或者ESP8266根据开发板的I2C引脚进行接线
引脚 | 接线 |
---|---|
VDD | 3.3/5V |
ADDR | GND |
SDA | 4 |
SCL | 5 |
说明
将上面的代码下载到本地并通过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或周期模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77// #define SINGLE_SHOT_LOW_LEVEL
// #define 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 results
if (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 over
vTaskDelayUntil(&last_wakeup, 5000 / portTICK_PERIOD_MS);
}
}
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 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 5 seconds are over
vTaskDelayUntil(&last_wakeup, 5000 / portTICK_PERIOD_MS);
}
}
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);
}
}-
单次测量模式
-
在单次测量模式下,一条测量命令会触发精确采集一个数据对。每个数据对包括 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
void app_main(void)
{
// Set UART Parameter.
uart_set_baud(0, 115200);
// Give the UART some time to settle
vTaskDelay(1);
// Init I2C bus interfaces at which SHT3x sensors are connected
int 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);
}
else
printf("Could not initialize SHT3x sensor\n");
}
如果串口输出的结果为Could not initialize SHT3x sensor
,可以通过下面的程序来扫描I2C设备来确保SHT3x是否连接正常
1 |
|
输出结果中I2C地址有0x44或者0x45则说明SHT3x连接正常
最终的结果如下: