ESP32驱动DHT11温湿度传感器详解
一、DHT11介绍
DHT11 是一款常用的数字温湿度传感器,适合于需要测量温度和湿度的基本应用场景。其测量范围为湿度为5%到95%RH,温度范围为-20℃到60℃,湿度测量精度为±5%RH,温度测量精度为±2℃,采用单总线通信协议,通过一个数据引脚完成输入输出双向传输。
DHT11 传感器有4个管脚,其中有一个管脚不用接,另外就是VCC,SIG,GND,可能大家自行买的DHT11是带了转接板的,因此需要仔细确认管脚顺序,DHT11硬件连接简单,与MCU 连接如下所示,只需要在信号脚上接一个5K的上拉电阻即可。供电范围是3-5.5V,超过这个范围可能会烧毁。
DHT11 的通信包数据长度为40个字节。组成如下:8bit湿度整数数据+8bit湿度小数数据+8bit 温度整数数据+8bit温度小数数据+8bit校验和,湿度小数数据是0不用关注,数据传输格式为高位在前,低位在后,校验和是前4个字节相加。对于DHT11的数据传输时序非常严格,并非是低电平为0,高电平为1,和上一课WS2812类似,对于逻辑0和逻辑1, 均是通过不同时间的高电平占比来表示的。具体时序逻辑如下图
大致流程就是,主机发起开始信号(>18ms的低电平),拉高40us等待。然后DHT11会拉低80us表示响应信号,然后拉高80us表示开始传输数据。每一位数据前都有50us的低电平,紧接着如果是数据0,高电平持续时间大概在23-27us,如果是数据1,高电平大概是68us-74us,全部数据传输完成后,DHT11拉低50us,表示传输完毕,然后主机拉高表示通信结束。通过梳理这些时序,我们发现使用ESP32的RMT模块是可以拿来驱动DHT11的,不过这次我们要用到的是RMT模块的接收。具体代码请看下节。
二、ESP32驱动DHT11
在本次学习的开发板上,DHT11的信号脚是接到GPIO25上,大家也可以接到其他GPIO上,不过要改一下代码中的GPIO脚号。代码在esp32-board/dht11中,我们先来分析几个关键函数。
初始化中,首先是需要定义rmt_rx_channel_config_t内容,大致就是选择时钟源、时钟分辨率、底层内存块大小(一般设置为64)、GPIO编号等内容,时钟频率这里设定为1M,刚好是1us,因此低于1us的脉冲无法分辨。而DHT11时序中没有低于10us的脉冲,因此绰绰有余。
然后创建一个接收队列,在main函数主循环中实时接收数据。队列数据内容是rmt_rx_done_event_data_t,里面包含了RMT数据(RMT符号)信息。
另外一个重要的点是设置RMT接收完成回调函数,当ESP32检测到RMT接收完成后,就会调用这个接收函数,通知我们数据接收完毕,我们看一下这个回调函数的实现。
回调函数中edata参数包含了RMT数据信息,我们把这个参数发到刚才创建的队列中,然后就返回了,xQueueSendFromISR是xQueueSend的中断函数版本,只能在中断函数中调用。
然后看一下,我们是如何获取DHT11数据的,请看如下代码
前面的启动时序代码就不做过多说明了,大家对照着时序图和注释看就行,有几个点需要说明一下,rmt_receive_config_t这个结构体定义了两种脉冲,第一种是最小脉冲信号,低于这个脉冲宽度,RMT模块认为是干扰信号,第二种是最大脉宽,大于此脉宽的视为RMT接收结束信号,在这里分别设置1us以及200us。
调用rmt_receive函数,把过滤脉冲配置、接收的RMT符号缓存传入,在底层即开始接收到,然后我们从队列中接收从回调函数发来的数据即可。
parse_items函数是解析RMT符号,把它转化为我们程序中可以识别的数据。接下来看下这个函数的实现
点击链接ESP32驱动DHT11温湿度传感器详解阅读原文