DHT11概述
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用中,在苛刻应用场合的最佳选择。产品为4针单排引脚封装,连接方便。DHT11技术文档
引脚参数
Data脚通信
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次 通讯时间4ms左右,数据分小数部分和整数部分。
数据格式
一次完整的数据传输为40bit,高位先出:8bit湿度整数数据 + 8bit湿度小数数据 + 8bi温度整数数据 + 8bit温度小数数据 + 8bit校验和
时序图
总时序图
开始数据传送时序图
数据传送时序图
通讯步骤
根据时序定义来完成通讯过程
- 总线空闲状态为高电平
HIGH
,主机把总线拉低LOW
等待DHT11响应,主机把总线拉低必须大于18ms,保证DHT11能检测到起始信号; - 主机把总线拉高
HIGH
, 延迟等待20-40ms让DHT11 把总线拉低到LOW
; - 主机检测到总线为
LOW
后延迟等待80us; - 主机检测到总线为
HIGH
后继续延迟等待80us即可开始进行数据读取; - 主机等待50us,当检测到总线为
HIGH
时,延时30us再次检测总线状态,根据时序图定义,高电平持续时间大于30us时候为1
小于为0
即可获取到数据,不断重复8次即可获取到1字节的数据; - 重复执行步骤5,5次即可获取到全部的数据
Arduino实现
设备连接
代码编写
//Test the DHT11
int dhPin = 2; // 温湿度信号接脚连入 Arduino 的 Pin 8
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 以上就是 1data |= (1 << (7 - i)); //高位在前,低位元在后;//如果这时已经是 LOW, 表示这 bit 是 0, 不必塞入 data//..而且以下的 while 也会立即结束(因为 LOW), 准备接收下一个 bitwhile (digitalRead(dhPin) == HIGH); // 等待下一bit的接收;//这时一定已经变成 LOW 了}// if}// for(return data; // 收完 8 bit = one byte = one char
} // readData(
void start_test( ) { // 每次要与 DHT11 沟通digitalWrite(dhPin, LOW); //拉低到 LOW,发送表示要开始沟通的信号;delay(30); //延时要大于 18ms,以便 DHT11 能检测到开始信号;我们用30msdigitalWrite(dhPin, HIGH); // 拉高HIGH, 让 DHT11 拉低到 LOW 告诉我们要传送delayMicroseconds(40); // 给40us等待 DHT11 响应;pinMode(dhPin, INPUT); // 改为输入 mode 准备 digitalRead( )while (digitalRead(dhPin) == HIGH); // 必须等到 LOWdelayMicroseconds(80); //DHT11 发出响应,会拉低 80us;所以至少等80uswhile (digitalRead(dhPin) == LOW); // 继续等到变 HIGHdelayMicroseconds(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, 准备拉高HIGHdigitalWrite(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);
}
串口输出
参考文档
不使用 DHTxx 庫, 如何自己读取 DHT11 湿度温度 ?
Arduino教程——DHT11数字温湿度传感器