温湿度传感器DHT11的简单应用


一、DHT11是什么?

DHT11是一种温湿度传感器模块,用于测量环境的温度和湿度。它采用数字信号输出,使用单总线通信协议,具有低成本、简单易用的特点。

DHT11传感器由一个温度传感器和一个湿度传感器组成,内部集成了模拟信号读取、数字信号处理和校准等功能。传感器通过测量热敏电阻来获取环境温度,并通过测量湿度敏感电阻来获取环境湿度。它将温度和湿度转换为数字信号,通过单总线通信协议将数据传输给主控设备。

DHT11传感器模块的工作电压通常为3.3V或5V,可以与各类微控制器(如Arduino、Raspberry Pi等)进行连接和交互。通过简单的代码和接线,你可以读取DHT11传感器提供的温度和湿度数值,从而监测和控制环境的温湿度。

需要注意的是,DHT11相对于其他高精度传感器而言,其精度较低,温湿度测量的范围和精确度也相对有限,见下面参数表。

在这里插入图片描述
相关重要参数如下:

参数规格
工作电压3.3V-5.5V
外形尺寸23.2(L)mm ×12.5(W)mm
测量范围温度:-20~+60℃ 湿度:5~95%RH
精度温度:±2℃ 湿度:±5%RH (25℃)
分辨率温度:0.1℃ 湿度:1%RH
衰减值温度:<0.1℃/年 湿度:<1%RH/年
输出信号单总线数字信号
外壳材料ABS塑料
重量1g
引脚数3/4(有一个空脚)

二、使用步骤

1.硬件

1.1 硬件连接

硬件相对比较简单,DHT11的数据接单片机IO口即可。这里我用的是主控STM32F103C8的PA4.

/* Defines ------------------------------------------------------------------*/
#define DHT11_GPIO_RCC  RCC_APB2Periph_GPIOA
#define DHT11_GPIO_Port GPIOA
#define DHT11_Pin       GPIO_Pin_4//根据实际的引脚修改

1.2 工作原理

1.2.1 串行单总线

串行单总线是一种通信协议,它允许多个设备通过共享同一条数据线进行通信。在这种协议中,每个设备都有一个唯一的地址,主控设备可以通过这个地址来选择特定的设备进行通信。这种通信方式可以减少连接线的数量,降低成本,并简化系统设计。

DHT11之所以采用串行单总线通信,主要是出于简单、成本低廉和易用性的考虑。采用串行单总线通信可以大大简化DHT11模块与主控设备(比如微控制器)的连接,只需要一根数据线即可完成通信,从而降低了连接复杂性和成本。此外,串行单总线通信也使得多个传感器可以共享同一条数据线,方便在系统中同时使用多个传感器模块。

1.2.2 温湿度数据采集原理

1.DHT11传输的40位数据包括湿度整数数据、湿度小数数据、温度整数数据、温度小数数据和校验位。这些数据的传输顺序是高位先出的,也就是从最高位开始传输到最低位。

8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位

2.每个数据位的传输格式如下:

位数据“0”:先发送一个持续时间为54微秒的低电平信号,然后是一个持续时间在23至27微秒之间的高电平信号。
位数据“1”:先发送一个持续时间为54微秒的低电平信号,然后是一个持续时间在68至74微秒之间的高电平信号。

3.此外,校验位的计算方式是将湿度整数数据、湿度小数数据、温度整数数据和温度小数数据相加,得到的结果应与传输的校验位数据相等。

8bit校验位=8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据

2.软件

2.1 DHT11初始化如下(示例):


/*******************************************************************************
 * 函数名:DHT11_Init
 * 描述  :DHT11初始化
 * 输入  :void
 * 输出  :uint8_t
 * 调用  :
 * 备注  :返回0:存在  返回1:未检测到DHT11的存在
 *******************************************************************************/
