樹(shù)莓派基礎(chǔ)實(shí)驗(yàn)27:溫濕度傳感器DHT11 實(shí)驗(yàn)

一奇徒、介紹

?? 數(shù)字溫濕度傳感器DHT11是一種復(fù)合傳感器干像,包含溫度和濕度的校準(zhǔn)數(shù)字信號(hào)輸出赖歌。采用專(zhuān)用數(shù)字模塊采集技術(shù)和溫濕度傳感技術(shù)构资,確保產(chǎn)品具有高可靠性和優(yōu)異的長(zhǎng)期穩(wěn)定性割坠。
?? 該傳感器包含一個(gè)電阻濕感元件和一個(gè)NTC溫度測(cè)量設(shè)備齐帚,并與一個(gè)高性能8位微控制器連接。其精度:濕度+-5%RH彼哼, 溫度+-2℃对妄。量程:濕度20-90%RH, 溫度0~50℃敢朱。采樣周期:大于等于1秒/次剪菱。
?? 在我們剛開(kāi)始練習(xí)寫(xiě)傳感器的時(shí)序時(shí),DHT11非常適合新手入門(mén)練習(xí)如何寫(xiě)時(shí)序拴签。


二孝常、組件

★Raspberry Pi主板*1

★樹(shù)莓派電源*1

★40P軟排線*1

★濕度傳感器DHT11模塊*1

★面包板*1

★跳線若干

三、實(shí)驗(yàn)原理

溫濕度傳感器
溫濕度傳感器模塊原理圖

?? DHT11是一款價(jià)格便宜蚓哩,易于使用的溫度濕度測(cè)量二合一傳感器茫因。它具有超小體積、極低功耗的特點(diǎn)杖剪。它使用單根總線與單片機(jī)進(jìn)行雙向的串行數(shù)據(jù)傳輸冻押,信號(hào)傳輸距離可達(dá)20米以上。非常適用于對(duì)精度和實(shí)時(shí)性要求不高的溫濕度測(cè)量場(chǎng)合盛嘿。

DHT11硬件原理圖

?? 數(shù)據(jù)總線DATA使用上拉電阻拉高洛巢,因此總線空閑時(shí)為高電平。上拉電阻阻值推薦范圍:4.7K~5.1K次兆。必要時(shí)在VDD和GND之間并一個(gè)100nF的去耦電容稿茉。

1. DHT11的數(shù)據(jù)格式:

??DATA 用于樹(shù)莓派與DHT11之間的通訊和同步,采用單總線數(shù)據(jù)格式,一次通訊時(shí)間4ms左右漓库,數(shù)據(jù)分小數(shù)部分和整數(shù)部分恃慧,具體格式在下面說(shuō)明,操作流程如下:

?? DHT11用的是單總線協(xié)議渺蒿,一次傳送40位的數(shù)據(jù)痢士。 注意了,看到這一句話茂装,也就是說(shuō)我們每次讀取DHT11的數(shù)據(jù)時(shí)怠蹂,都要一次性讀取40次,也就是讀取40位少态。并且數(shù)據(jù)前16位是與濕度相關(guān)的城侧,中間16位是與溫度相關(guān)的,最后八位是用來(lái)校驗(yàn)的彼妻,當(dāng)我們校驗(yàn)成功后嫌佑,證明這一次的溫濕度結(jié)果正確的,我們的樹(shù)莓派就可以使用這個(gè)溫濕度值侨歉;如果校驗(yàn)不通過(guò)歧强,那么就代表我們這次讀取出來(lái)的溫濕度值,是錯(cuò)誤的(也許是我們的時(shí)序錯(cuò)誤了为肮,也許是傳感器的問(wèn)題),我們不進(jìn)行采樣肤京。

DHT11數(shù)據(jù)格式示例

2. DHT11的工作原理:

數(shù)據(jù)時(shí)序圖

DHT11的總體通信流程:
第一步:主機(jī)(樹(shù)莓派)先發(fā)送開(kāi)始信號(hào)颊艳,從機(jī)(DHT11)會(huì)返回一個(gè)相應(yīng)信號(hào)進(jìn)行應(yīng)答。
第二步:主機(jī)信號(hào)線拉高準(zhǔn)備接收數(shù)據(jù)忘分。
第三步:開(kāi)始接收數(shù)據(jù)(一次接收40位)棋枕。

?? DHT11使用單一總線通信,即DATA引腳和單片機(jī)連接的線妒峦≈匕撸總線總是處于空閑狀態(tài)和通信狀態(tài)這個(gè)2個(gè)狀態(tài)之間。當(dāng)樹(shù)莓派沒(méi)有與DHT11交互時(shí)肯骇,總線處于空閑狀態(tài)窥浪,在上拉電阻的作用下,處于高電平狀態(tài)笛丙。

