[ WiFi 智能家居项目 ] [ 14 ] WiFi 智能环境采集

简介

使用 DHT11 采集室内温湿度,其内置一个电阻式湿敏元件和一个 NTC 测温元件,内部的单片机完成温湿度信号的采集与处理,并通过单总线与外部应用系统进行通信。

通信协议

单总线即只有一条数据线,由它完成 DHT11 与外部应用系统的控制和数据交换。因为该单总线是漏极开路输出的三态端口,所以通常需要外接一个约 5.1KΩ 的上拉电阻,当总线闲置时,其状态为高电平

单总线传输数据位定义

一次完整的数据传输为40bit,高位先出

  • 8bit湿度整数数据+8bit湿度小数数据
  • 8bit温度整数数据+8bit温度小数数据
  • 8bit校验和,即前面 4 个字节数据之和的低 8 位


通信协议

1. 主机 -> DHT11。 起始信号为低电平,且持续时间必须大于 18ms。

image.png

        // ESP8266 发送起始信号,起始信号为低电平
        // 拉低18ms
        GPIO_OUTPUT_SET(DHT11_PIN_NUM,DHT11_RESET);
        os_delay_us(18*1000);
        GPIO_OUTPUT_SET(DHT11_PIN_NUM,DHT11_SET);
        // 延迟 40us 等待 DHT11 响应
        // 拉高40us
        GPIO_AS_INPUT(DHT11_PIN_BIT);
        os_delay_us(4*10);

2. DHT11 -> 主机。 DHT11 的 DATA 引脚接收到主机发来的起始信号后,等待起始信号结束,然后输出 80 us 低电平信号作为相应,之后再输出 80us 高电平通知主机准备接收数据。

image.png

    //等待拉低80us应答
    if(!GPIO_INPUT_GET(DHT11_PIN_NUM)) 
    {
        //等待拉高应答
        ucharFLAG=2; 
        while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
        ucharFLAG=2;

3. DHT 11 -> 主机。 主机收到 DHT11 的响应信号后,根据 DATA 引脚电平的变化,接收 40 位数据。位数据 “0” “1” 的信号格式如下:

image.png

(左边为“0”,右边为“1”)通过高低电平的时间间隔,来判断是“0”或“1”。

        //等待拉低传输数据
        while(GPIO_INPUT_GET(DHT11_PIN_NUM)&&ucharFLAG++); 
        for(i=0;i<8;i++)    
        {
            //等待拉高
            ucharFLAG=2; 
            while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
            //延时30us
            os_delay_us(3*10);
            //赋值当前bit为0
            uchartemp=0;
            //如果继续为高,则赋值为bit为1
            if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
            //判断是否超时
            ucharFLAG=2;
            while(GPIO_INPUT_GET(DHT11_PIN_NUM)&&ucharFLAG++); 
            //超时退出
            if(ucharFLAG==1)break;    
            //左移1位。进行赋值
            ucharcomdata<<=1;
            ucharcomdata|=uchartemp; 
        }
        ucharRH_data_H_humidity = ucharcomdata;

通过校验位,判断接收数据是否正确:

    uchartemp=(ucharT_data_H_temp+ucharT_data_L_temp+ucharRH_data_H_humidity+ucharRH_data_L_humidity);
             
    if(uchartemp==ucharcheckdata_temp)
    {          
        ucharT_data_H  = ucharT_data_H_temp;
        ucharT_data_L  = ucharT_data_L_temp;
        ucharRH_data_H = ucharRH_data_H_humidity;
        ucharRH_data_L = ucharRH_data_L_humidity;
        ucharcheckdata = ucharcheckdata_temp;                    
    } 
    else //没用成功读取,返回0
    {
        ucharT_data_H  = 0;
        ucharT_data_L  = 0;
        ucharRH_data_H = 0;
        ucharRH_data_L = 0; 
    } 

在等待 DH11 低电平响应信号或等待 DH11 低电平响应信号结束时,应该考虑器件或线路故障造成通讯的死循环。比如,如果 DHT11 未与电路连接,在程序等待 DHT11 低电平响应信号时,由于上拉电阻的作用,DATA 线会一直是高电平,所以必须有超时判断,以避免死机。

4. DHT11 的 DATA 引脚输出 40 位数据后,继续输出 50us 低电平后转为输入状态,由于上拉电阻的存在,DATA 引脚变为高电平。

两次读取数据的时间间隔至少为 5s。

5. 等待下一个起始信号到来。

代码

见“通信协议”。

参考

[1]梁桃华,周江,肖冠南.基于DHT11的温湿度计的设计与实现[J].电子制作,2024,32(15):88-90.DOI:10.16589/j.cnki.cn11-3571/tn.2024.15.026.