【硬件模块】DHT11数字式温湿度传感器模块

2024-05-02 19:36

本文主要是介绍【硬件模块】DHT11数字式温湿度传感器模块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

今天在这边新开一个系列,那就是硬件模块。

后续会把之前写过的硬件模块再写一遍,因为之前都是使用的STM32来驱动模块的,而现在我快速上手ESP32系列也快结束了,因此我在原本文章的基础上再加上使用ESP32来驱动的部分构成硬件模块这个系列。

当然了,也不是吃老本的,这个系列也会写一些之前都没用过的模块,今天就先以DHT11这个之前都没写过的模块来开个头。

DHT11

DHT11是一款数字式温湿度传感器,它采用了已校准的数字信号输出方式,使得测量结果更加准确可靠。该传感器集成了温度测量、湿度测量和数字信号输出等功能,可以实时监测环境的温度和湿度变化。

DHT11传感器内部包含一个湿度检测电容和一个NTC温度测量元件,以及一个高性能的8位微控制器来处理信号。当传感器暴露在环境中时,温度传感器和湿度传感器能够感知到环境的温度和湿度,并将其转换为电信号。随后,微控制器将这些电信号转换为数字信号,并通过单总线通信协议输出给微处理器。

DHT11传感器具有多种优点。首先,它采用数字信号输出,使得读取数据变得简单方便,只需通过一根数据线即可完成温湿度读取。其次,DHT11的价格相对较低,适合大规模应用和低成本项目。此外,它还支持多种平台和开发板,如Arduino、Raspberry Pi等,可以广泛应用于各种嵌入式系统和物联网设备。

然而,DHT11传感器也存在一些缺点。首先,其精度相对较低,温度精度为±2°C,湿度精度为±5%RH,可能无法满足一些高精度测量的需求。其次,DHT11的响应时间较慢,通常需要2秒以上才能完成一次温湿度测量。此外,其测量范围也有限制,温度测量范围为0°C~50°C,湿度测量范围为20%~90%RH。

在实际应用中,DHT11传感器常用于室内环境监测、气象站和气象监测、温湿度控制系统以及物联网项目等领域。例如,在家庭、办公室、实验室等室内环境中,DHT11可以帮助维持舒适的生活和工作环境,并及时采取调节措施。在构建小型气象站时,DHT11可用于监测当地的温度和湿度,为农业、气象学研究以及天气预报等提供重要数据。同时,在温室、温室大棚和养殖场等环境中,DHT11传感器可以实现温湿度的自动控制,提供适宜的环境条件。此外,在物联网项目中,DHT11也是常用的传感器之一,可以实时监测和传输温湿度数据。

综上所述,DHT11是一款功能强大、简单易用且成本较低的温湿度传感器,适用于多种应用场景。然而,在选择使用时需要根据具体需求考虑其精度、响应时间以及测量范围等因素。

以上介绍来自文心一言。

简单来说就是DHT11这个温湿度传感器相当便宜,但是代价就是精度很差。

引脚

其中1号引脚是VCC,2号引脚是数据线,3号引脚没有用,4号引脚是GND。

供电电压的范围是3.3~5.5V

使用的通信协议是1-Wire,所以只需要2号引脚一根数据线即可。

时序

第一步是DHT11上电后需要等待1s,然后处于一个上拉输入的状态。

对于我们的单片机(主机)来说,我们要做的就是等DHT11一秒钟,其他不用操作。

第二步就是我们主机发送起始信号告诉DHT11开始采集数据了。

我们先拉低数据线18~30ms,可以拉个20ms。

之后再拉高延时一会等待DTH11反应,然后改为上拉输入模式。

第三步是DHT11收到信号之后等待数据线的低电平结束后会再拉低数据线83us表示收到,然后再拉高数据线87us通知我们的主机接收数据。

对于我们主机来说,我们发送完上面的起始信号检测数据线是不是被拉低了,如果是,那么我们再等待数据线拉高回去。

DHT11一共会发送40位数据,这40位数据分别代表什么含义这个稍后再说。

我们先看看数据0和1的区别,它们一开始都是拉低54us,不一样的是数据0后面拉高23~27us,而数据1后面拉高了66~74us。

也就是说不管是什么数据,都是先拉低后拉高,不一样的是后面拉高的持续时间。

因此我们可以先等待数据线拉高,拉高之后延时30us,如果是数据0,那么我们读出的将会是低电平,如果是数据1,那么我们读出的是高电平。这样就算是读出了一个bit。

接下来为了时序能够接上,我们再等待数据线拉低(如果是数据0则不用等待,数据线就是拉低的状态)。

重复上面的步骤8次,我们就读出了一个Byte。

最后读完40个bit(5个Byte)之后,我们再来个结束信号。

实际上我们不需要什么操作,上面都是DTH11需要执行的。

我们只要在读出数据之后等待60us即可。

数据