?? 當(dāng)單片機(jī)和DHT11正在通信時(shí)漾脂,總線處于通信狀態(tài),一次完整的通信過(guò)程如下:

?? 第一步:DHT11 上電后(DHT11 上電后要等待 1秒以越過(guò)不穩(wěn)定狀態(tài)在此期間不能發(fā)送任何指令)胚鸯,測(cè)試環(huán)境溫濕度數(shù)據(jù)骨稿,幵記錄數(shù)據(jù),同時(shí) DHT11 的 DATA 數(shù)據(jù)線由上拉電阻拉高一直保持高電;此時(shí) DHT11 的DATA 引腳處于輸入狀態(tài)坦冠,時(shí)刻檢測(cè)外部信號(hào)形耗。

?? 第二步:微處理器的 I/O 設(shè)置為輸出,同時(shí)輸出低電平辙浑,且低電平保持時(shí)間不能小于 18ms激涤,然后輸出高電平20~40us,再樹(shù)莓派的 I/O設(shè)置為輸入狀態(tài)例衍,等待 DHT11 作出回答信號(hào)昔期,發(fā)送信號(hào)如圖所示:

主機(jī)發(fā)送起始信號(hào)

?? 第三步:DHT11 的 DATA 引腳檢測(cè)到外部信號(hào)有低電平時(shí),等待外部信號(hào)低電平結(jié)束佛玄,延遲后 DHT11 的 DATA引腳處于輸出狀態(tài)硼一,輸出 80 微秒的低電平作為應(yīng)答信號(hào),緊接著輸出 80 微秒的高電平通知外設(shè)準(zhǔn)備接收數(shù)據(jù)梦抢,樹(shù)莓派的 I/O 此時(shí)處于輸入狀態(tài)般贼,檢測(cè)到 I/O 有低電平(DHT11 回應(yīng)信號(hào))后,等待 80 微秒的高電平后的數(shù)據(jù)接收奥吩,發(fā)送信號(hào)如圖所示:

DHT11應(yīng)答信號(hào)

?? 第四步:由 DHT11 的 DATA 引腳輸出 40 位數(shù)據(jù)哼蛆,樹(shù)莓派根據(jù) I/O 電平的變化接收 40 位數(shù)據(jù),位數(shù)據(jù)“0”的格式為: 50 微秒的低電平和 26-28 微秒的高電平霞赫;位數(shù)據(jù)“1”的格式為: 50 微秒的低電平加 70微秒的高電平腮介。位數(shù)據(jù)“0”、“1”格式信號(hào)如圖所示:

位數(shù)據(jù)“0”端衰、“1”的格式

?? 我們可以把這一段的時(shí)序理解為叠洗,DHT11先把數(shù)據(jù)線拉低50us,然后我們?cè)偃?duì)比高電平持續(xù)的時(shí)間旅东,如果持續(xù)時(shí)間較短灭抑,則為位“0”;如果持續(xù)時(shí)間較長(zhǎng)抵代,則為位“1”腾节。

?? 結(jié)束信號(hào):DHT11 的 DATA 引腳輸出 40 位數(shù)據(jù)后,繼續(xù)輸出低電平 50 微秒后轉(zhuǎn)為輸入狀態(tài)荤牍,由于上拉電阻隨之變?yōu)楦唠娖桨赶佟5?DHT11 內(nèi)部重測(cè)環(huán)境溫濕度數(shù)據(jù),幵記錄數(shù)據(jù)康吵,等待外部信號(hào)的到來(lái)救湖。

注意事項(xiàng):

1、DHT11上電后涎才,要等待 1秒 以越過(guò)不穩(wěn)定狀態(tài)鞋既,在此期間不能發(fā)送任何指令力九。

2、DHT11屬于低速傳感器邑闺,兩次通信請(qǐng)求之間的間隔時(shí)間不能太短跌前,一般來(lái)說(shuō)要不能低于1秒。

對(duì)DHT11的時(shí)序做一個(gè)總結(jié):
一. 主機(jī)(單片機(jī))發(fā)送起始信號(hào):
??1.主機(jī)先拉高data陡舅。
??2.拉低data延遲18ms抵乓。
??3.拉高data(單片機(jī)引腳設(shè)置為輸入)。

二. 從機(jī)(DHT11)收到起始信號(hào)后進(jìn)行應(yīng)答:
??從機(jī)拉低data靶衍,主機(jī)讀取到data線被拉低持續(xù)80us后從機(jī)拉高data線灾炭, 持續(xù)80us,直到高電平結(jié)束颅眶,意味著主機(jī)可以開(kāi)始接受數(shù)據(jù)蜈出。

