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();
}
評論
查看更多