现在我们来看看五个Byte都是些什么含义。

从头到尾依次是湿度的整数,湿度的小数(一直都是0,不需要管它),温度的整数,温度的小数,校验位。

一共有两个数据,湿度和温度。

其中湿度的小数一直都是0。温度的小数对应的值乘上0.1度就是对应的温度。

最后一个校验位是前四位加起来的值。如果前四位加起来不等于校验位,那么表示数据出错了。

需要注意的是前四位数相加的值需要强转成8bit的类型才能和校验位进行比较。

STM32驱动代码

下面的代码里涉及OLED显示和Delay延时函数的部分需要自己实现。

 OLED只是为了展示读取的数据,没有的小伙伴用串口通信打印到电脑上也可以。

延时函数网上随便一搜就有,也可以翻一下我之前的文章,直接复制粘贴也行。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"#define DHT11_DATE_PROT GPIO_Pin_0void Z_DHT11_Init(void);
void Z_DHT11_Output(void);
void Z_DHT11_Input(void);
void Z_DHT11_SetDate(BitAction val);
uint8_t Z_DHT11_GetDate(void);
uint8_t Z_DHT11_GetByte(void);
void Z_DHT11_GetTemperatureAndHumidity(void);//初始化DHT11
void Z_DHT11_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);Z_DHT11_Output();Z_DHT11_SetDate(1);Delay_s(1);
}//将数据线配置为输出模式
void Z_DHT11_Output(void){GPIO_InitTypeDef itd;itd.GPIO_Mode=GPIO_Mode_Out_PP;         //推挽输出itd.GPIO_Pin=DHT11_DATE_PROT;itd.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&itd);
}//将数据线配置为输入模式
void Z_DHT11_Input(void){GPIO_InitTypeDef itd;itd.GPIO_Mode=GPIO_Mode_IPU;            //上拉输入itd.GPIO_Pin=DHT11_DATE_PROT;itd.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&itd);
}void Z_DHT11_SetDate(BitAction val){GPIO_WriteBit(GPIOA,DHT11_DATE_PROT,val);
}uint8_t Z_DHT11_GetDate(void){return GPIO_ReadInputDataBit(GPIOA,DHT11_DATE_PROT);
}//读取一个Byte
uint8_t Z_DHT11_GetByte(void){uint8_t data;for(uint8_t i=0;i<8;i++){while(Z_DHT11_GetDate()==0);Delay_us(30);data<<=1;if(Z_DHT11_GetDate()==1) data|=1;while(Z_DHT11_GetDate()==1);}return data;
}uint8_t DTH11_Data[5];
//获取温湿度
void Z_DHT11_GetTemperatureAndHumidity(void){Z_DHT11_Output();Z_DHT11_SetDate(0);Delay_ms(20);Z_DHT11_SetDate(1);Delay_us(30);Z_DHT11_Input();if(Z_DHT11_GetDate()!=0) return;while(Z_DHT11_GetDate()==0);while(Z_DHT11_GetDate()==1);DTH11_Data[0]=Z_DHT11_GetByte();DTH11_Data[1]=Z_DHT11_GetByte();DTH11_Data[2]=Z_DHT11_GetByte();DTH11_Data[3]=Z_DHT11_GetByte();DTH11_Data[4]=Z_DHT11_GetByte();Delay_us(60);
}int main(void){OLED_Init();Z_DHT11_Init();while(1){Z_DHT11_GetTemperatureAndHumidity();if((uint8_t)(DTH11_Data[0]+DTH11_Data[2]+DTH11_Data[3])!=DTH11_Data[4]) continue;OLED_ShowNum(1,1,DTH11_Data[0],2);OLED_ShowNum(1,4,DTH11_Data[1],2);OLED_ShowNum(2,1,DTH11_Data[2],2);OLED_ShowNum(2,4,DTH11_Data[3],2);OLED_ShowNum(3,1,DTH11_Data[4],2);Delay_ms(500);}
}

数据可以正常读取,就是精度确实有点低。

ESP32驱动代码

其实只需要把STM32的代码改改就行了,差别不大。

ESP32的代码相比较STM32会更简洁一些。

因为ESP32可以将GPIO口初始化成既可以输入也可以输出,因此不需要像STM32那样切换GPIO口的模式。我们只需要初始化一次GPIO口的模式即可,记得加上上拉电阻。

#include <stdio.h>
#include <unistd.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"#define DHT11_DATE_PROT 18void Z_DHT11_Init(void);
void Z_DHT11_SetDate(uint8_t val);
uint8_t Z_DHT11_GetDate(void);
uint8_t Z_DHT11_GetByte(void);
void Z_DHT11_GetTemperatureAndHumidity(void);// 初始化DHT11
void Z_DHT11_Init(void){gpio_config_t init = {.intr_type = GPIO_INTR_DISABLE,         // 失能中断;.mode = GPIO_MODE_INPUT_OUTPUT,         // 输出模式.pin_bit_mask = (1ULL << DHT11_DATE_PROT),.pull_down_en = GPIO_PULLDOWN_DISABLE,  // 失能下拉模式.pull_up_en = GPIO_PULLUP_ENABLE,      // 使能上拉模式};gpio_config(&init);Z_DHT11_SetDate(1);vTaskDelay(1000/portTICK_PERIOD_MS);
}void Z_DHT11_SetDate(uint8_t val){gpio_set_level(DHT11_DATE_PROT,val);
}uint8_t Z_DHT11_GetDate(void){return gpio_get_level(DHT11_DATE_PROT);
}// 读取一个Byte
uint8_t Z_DHT11_GetByte(void){uint8_t data = 0;for (uint8_t i = 0; i < 8; i++){while (Z_DHT11_GetDate() == 0);usleep(30);data <<= 1;if (Z_DHT11_GetDate() == 1)     data |= 1;while (Z_DHT11_GetDate() == 1);}return data;
}uint8_t DTH11_Data[5];
// 获取温湿度
void Z_DHT11_GetTemperatureAndHumidity(void){Z_DHT11_SetDate(0);vTaskDelay(20/portTICK_PERIOD_MS);Z_DHT11_SetDate(1);usleep(30);if (Z_DHT11_GetDate() != 0) return;while (Z_DHT11_GetDate() == 0);while (Z_DHT11_GetDate() == 1);DTH11_Data[0] = Z_DHT11_GetByte();DTH11_Data[1] = Z_DHT11_GetByte();DTH11_Data[2] = Z_DHT11_GetByte();DTH11_Data[3] = Z_DHT11_GetByte();DTH11_Data[4] = Z_DHT11_GetByte();usleep(60);
}void app_main(void){Z_DHT11_Init();while (1){Z_DHT11_GetTemperatureAndHumidity();if ((uint8_t)(DTH11_Data[0] + DTH11_Data[2] + DTH11_Data[3]) != DTH11_Data[4])  continue;printf("%d,%d,%d,%d,%d\r\n",DTH11_Data[0],DTH11_Data[1],DTH11_Data[2],DTH11_Data[3],DTH11_Data[4]);vTaskDelay(1000/portTICK_PERIOD_MS);}
}

ESP32移植STM32代码成功,并且还可以直接通过printf打印到电脑上方便我们查看数据。

说好听一点叫移植,说不好听一点那就是把代码抄过来改改能跑就行。

我们在改代码的时候,函数声明什么的都可以不改,只需要把每个函数里的逻辑适配成我们要移植的芯片的逻辑就行。

这篇关于【硬件模块】DHT11数字式温湿度传感器模块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/955009

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

python内置模块datetime.time类详细介绍

​​​​​​​Python的datetime模块是一个强大的日期和时间处理库,它提供了多个类来处理日期和时间。主要包括几个功能类datetime.date、datetime.time、datetime.datetime、datetime.timedelta,datetime.timezone等。 ----------动动小手,非常感谢各位的点赞收藏和关注。----------- 使用datet

C8T6超绝模块--EXTI

C8T6超绝模块–EXTI 大纲 控制流程结构体分析EXTI实现按键 具体案例 控制流程 这里是流程框图,具体可以去看我STM32专栏的EXTI的具体分析 结构体分析 typedef struct {uint32_t EXTI_Line; // 中断/事件线EXTIMode_TypeDef EXTI_Mode; // EXTI 模式EXTITrigger_TypeDef EXTI_

1、创建多模块的maven springboot项目

现在的java的项目都是多模块的,这次也跟个风。 目标:实现下述结构 项目AcedBoot, 子模块:         aced-api 对外提供接口,         aced-web 给前端提供接口,         aced-service 服务层,         aced-dao 数据底层,包含数据库mapper和实体类entity,         aced-commo

Vue2电商项目(二) Home模块的开发;(还需要补充js节流和防抖的回顾链接)

文章目录 一、Home模块拆分1. 三级联动组件TypeNav2. 其余组件 二、发送请求的准备工作1. axios的二次封装2. 统一管理接口API----跨域3. nprogress进度条 三、 vuex模块开发四、TypeNav三级联动组件开发1. 动态展示三级联动数据2. 三级联动 动态背景(1)、方式一:CSS样式(2)、方式二:JS 3. 控制二三级数据隐藏与显示--绑定styl

PrestaShop免费模块/插件/扩展/工具下载

PrestaShop免费模块/插件/扩展/工具下载 PrestaShop免费模块 适用于您的电子商务网站的PrestaShop模块 现有超过3,000个PrestaShop模块可帮助您自定义在线商店,增加流量,提高转化率并建立客户忠诚度。 使您的电子商务网站成功! 下载(超过142+之多的PrestaShop官网认证的免费模块) 标签PrestaShop免费, PrestaShop免费工