三. 主機(jī)開(kāi)始接收數(shù)據(jù):
??1.主機(jī)先把data線拉高(io設(shè)置為輸入)。
??2.從機(jī)把data線拉低涛酗,主機(jī)讀取data線電平续滋,直到低電平結(jié)束(大約50us)從機(jī)拉高data線后肃续,對(duì)比高電平持續(xù)的時(shí)間捆愁,如果持續(xù)時(shí)間較短饿凛,則為位“0”;如果持續(xù)時(shí)間較長(zhǎng)時(shí)剖笙,則為位“1”卵洗。
??3.繼續(xù)重復(fù)上述1,2步驟累計(jì)40次。

四. data線拉低50us代表讀取結(jié)束

五. 校驗(yàn)數(shù)據(jù)

更多資料請(qǐng)參考DHT11 官方手冊(cè):
https://www.dfrobot.com.cn/image/data/DFR0067/DFR0067_DS_10.pdf

四弥咪、實(shí)驗(yàn)步驟

??第1步:連接電路过蹂。

樹(shù)莓派 T型轉(zhuǎn)接板 溫濕度傳感器
GPIO0 G17 OUT(DATA)
5V 5V VCC
GND GND GND
溫濕度傳感器DHT11 實(shí)驗(yàn)電路圖
溫濕度傳感器DHT11 實(shí)驗(yàn)實(shí)物接線圖

??第2步:編寫(xiě)控制程序。將提取的二進(jìn)制數(shù)據(jù)轉(zhuǎn)化為十進(jìn)制數(shù)據(jù)酪夷,校驗(yàn)后打印出來(lái)。
??本次編程中將用到NumPy(Numerical Python)擴(kuò)展程序庫(kù)孽惰,支持大量的維度數(shù)組與矩陣運(yùn)算晚岭,此外也針對(duì)數(shù)組運(yùn)算提供大量的數(shù)學(xué)函數(shù)庫(kù)。詳情參考NumPy 教程:
??https://www.runoob.com/numpy/numpy-tutorial.html

??為便于對(duì)比DHT11高電平持續(xù)的時(shí)間勋功,我們?cè)O(shè)置了一個(gè)計(jì)數(shù)器參數(shù)k坦报,如果持續(xù)時(shí)間較短,則k值較锌裥片择;如果持續(xù)時(shí)間較長(zhǎng)時(shí),則k值較大骚揍。當(dāng)然字管,也可以使用時(shí)間函數(shù)直接對(duì)比時(shí)間長(zhǎng)短啰挪,但是程序相對(duì)要復(fù)雜一些。比如使用GPIO.add_event_detect()和time.time()函數(shù)嘲叔。

執(zhí)行結(jié)果截圖

??從上面的截圖中可以看出亡呵,高電平持續(xù)的時(shí)間較短,26-28 微秒時(shí)硫戈,參數(shù)k等于5或6锰什;高電平持續(xù)的時(shí)間較長(zhǎng),70 微秒時(shí)丁逝,參數(shù)k等于17或18汁胆。

#!/usr/bin/env python
import RPi.GPIO as GPIO
import numpy as np
import time
 
DHTPIN = 17         #引腳號(hào)17

GPIO.setmode(GPIO.BCM)      #以BCM編碼格式