uint8_t DHT11_Init(void)
{	
	delay_syms(1000);//在上电后到对DHT11初始化前应有1s的稳定期,等待传感器稳定。可以在单片机上电后采用1s延时处理。	
	DHT11_RST();//DHT11端口复位,发出起始信号
	return DHT11_Check();//等待DHT11回应
}

2.2 DHT11复位如下(示例):

/*******************************************************************************
 * 函数名:DHT11_RST
 * 描述  :DHT11复位
 * 输入  :void
 * 输出  :uint8_t
 * 调用  :
 * 备注  :DHT11开始信号
 *******************************************************************************/
void DHT11_RST(void)
{
    DHT11_IO_OUT();//端口为输出	
	DHT11_IO_LOW();//使总线为低电平
	delay_syms(25);//拉低至少18ms
	DHT11_IO_HIGH();//使总线为高电平	
	Delay_20us();//主机拉高20~40us
}

2.3 等待DHT11的回应如下(示例):

/*******************************************************************************
 * 函数名:DHT11_Check
 * 描述  :等待DHT11的回应
 * 输入  :void
 * 输出  :uint8_t
 * 调用  :
 * 备注  :返回0:存在  返回1:未检测到DHT11的存在
 *******************************************************************************/
uint8_t DHT11_Check(void) 	   
{   
	uint8_t retry = 0;
	DHT11_IO_IN(); 
    while((DHT11_IO_Read()) && retry < 100)//DHT11会拉低40~80us
	{
		retry++;
		Delay_2us();
	};	 
	if(retry >= 100) return 1;
	else retry = 0;
    while ((!DHT11_IO_Read()) && retry < 100)//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		Delay_2us();
	};
	if(retry >= 100) return 1;	    
	return 0;
}

2.4 检测DHT11是否正常代码如下(示例):

/*******************************************************************************
 * 函数名:DHT11_Detection
 * 描述  :检测DHT11是否正常
 * 输入  :void
 * 输出  :uint8_t
 * 调用  :
 * 备注  :返回0:存在  返回1:未检测到DHT11的存在
 *******************************************************************************/
void DHT11_Detection(void)
{
    if(DHT11_Init() == 0)
	{
		DHT11_flag = 1;
		printf("DHT11 OK\r\n");	
	}
    else
	{	
		DHT11_flag = 0;
		printf("DHT11 Fail\r\n");				
	}			
}

2.5 DHT11读取一个字节代码如下(示例):

/*******************************************************************************
 * 函数名:DHT11_Read_Byte
 * 描述  :DHT11读取一个字节
 * 输入  :void
 * 输出  :uint8_t
 * 调用  :
 * 备注  :返回值:读到的数据
 *******************************************************************************/
uint8_t DHT11_Read_Byte(void)
{
    uint8_t i, dat;
    dat = 0x00;
    for (i = 0; i < 8; i++)
    {
        dat <<= 1;//左移运算符,dat左移1位
        dat |= DHT11_Read_Bit();
    }
    return dat;
}

2.6 DHT11读取一个位数据代码如下(示例):

/*******************************************************************************
 * 函数名:DHT11_Read_Bit
 * 描述  :DHT11读取数据  读取一个位
 * 输入  :void
 * 输出  :uint8_t
 * 调用  :
 * 备注  :返回0/1
 *******************************************************************************/
uint8_t DHT11_Read_Bit(void)
{
    uint8_t retry = 0;
    while((DHT11_IO_Read() == 1) && retry < 100) //等待变为低电平
    {
        retry++;
		Delay_2us();
    }
    while((DHT11_IO_Read() == 0) && retry < 100) //等待变高电平
    {
        retry++;
		Delay_2us();
    }	
	Delay_20us();
	Delay_20us();		
    if(DHT11_IO_Read() == 1) //用于判断高低电平,即数据1或0
    {
        return 1;
	}
    else
    {
       return 0;
	}
}

2.7 DHT11读取温湿度数据代码如下(示例):

