基于arduino的dht11温湿度传感器的使用
DHT11库文件下载
Arduino不调用库实现DHT11数据读取
DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度+-5%RH, 温度+-2℃,量程湿度20-90%RH, 温度0~50℃。
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达 20 米以上,使其成为该类应用中,在苛刻应用场合的最佳选择。产品为4针单排引脚封装,连接方便。DHT11温湿度传感器常应用于暖通空调、汽车 、 消费品 、 湿度调节器 、 除湿器、医疗、自动控制等领域。
DHT11温湿度传感器电气特性
温湿度传感器DHT11封装形式及接口说明
建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻(若购买的是已集成的模块,模块上已加上拉电阻,以下请忽略),当然,如果你想要精简电路的话, STC增强型单片机自带的推挽输出功能不失为一个选择,其相当于外接了一个2k的上拉电阻,但在设计电路时需注意:整个单片机的电流推荐不超过55mA,即从MCU-VCC流入的电流不超过55mA,从MCU-GND流出的电流不超过55mA,整体流入、流出电流均不超过55mA,封装尺寸及典型应用电路图如下图所示。
DHT11温湿度传感器典型应用电路
DHT11温湿度传感器时序图
DHT11温湿度传感器连接图
将DHT11的正极与5V电源接口相连,负极与GND相连,中间的数据接口与2号引脚相连。
代码
#include <dht11.h> dht11 DHT11; #define DHT11PIN 3 void setup(){ Serial.begin(9600); Serial.println("DHT11 TEST PROGRAM"); Serial.print("LIBRARY VERSION:"); Serial.println(DHT11LIB_VERSION); Serial.println(); } void loop(){ Serial.println("\n"); int chk=DHT11.read(DHT11PIN); Serial.println("Read sensor: "); switch(chk){ case DHTLIB_OK: Serial.println("OK"); break; case DHTLIB_ERROR_CHECKSUM: Serial.println("Checksum error"); break; case DHTLIB_ERROR_TIMEOUT: Serial.println("Time out error"); break; default: Serial.println("Unknown error"); break; } Serial.print("Humidity (%): "); Serial.println((float)DHT11.humidity, 2); Serial.print("Temperature (oC): "); Serial.println((float)DHT11.temperature, 2); delay(2000); }
注意事项
1、代码中引用了#include <dht11.h>,这个是操作DHT11的库文件,有了它,就可以轻松操作我们这个温湿度传感器了。但是引用这个库文件的操作步骤是:
(1)在网上找到并下载该库文件,包括一个头文件和一个.cpp文件。
(2)在arduino IDE中点击菜单:程序–导入库–add library,然后选择你存放库文件的那个文件夹。
(3)在代码中引用#include <dht11.h>,这样就可以使用了。
2、#define DHT11PIN 3,表示定义引脚3的名字为DHT11PIN ,注意这个定义语句后面没有分号。
原理分析
在硬件编程过程中,当你拿到一个器件,首先要了解他的引脚定义,这会告诉你这个东西应该怎么连接,在一个就是要看他的时序图,看了时序图你就知道主从设备之间进行数据采集过程中的代码应该怎么写,比如怎么启动,如何握手,怎么采集真正的数据等等。
在我们这个试验中,DHT11的时序图是这样的:
DHT11温湿度传感器使用注意事项
DHT11的供电电压为3-5.5V。传感器上电后,要等待1s以越过不稳定状态在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF的电容,用以去耦滤波。
微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零。
操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据+8bit校验和
数据传送正确时校验和数据等于8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据所得结果的末8位。
用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据。
从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集。采集数据后转换到低速模式。
通讯过程
总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号。主机发送开始信号结束后,延时等待20-40us后,读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可,总线由上拉电阻拉高。
总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示。如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常。当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。
数字0信号表示方法
数字1信号表示方法
通讯步骤
根据时序定义来完成通讯过程
- 总线空闲状态为高电平
HIGH
,主机把总线拉低LOW
等待DHT11响应,主机把总线拉低必须大于18ms,保证DHT11能检测到起始信号; - 主机把总线拉高
HIGH
, 延迟等待20-40ms让DHT11 把总线拉低到LOW
; - 主机检测到总线为
LOW
后延迟等待80us; - 主机检测到总线为
HIGH
后继续延迟等待80us即可开始进行数据读取; - 主机等待50us,当检测到总线为
HIGH
时,延时30us再次检测总线状态,根据时序图定义,高电平持续时间大于30us时候为1
小于为0
即可获取到数据,不断重复8次即可获取到1字节的数据; - 重复执行步骤5,5次即可获取到全部的数据
程序:
//Test the DHT11 int dhPin = 3; // 温湿度信号接脚连入 Arduino 的 Pin 3 byte dat[5]; // 存放湿度2byte, 温度 2 byte, checksum 1 byte byte readData() { // 每次读取 8 bits ( one byte) byte data = 0 ; // 初始化数据,不然可能出错 for (int i = 0; i < 8; i++) { if (digitalRead(dhPin) == LOW) { // 一开始要 LOW 才表示要传过来 while (digitalRead(dhPin) == LOW); //等待 50us; // 现在已经变成 HIGH 了 delayMicroseconds(30); //判断高电平持续时间,以判定资料是‘0’还是‘1’; if (digitalRead(dhPin) == HIGH) // 持续了 30 us 以上就是 1 data |= (1 << (7 - i)); //高位在前,低位元在后; //如果这时已经是 LOW, 表示这 bit 是 0, 不必塞入 data //..而且以下的 while 也会立即结束(因为 LOW), 准备接收下一个 bit while (digitalRead(dhPin) == HIGH); // 等待下一bit的接收; //这时一定已经变成 LOW 了 } } return data; // 收完 8 bit = one byte = one char } void start_test( ) { // 每次要与 DHT11 沟通 digitalWrite(dhPin, LOW); //拉低到 LOW,发送表示要开始沟通的信号; delay(30); //延时要大于 18ms,以便 DHT11 能检测到开始信号;我们用30ms digitalWrite(dhPin, HIGH); // 拉高HIGH, 让 DHT11 拉低到 LOW 告诉我们要传送 delayMicroseconds(40); // 给40us等待 DHT11 响应; pinMode(dhPin, INPUT); // 改为输入 mode 准备 digitalRead( ) while (digitalRead(dhPin) == HIGH); // 必须等到 LOW delayMicroseconds(80); //DHT11 发出响应,会拉低 80us;所以至少等80us while (digitalRead(dhPin) == LOW); // 继续等到变 HIGH delayMicroseconds(80); //DHT11 会拉高到HIGH 80us 后开始发送数据; /// 以下连续读入 5 bytes (40 bits), 最后的 byte 是 checksum 校验值 for (int i = 0; i < 5; i++) dat[i] = readData(); //接收温湿度资料,校验位元; pinMode(dhPin, OUTPUT); // 改为 Output mode, 准备拉高HIGH digitalWrite(dhPin, HIGH); //发送完一次资料后释放bus,等待下一次开始信号; } void setup( ) { Serial.begin(9600); Serial.println("begin!"); pinMode(dhPin, OUTPUT); } void loop( ) { start_test( ); // 读取湿度温度和检核位到 dat[ ]; 其中dat[4]是checkSum // 根据datasheet规定, dat[4] 要 == (dat[0]+dat[1]+dat[2]+dat[3]) %256 // 否则表示沟通有错误 !! Serial.print("Current humdity = "); Serial.print(dat[0], DEC); //显示湿度的整数部分; Serial.print('.'); Serial.print(dat[1], DEC); //显示湿度的小数位;(其实是 0) Serial.println(" %"); // 注意有空格要用 " %" 不可用 ' %' Serial.print("Current temperature = "); Serial.print(dat[2], DEC); //显示温度的整数部分; Serial.print('.'); Serial.print(dat[3], DEC); //显示温度的小数位;(其实是 0) Serial.println(" C"); delay(1985); }
DHT11通信波形;测试平台Arduino Due