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信号表示方法
程序:
//DHT11temperature
//chriz_w@163.com
//arduinonano
//arduinolite
#include“arduino_lit.h”
#defineDHT11Pin2
//TesttheDHT11--chriz_w@163.com
bytedat[5];//存放湿度2byte,温度2byte,checksum1byte
bytereadData(){//每次读取8bits(onebyte)
bytedata;
for(inti=0;i《8;i++){
if(digitalRead(DHT11Pin)==LOW)
{
//一开始要LOW才表示要传过来
while(digitalRead(DHT11Pin)==LOW);//等待50us;
//现在已经变成HIGH了
_delay_us(30);//判断高电平持续时间,以判定资料是‘0’还是‘1’;
if(digitalRead(DHT11Pin)==HIGH)//根据时序持续了30us以上就是1
data|=(1《《(7-i));//高位在前,低位元在后;
//如果这时已经是LOW,表示这bit是0,不必塞入data
//。。而且以下的while也会立即结束(因为LOW),准备接收下一个bit
while(digitalRead(DHT11Pin)==HIGH);//等待下一bit的接收;
//这时一定已经变成LOW了
}
}
returndata;//收完8bit=onebyte=onechar
}
voidstart_dht11(){//每次要与DHT11沟通
DIGITAL_WRITE(DHT11Pin,LOW);//拉低到LOW,发表示要开始沟通的信号;
_delay_ms(30);//延时要大于18ms,以便DHT11能检测到开始信号;这里用30ms
DIGITAL_WRITE(DHT11Pin,HIGH);//拉高HIGH,让DHT11拉低到LOW告诉我们要传送
_delay_us(40);//给40us等待DHT11响应;
PIN_MODE(DHT11Pin,INPUT);//改为输入mode准备digitalRead()
while(DIGITAL_READ(DHT11Pin)==HIGH);//必须等到LOW
_delay_us(80);//DHT11发出响应,会拉低80us;所以至少等80us
while(DIGITAL_READ(DHT11Pin)==LOW);//继续等到变HIGH
_delay_us(80);//DHT11会拉高到HIGH80us后开始发送资料;
///以下连续读入5bytes(40bits),最后的byte是checksum校验值
for(inti=0;i《5;i++)
dat[i]=readData();//接收温湿度资料,校验;
PIN_MODE(DHT11Pin,OUTPUT);//改为Outputmode,准备拉高HIGH
DIGITAL_WRITE(DHT11Pin,HIGH);//发送完一次资料后释放bus,等待下一次开始信号;
}
voidsetup(){
SERIAL_BEGIN();
PIN_MODE(DHT11Pin,OUTPUT);
}
voidloop(){
start_dht11();//读取湿度温度和检核位到dat[];其中dat[4]是checkSum
//根据datasheet规定,dat[4]要==(dat[0]+dat[1]+dat[2]+dat[3])%256
//否则表示沟通有错误!!
PRINT(“currenthumidity=”);
println(dat[0]&0xff,10,serial_puts);
PRINT(“currenttemperature=”);
println(dat[2]&0xff,10,serial_puts);//显示温度的整数部分;
_delay_ms(2000);
}
intmain()
{
setup();
while(1)
loop();
}
评论
查看更多