/*******************************************************************************
 * 函数名:DHT11_Read_Data
 * 描述  :DHT11读取一次数据
 * 输入  :temp:温度值(范围:0~50°)
           humi:湿度值(范围:20%~90%)
 * 输出  :uint8_t
 * 调用  :
 * 备注  :返回值:0,正常;1,读取失败
 *******************************************************************************/
uint8_t DHT11_Read_Data(uint8_t *temphigh, uint8_t *templow, uint8_t *humi)
{
    uint8_t buf[5];
    uint8_t i;
    DHT11_RST();//DHT11端口复位,发出起始信号
    if(DHT11_Check() == 0)//等待DHT11回应,0为成功回应
    {
        for(i = 0; i < 5; i++) //读取40位数据
        {
            buf[i] = DHT11_Read_Byte();//读出数据
        }
        if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])	//数据校验
        {
            *humi = buf[0];//将湿度整数值放入指针humi
            *temphigh = buf[2];//将温度整数值放入指针temphigh
            *templow = buf[3];//将温度小数值放入指针templow					
        }
    }
    else return 1;
    return 0;
}

2.8 DHT11采集温湿度数据代码如下(示例):

/*******************************************************************************
 * 函数名:DHT11_Collect_data
 * 描述  :DHT11采集温湿度数据
 * 输入  :void
 * 输出  :void
 * 调用  :1s
 * 备注  :
 *******************************************************************************/
void DHT11_Collect_data(void)
{
    uint8_t humidity = 0;
    uint8_t tempe_high = 0;	
    uint8_t tempe_low = 0;		
	if(DHT11_Read_Data(&tempe_high,&tempe_low,&humidity) == 0)
	{			
       DHT11_humi = humidity;
       DHT11_temp_high = tempe_high;	
       DHT11_temp_low = tempe_low;				
	   printf("DHT11_temp_high = %d\r\n",DHT11_temp_high);		
	   printf("DHT11_temp_low = %d\r\n",DHT11_temp_low);				
	   printf("DHT11_humi = %d\r\n",DHT11_humi);						
	}	
	else
	{
	   printf("DHT11 DATA Fail\r\n");					
	}		
}

显示部分,这里的显示是用0.96寸OLED显示的,不懂的话可以参考我的另外一篇博客:0.96寸OLED(IIC接口)显示屏的图像显示应用

注意:OLED字模库没有包含°,也没特地去取°,不影响温湿度的数据显示。

/*******************************************************************************
 * 函数名:OLED_Rfresh
 * 描述  :OLED实时显示数据刷新
 * 输入  :void
 * 输出  :void
 * 调用  :1s
 * 备注  :
 *******************************************************************************/
void OLED_Rfresh(void)
{
  if(DHT11_flag)
	{
	  OLED_ShowString(1, 1, "Temp:");	
      OLED_ShowSignedNum(1, 6, DHT11_temp_high, 2);		
	  OLED_ShowString(1, 9, ".");	
	  OLED_ShowSignedNum(1, 9, DHT11_temp_low, 1);
	  OLED_ShowString(1, 11, "C");		
	  OLED_ShowString(2, 1, "Humi:");			
      OLED_ShowSignedNum(2, 6, DHT11_humi, 2);	
	  OLED_ShowString(2, 9, "%");				
	}		
}

2.9 测试结果:

2.9.1 上电状态

在这里插入图片描述
上电串口打印DHT11 OK表示DHT11工作正常

uint8_t DHT11_temp_high = 0;//温度高位
uint8_t DHT11_temp_low = 0;//温度低位
uint8_t DHT11_humi = 0;//湿度

在这里插入图片描述

2.9.2 湿纸巾状态

由于要让湿度变化明显比较容易,所以咱直接湿纸巾盖上去。
在这里插入图片描述
可以发现湿度变化比较大,温度也有稍微变化,毕竟水降点温。
在这里插入图片描述


三、总结

今天简单介绍了温湿度传感器DHT11的温湿度数据采集及显示,感谢你的观看,谢谢!

在这里插入图片描述

  • 35
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaobuding_QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值