def read_dht11_dat():
    
    GPIO.setup(DHTPIN, GPIO.OUT)
    GPIO.output(DHTPIN, GPIO.LOW)
    #給信號(hào)提示傳感器開(kāi)始工作,并保持低電平18ms以上
    time.sleep(0.02)                #這里保持20ms   
    GPIO.output(DHTPIN, GPIO.HIGH)  #然后輸出高電平
    
    GPIO.setup(DHTPIN, GPIO.IN)    
    # 發(fā)送完開(kāi)始信號(hào)后得把輸出模式換成輸入模式,不然信號(hào)線上電平始終被拉高
 
    while GPIO.input(DHTPIN) == GPIO.LOW:
        continue
    #DHT11發(fā)出應(yīng)答信號(hào)霜幼,輸出 80 微秒的低電平
    
    while GPIO.input(DHTPIN) == GPIO.HIGH:
        continue
    #緊接著輸出 80 微秒的高電平通知外設(shè)準(zhǔn)備接收數(shù)據(jù)
    
    
    #開(kāi)始接收數(shù)據(jù)
    j = 0               #計(jì)數(shù)器
    data = []           #收到的二進(jìn)制數(shù)據(jù)
    kk=[]               #存放每次高電平結(jié)束后的k值的列表
    while j < 40:
        k = 0
        while GPIO.input(DHTPIN) == GPIO.LOW:  # 先是 50 微秒的低電平
            continue
        
        while GPIO.input(DHTPIN) == GPIO.HIGH: # 接著是26-28微秒的高電平嫩码,或者 70 微秒的高電平
            k += 1
            if k > 100:
                break
        kk.append(k)
        if k < 8:       #26-28 微秒時(shí)高電平時(shí)通常k等于5或6
            data.append(0)      #在數(shù)據(jù)列表后面添加一位新的二進(jìn)制數(shù)據(jù)“0”
        else:           #70 微秒時(shí)高電平時(shí)通常k等于17或18
            data.append(1)      #在數(shù)據(jù)列表后面添加一位新的二進(jìn)制數(shù)據(jù)“1”
 
        j += 1
 
    print("sensor is working.")
    print '初始數(shù)據(jù)高低電平:\n',data    #輸出初始數(shù)據(jù)高低電平
    print '參數(shù)k的列表內(nèi)容:\n',kk      #輸出高電平結(jié)束后的k值
    
    m = np.logspace(7,0,8,base=2,dtype=int) #logspace()函數(shù)用于創(chuàng)建一個(gè)于等比數(shù)列的數(shù)組
    #即[128 64 32 16 8 4 2 1],8位二進(jìn)制數(shù)各位的權(quán)值
    data_array = np.array(data) #將data列表轉(zhuǎn)換為數(shù)組

    #dot()函數(shù)對(duì)于兩個(gè)一維的數(shù)組辛掠,計(jì)算的是這兩個(gè)數(shù)組對(duì)應(yīng)下標(biāo)元素的乘積和(數(shù)學(xué)上稱(chēng)之為內(nèi)積)
    humidity = m.dot(data_array[0:8])           #用前8位二進(jìn)制數(shù)據(jù)計(jì)算濕度的十進(jìn)制值
    humidity_point = m.dot(data_array[8:16])
    temperature = m.dot(data_array[16:24])
    temperature_point = m.dot(data_array[24:32])
    check = m.dot(data_array[32:40])
    
    print humidity,humidity_point,temperature,temperature_point,check
    
    tmp = humidity + humidity_point + temperature + temperature_point
    #十進(jìn)制的數(shù)據(jù)相加
 
    if check == tmp:    #數(shù)據(jù)校驗(yàn)谢谦,相等則輸出
        return humidity, temperature
    else:               #錯(cuò)誤輸出錯(cuò)誤信息
        return False
 
def main():
    print "Raspberry Pi DHT11 Temperature test program\n"
    time.sleep(1)           #通電后前一秒狀態(tài)不穩(wěn)定,時(shí)延一秒
    while True:
        result = read_dht11_dat()
        if result:
            humidity, temperature = result
            print "humidity: %s %%,  Temperature: %s  ℃" % \
                  (humidity, temperature)
            print '\n' 
            time.sleep(1)

        if result == False:
            print "Data are wrong,skip\n"
            time.sleep(1)
            
def destroy():
    GPIO.cleanup()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        destroy() 



??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末萝衩,一起剝皮案震驚了整個(gè)濱河市回挽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌猩谊,老刑警劉巖千劈,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異牌捷,居然都是意外死亡墙牌,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)暗甥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)喜滨,“玉大人,你說(shuō)我怎么就攤上這事撤防∷浞纾” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵寄月,是天一觀的道長(zhǎng)辜膝。 經(jīng)常有香客問(wèn)我,道長(zhǎng)漾肮,這世上最難降的妖魔是什么厂抖? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮克懊,結(jié)果婚禮上忱辅,老公的妹妹穿的比我還像新娘七蜘。我一直安慰自己,他們只是感情好耕蝉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布崔梗。 她就那樣靜靜地躺著,像睡著了一般垒在。 火紅的嫁衣襯著肌膚如雪蒜魄。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天场躯,我揣著相機(jī)與錄音谈为,去河邊找鬼。 笑死踢关,一個(gè)胖子當(dāng)著我的面吹牛伞鲫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播签舞,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼秕脓,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了儒搭?” 一聲冷哼從身側(cè)響起吠架,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搂鲫,沒(méi)想到半個(gè)月后傍药,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡魂仍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年拐辽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片擦酌。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡俱诸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赊舶,到底是詐尸還是另有隱情睁搭,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布锯岖,位于F島的核電站介袜,受9級(jí)特大地震影響甫何,放射性物質(zhì)發(fā)生泄漏出吹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一辙喂、第九天 我趴在偏房一處隱蔽的房頂上張望捶牢。 院中可真熱鬧鸠珠,春花似錦、人聲如沸秋麸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)灸蟆。三九已至驯耻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炒考,已是汗流浹背可缚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斋枢,地道東北人帘靡。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瓤帚,于是被迫代替她去往敵國(guó)和親描姚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容