【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连接正常
最终的结果如下:









