DHT11温湿度传感器模块使用方法和驱动代码实现
DHT11模块简介
DHT11是一款价格便宜,易于使用的温度湿度测量二合一传感器。它具有超小体积、极低功耗的特点。它使用单根总线与单片机进行双向的串行数据传输,信号传输距离可达20米以上。非常适用于对精度和实时性要求不高的温湿度测量场合。
本文将以DFRobot开源硬件平台的DHT11模块和DFRduino开发板来演示,讲解DHT11的驱动和使用。
DHT11电气参数
电源电压:3~5.5V(典型值:5V);
温度量程:0~50℃,误差 ±2℃;
湿度量程:20~90%RH,误差 ±5%RH;
采样周期:大于等于1秒/次。
DHT11硬件原理图
数据总线DATA使用上拉电阻拉高,因此总线空闲时为高电平。上拉电阻阻值推荐范围:4.7K~5.1K。
必要时在VDD和GND之间并一个100nF的去耦电容。
DHT11的工作原理
DHT11使用单一总线通信,即DATA引脚和单片机连接的线。总线总是处于空闲状态和通信状态这个2个状态之间。
当单片机没有与DHT11交互时,总线处于空闲状态,在上拉电阻的作用下,处于高电平状态。
当单片机和DHT11正在通信时,总线处于通信状态,一次完整的通信过程如下:
①单片机将驱动总线的IO配置为输出模式。准备向DHT11发送数据。
②单片机将总线拉低至少18ms,以此来发送起始信号。再将总线拉高并延时20~40us,以此来代表起始信号结束。
③单片机将驱动总线的IO配置为输入模式,准备接收DHT11回传的数据。
④当DHT11检测倒单片机发送的起始信号后,就开始应答,回传采集到的传感器数据。DHT11先将总线拉低80us作为对单片机的应答(ACK),然后接着将总线拉高80us,准备回传采集到的温湿度数据。温湿度数据以固定的帧格式发送,具体格式如下图:
可以发现一帧为40个bit,而每一个bit的传输时序逻辑为:每一个bit都以50us的低电平(DHT11将总线拉低)为先导,然后紧接着DHT11拉高总线,如果这个高电平持续时间为26~28us,则代表逻辑0,如果持续70us则代表逻辑1。
⑤当一帧数据传输完成后,DHT11释放总线,总线在上拉电阻的作用下再次恢复到高电平状态。
注意事项:
1、DHT11上电后,要等待 1秒 以越过不稳定状态,在此期间不能发送任何指令。
2、DHT11属于低速传感器,两次通信请求之间的间隔时间不能太短,一般来说要不能低于1秒。
3、当前DHT11通信帧的小数部分默认都是0,厂商预留给以后实现。所以一般只读取整数值部分即可。校验和定义为:前4个Byte的总和的低8位。
Ardunio驱动代码
在DFRobot官网可以找到DHT11模块驱动库,但出于学习和讲解的目的,下面给出了我自己的驱动实现源代码。使用C语言编写,并在Arduino上测试。
//file:dht11.h
//author:lulipro
//date:2019-5-5 #ifndef DHT11_H__
#define DHT11_H__ #include <stdint.h> #ifdef __cplusplus
extern "C" {
#endif #define DHT11_OK (0) //读取成功
#define DHT11_TIMEOUT (-1) //DHT11响应超时
#define DHT11_CHECKERROR (-2) //数据帧校验错误 void DHT11_init(uint8_t pin);
int DHT11_read(uint8_t* temperature,uint8_t* humidity ); #ifdef __cplusplus
}
#endif #endif
//file:dht11.c
//author:lulipro
//date:2019-5-5 #include "dht11.h" #include <Arduino.h> //for pinMode(),delay() 等
#include <string.h> //for memset() static uint8_t DHT11_dataPin_; //驱动DHT11的数据线引脚
static uint8_t DHT11_recvData_[]; //存放 从DHT11读取的数据的缓冲数组,40个bit
/**********************
*作用:初始化
*参数:pin,Arduino驱动DHT11的总线使用的IO引脚
*返回:无
**********************/
void DHT11_init(uint8_t pin)
{
DHT11_dataPin_ = pin;
//delay(1000);
}
/*********************
*作用:读取一次DHT11的传感器数据
*参数:temperature,指向存放温度数据的指针;humidity,指向存放湿度数据的指针
*返回:函数的执行状态:DHT11_OK,DHT11_TIMEOUT,DHT11_CHECKEROR
*********************/
int DHT11_read(uint8_t* temperature,uint8_t* humidity )
{
uint8_t time_cnt;
uint8_t i;
uint8_t bit_position;
memset(DHT11_recvData_,,); //缓冲数组内容清0 /*--------------主机发送起始信号----------------*/
pinMode(DHT11_dataPin_,OUTPUT);
digitalWrite(DHT11_dataPin_, LOW); // 主机将总线拉低(时间>=18ms),使得DHT11能够接收到起始信号。
delay(); //至少 18 ms
digitalWrite(DHT11_dataPin_, HIGH); // 主机将总线拉高,代表起始信号结束。
delayMicroseconds(); //延时20~40us /*--------------引脚配置为输入模式,准备接收传感器回传的数据-------------------*/
pinMode(DHT11_dataPin_,INPUT); //配置为输入模式
//DHT11将总线拉低至少80us,作为DHT11的响应信号(ACK)。
time_cnt=;
while(LOW == digitalRead(DHT11_dataPin_))
{
delayMicroseconds();
++time_cnt;
if(time_cnt > ) return DHT11_TIMEOUT;
}
//DHT11将总线拉高至少80us,为发送传感器数据做准备。
time_cnt=;
while(HIGH == digitalRead(DHT11_dataPin_))
{
delayMicroseconds();
++time_cnt;
if(time_cnt > ) return DHT11_TIMEOUT;
} /*-------------------DHT11数据帧的接收和解析------------------*/
for( i= ; i < ; ++i )
{
time_cnt = ;
while( LOW == digitalRead(DHT11_dataPin_) ) //拉低50us作为bit信号的起始标志
{
time_cnt++;
delayMicroseconds();
if(time_cnt>) return DHT11_TIMEOUT;
}
time_cnt = ;
while( HIGH == digitalRead(DHT11_dataPin_) ) //拉高。持续26~28us表示bit0,持续70us表示bit1
{
time_cnt++;
delayMicroseconds();
if(time_cnt>) return DHT11_TIMEOUT;
}
if(time_cnt>){ //说明是bit1
bit_position = - i%;
DHT11_recvData_[i/] |= (uint8_t)(<<bit_position);
} } //------------检验和的比对-------------
i = (uint8_t)(DHT11_recvData_[] + DHT11_recvData_[] + DHT11_recvData_[] + DHT11_recvData_[]) ;
if(i != DHT11_recvData_[] ) return DHT11_CHECKERROR; *humidity = DHT11_recvData_[]; //回传湿度数据
*temperature = DHT11_recvData_[]; //回传温度数据 return DHT11_OK;
}
实验例子
硬件连接
Arduino 5V --- DHT11 VDD
Arduino pin5 --- DHT11 DATA
Arduino GND --- DHT11 GND
主程序
#include "dht11.h"
#include <stdint.h> uint8_t temperature ,humidity ; //保存温度和湿度的全局变量 void setup (void)
{
Serial.begin (); //波特率115200
DHT11_init(); //使用Arduino的pin 5驱动DHT11
delay();
} void loop(void)
{ switch (DHT11_read(&temperature,&humidity))
{
case DHT11_OK:
Serial.print("Temperature:");
Serial.print(temperature,DEC);
Serial.print("°C");
Serial.print(" Humidity:");
Serial.print(humidity,DEC);
Serial.println("%RH");
break;
case DHT11_TIMEOUT:
Serial.println("time out"); break;
case DHT11_CHECKERROR:
Serial.println("check error"); break;
default:
Serial.println("unknown error"); break;
} delay(); }
Arduino社区贡献的DHT11库
在DFRobot DHT11使用教程页面的【样例代码】一节找到【下载样例程序和库文件】,点击即可下载Arduino社区开发的DHT11驱动库。
下载后完成后,解压出来。在Arduino安装目录下的【librraies】目录下新建文件夹【dht11】,并将解压出来的dht11.cpp和dht11.h复制到新建的【dht11】文件夹下,即可完成库的安装。
安装到Arduino的【librraies】目录下的库使用#include <xxx>的方式来包含其头文件。例如下面的测试代码:
//
// FILE: dht11_test1.pde
// PURPOSE: DHT11 library test sketch for Arduino
//
#include <dht11.h> //包含驱动库的头文件
dht11 DHT; //创建一个dht11模块对象
#define DHT11_PIN 4 void setup(){
Serial.begin();
Serial.println("DHT TEST PROGRAM ");
Serial.print("LIBRARY VERSION: ");
Serial.println(DHT11LIB_VERSION);
Serial.println();
Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
} void loop(){
int chk;
Serial.print("DHT11, \t");
chk = DHT.read(DHT11_PIN); // READ DATA
switch (chk){
case DHTLIB_OK:
Serial.print("OK,\t");
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.print("Checksum error,\t");
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.print("Time out error,\t");
break;
default:
Serial.print("Unknown error,\t");
break;
}
// DISPLAT DATA
Serial.print(DHT.humidity,);
Serial.print(",\t");
Serial.println(DHT.temperature,); delay();
}
本文参考资料
DHT11温湿度传感器模块使用方法和驱动代码实现的更多相关文章
- Arduino和C51开发DHT11温湿度传感器
技术:51单片机.Arduino.DHT11.温湿度传感器.传感器 概述 学习单片机离不开对传感器的学习,本文主要介绍DHT11温湿度传感器的使用方法,同学也可以了解更多的传感器,这对你以后开发产 ...
- 树莓派使用DHT11温湿度传感器
一.相关介绍 DHT11介绍: DHT11是一款比较便宜的温湿度传感器模块.读取数据只需要占用一个IO口.能够同时测量温度和相对湿度. DHT11的数据手册可以看这里:http://wenku.bai ...
- 【雕爷学编程】Arduino动手做(55)--DHT11温湿度传感器
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备 ...
- 在树莓派上读取DHT11温湿度传感器-python代码实现及常见问题(全面简单易懂)
最近由于自己的课题需要,想要用在树莓派上使用DHT11温湿度传感器来读取空气中温湿度,遇到了几个问题,解决之后也对之前的知识进行了回顾,总结,特整理如下,希望能给也在学习树莓派的小伙伴们带来一些帮助. ...
- DHT11温湿度传感器编程思路以及代码的实现(转载)
源自:https://blog.csdn.net/qq_34952376/article/details/81193938 在我们刚开始进入单片机的学习中,练习写传感器的时序是必不可少的,其实我比较推 ...
- STC15系列通用-STC15F2K60S2/STCW4K32S4读取DHT11温湿度传感器数据串口输出代码实例工程免费下载
//为了方便大家调试,另附程序工程共大家下载,下载地址:https://www.90pan.com/b1908750 //************************** //程序说明:stc ...
- STM32驱动DHT11温湿度传感器
DHT11 是一款湿温度一体化的数字传感器.该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接.通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温 ...
- 玩转X-CTR100 l STM32F4 l DHT11温湿度传感器
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] DHT11数字温湿度传感器是一款含有已校准数字信号输 ...
- 四博智慧物联系统入门示例-1.增加一个DHT11温湿度传感器
1.准备工作 DOIT农业控制开发板或者esp32模组,并下载 四博智慧物联系统快速入门-2.准备工作 章节中的固件 DHT11连接在端口01 使用快速入门注册的管理账号和用户 2.配置网络 3.绑定 ...
随机推荐
- Python-函数参数类型及排序问题
Python中函数的参数问题有点复杂,主要是因为参数类型问题导致的情况比较多,下面来分析一下. 参数类型:缺省参数,关键字参数,不定长位置参数,不定长关键字参数. 其实总共可以分为 位置参数和关 ...
- Maven快速入门--Idea版
目录 1.web项目的基本知识 1.1 项目构建 1.1.1传统的构建过程如下: 1.1.2 mavn构建项目 1.2 maven构建项目的优点: 2. 依赖管理 2.1 传统依赖管理 2.1.1 手 ...
- AT+CNUM获取不到手机号
原因是卡商没有写入SIM卡 解决办法 手动写入 1. 先确认SIM卡的本机号码 2. 选择电话本存储 /* AT+CPBS Select phonebook memory storage " ...
- Can't toast on a thread that has not called Looper.prepare()
Android开发中Can't toast on a thread that has not called Looper.prepare()问题 说一下问题出现场景: 在一个Android项目中,利用 ...
- js中console在一行内打印字符串和对象
在前端开发中,大多数的调试一般都是F12中的console和network中查看请求数据和响应数据,也有一部分人喜欢用debugger. 在开发大一些的项目时,在开发环境下,打开着控制台,切换一下页面 ...
- python基础-内置装饰器classmethod和staticmethod
面向对象编程之classmethod和staticmethod classmethod 和 staticmethod都是python内置的装饰器 classmethod 的作用:给在类内部定义的方法装 ...
- springcloud学习之路: (二) springcloud打jar包并批量运行
springcloud中内置了tomcat所以打包的时候是直接把tomcat打入jar包 之后就可以做到, 单独的服务, 独立的jar包, 独立运行的效果了. 一.打jar包 1. 在pom.xml文 ...
- kolla部署openstack allinone,报错 ImportError: cannot import name decorate
使用 kolla-ansible 部署 opnenstack:stein,最后无法导入变量脚本,报错信息如下: [root@kolla ~]# . /etc/kolla/admin-openrc.sh ...
- 08、启动过程+at+crond+anacron
[root@li ~]# 加电--BIOS (basic input output system)--以什么设备来启动--/dev/sda -- mbr -- grub.conf --vmlinux ...
- UE4 C++中出现的让人手足无措的问题(持续更新)
最近开始涉入UE4更深层的一面——UE4 C++,由于其中的体系和在课本或者是网课上那么说的C++体系有一些误差(准确说就是遵循的C++标准不同),导致学习与运用起来有些吃力,所以作此总结,为自己的开 ...