DHT11溫濕度傳感器(配合樹莓派使用)
傳感器基本介紹以及參數(shù)
基本介紹以及接口
DHT11是一種數(shù)字溫濕度傳感器,可以測(cè)量周圍環(huán)境的溫度和相對(duì)濕度。該傳感器使用單個(gè)數(shù)字信號(hào)線與微控制器通信,具有較高的可靠性和穩(wěn)定性。它適用于許多應(yīng)用領(lǐng)域,如氣象觀測(cè)、室內(nèi)環(huán)境監(jiān)測(cè)、工業(yè)控制等。
DHT11傳感器使用的基本原理是通過感應(yīng)元件測(cè)量周圍環(huán)境的溫度和濕度,并將這些值轉(zhuǎn)換成數(shù)字信號(hào)。該傳感器包括一個(gè)感應(yīng)元件和一個(gè)數(shù)字信號(hào)處理芯片,具有較高的抗干擾性和穩(wěn)定性。在測(cè)量時(shí),傳感器通過單個(gè)數(shù)字信號(hào)線向微控制器發(fā)送數(shù)據(jù),包括溫度和濕度值,以及校驗(yàn)和等信息。
DHT11傳感器的優(yōu)點(diǎn)是價(jià)格低廉,使用方便,同時(shí)具有較高的精度和穩(wěn)定性。

需要注意的是,上圖所購(gòu)買的DHT11傳感器是自帶電阻的,如果買的是沒有電阻的傳感器(如下圖所示),就需要在DHT11傳感器的信號(hào)線(DATA)上,需要加入一個(gè)4.7K ~ 10K歐姆的上拉電阻。這個(gè)電阻的作用是將傳感器的信號(hào)線拉高,以確保在沒有數(shù)據(jù)傳輸時(shí),信號(hào)線的電平為高電平。如果不加上拉電阻,傳感器的信號(hào)線可能會(huì)漂移,導(dǎo)致數(shù)據(jù)傳輸錯(cuò)誤。(注:3號(hào)NC引腳懸空即可,什么都不接)


工作過程(大概理解即可,后面配合程序可以更好理解)
DHT11傳感器的工作過程可以分為三個(gè)階段:?jiǎn)?dòng)、數(shù)據(jù)傳輸和結(jié)束。
- 啟動(dòng)階段
當(dāng)微控制器需要獲取DHT11傳感器的溫濕度數(shù)據(jù)時(shí),它會(huì)向傳感器發(fā)送一個(gè)啟動(dòng)信號(hào)。啟動(dòng)信號(hào)包括一個(gè)低電平信號(hào),持續(xù)時(shí)間至少18毫秒,然后再發(fā)送一個(gè)高電平信號(hào),持續(xù)時(shí)間為20至40微秒。這個(gè)過程稱為啟動(dòng)階段,目的是喚醒傳感器,并準(zhǔn)備開始數(shù)據(jù)傳輸。
- 數(shù)據(jù)傳輸階段
在啟動(dòng)階段結(jié)束后,DHT11傳感器會(huì)向微控制器發(fā)送40位的數(shù)據(jù),其中包括16位的濕度數(shù)據(jù)、16位的溫度數(shù)據(jù)和8位的校驗(yàn)和。每一位數(shù)據(jù)都是通過連續(xù)的50微秒的高電平或低電平來表示的。
具體地說,濕度和溫度數(shù)據(jù)的高位先傳輸,低位后傳輸,每一位數(shù)據(jù)的高電平時(shí)間表示"1",低電平時(shí)間表示"0",數(shù)據(jù)總共需要傳輸40位。
傳輸數(shù)據(jù)過程中,如果傳輸?shù)臄?shù)據(jù)出現(xiàn)錯(cuò)誤,傳感器會(huì)重新發(fā)送數(shù)據(jù),直到正確接收為止。在傳輸完成后,微控制器會(huì)對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)和驗(yàn)證,確保數(shù)據(jù)的準(zhǔn)確性。
- 結(jié)束階段
當(dāng)數(shù)據(jù)傳輸完成后,傳感器會(huì)將信號(hào)線拉高,以結(jié)束本次數(shù)據(jù)傳輸。此時(shí),微控制器可以繼續(xù)發(fā)送啟動(dòng)信號(hào),以獲取傳感器的下一次溫濕度數(shù)據(jù)。
總體來說,DHT11傳感器通過感應(yīng)元件和數(shù)字信號(hào)處理芯片測(cè)量溫濕度,然后將數(shù)據(jù)轉(zhuǎn)換成數(shù)字信號(hào)傳輸給微控制器。它的工作過程比較簡(jiǎn)單,但需要注意一些細(xì)節(jié),如啟動(dòng)信號(hào)的發(fā)送、數(shù)據(jù)傳輸?shù)捻樞蚝托r?yàn)和的驗(yàn)證等。
一張圖概括:

樹莓派上使用Python編程讀取傳感器數(shù)據(jù)
DHT11和樹莓派的連接
關(guān)于樹莓派的基本介紹和環(huán)境搭建,可以看上一篇: https://blog.csdn.net/HeX_Maker/article/details/130050637
樹莓派上的各個(gè)引腳和接口非常簡(jiǎn)單,看下面兩張圖就夠了:


我在樹莓派上同時(shí)連接了三個(gè)DHT11傳感器,分別用的17 22 27三個(gè)GPIO口
Python編程
代碼
樹莓派中的Python代碼如下:
import RPi.GPIO as GPIO
import time
import serial
ser = serial.Serial("/dev/ttyAMA0",9600)
def delayMicrosecond(t):
start,end=0,0
start=time.time()
t=(t-3)/1000000
while end-start<t:
end=time.time()
tmp0=[] # Used to store the read data
tmp1=[]
tmp2=[]
data0 = 17 # DHT11 BCM
data1 = 27
data2 = 22
a,b=0,0
def DHT11_0():
GPIO.setup(data0, GPIO.OUT) # GPIO OUTPUT
GPIO.output(data0,GPIO.HIGH)
delayMicrosecond(10*1000) # delay 10ms
GPIO.output(data0,GPIO.LOW)
delayMicrosecond(25*1000) # delay 25ms
GPIO.output(data0,GPIO.HIGH)
GPIO.setup(data0, GPIO.IN) # GPIO INPUT
a=time.time() # Recording cycle start time
while GPIO.input(data0):
b=time.time() # time the record ended
if (b-a)>0.1: #Determine whether the cycle time exceeds 0.1 seconds to avoid the program from entering an infinite loop and getting stuck
break
a=time.time()
while GPIO.input(data0)==0:
b=time.time()
if (b-a)>0.1:
break
a=time.time()
while GPIO.input(data0):
b=time.time()
if (b-a)>=0.1:
break
for i in range(40):
a=time.time()
while GPIO.input(data0)==0:
b=time.time()
if (b-a)>0.1:
break
delayMicrosecond(28) # delay 28 microseconds
if GPIO.input(data0): # After more than 28 microseconds, it is judged whether it is still at a high level
tmp0.append(1) # Record the received bit as 1
a=time.time()
while GPIO.input(data0): # Loop until the input is low
b=time.time()
if (b-a)>0.1:
break
else:
tmp0.append(0) # Record the received bit as 0
def DHT11_1():
GPIO.setup(data1, GPIO.OUT)
GPIO.output(data1,GPIO.HIGH)
delayMicrosecond(10*1000)
GPIO.output(data1,GPIO.LOW)
delayMicrosecond(25*1000)
GPIO.output(data1,GPIO.HIGH)
GPIO.setup(data1, GPIO.IN)
a=time.time()
while GPIO.input(data1):
b=time.time()
if (b-a)>0.1:
break
a=time.time()
while GPIO.input(data1)==0:
b=time.time()
if (b-a)>0.1:
break
a=time.time()
while GPIO.input(data1):
b=time.time()
if (b-a)>=0.1:
break
for i in range(40):
a=time.time()
while GPIO.input(data1)==0:
b=time.time()
if (b-a)>0.1:
break
delayMicrosecond(28)
if GPIO.input(data1):
tmp1.append(1)
a=time.time()
while GPIO.input(data1):
b=time.time()
if (b-a)>0.1:
break
else:
tmp1.append(0)
def DHT11_2():
GPIO.setup(data2, GPIO.OUT)
GPIO.output(data2,GPIO.HIGH)
delayMicrosecond(10*1000)
GPIO.output(data2,GPIO.LOW)
delayMicrosecond(25*1000)
GPIO.output(data2,GPIO.HIGH)
GPIO.setup(data2, GPIO.IN)
a=time.time()
while GPIO.input(data2):
b=time.time()
if (b-a)>0.1:
break
a=time.time()
while GPIO.input(data2)==0:
b=time.time()
if (b-a)>0.1:
break
a=time.time()
while GPIO.input(data2):
b=time.time()
if (b-a)>=0.1:
break
for i in range(40):
a=time.time()
while GPIO.input(data2)==0:
b=time.time()
if (b-a)>0.1:
break
delayMicrosecond(28)
if GPIO.input(data2):
tmp2.append(1)
a=time.time()
while GPIO.input(data2):
b=time.time()
if (b-a)>0.1:
break
else:
tmp2.append(0)
while True:
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
del tmp0[0:] #delete list
del tmp1[0:]
del tmp2[0:]
time.sleep(1) # Delay 1 second
DHT11_0()
DHT11_1()
DHT11_2()
humidity0_bit=tmp0[0:8] # Delimited list, bits 0 to 7 are humidity integer data
humidity0_point_bit=tmp0[8:16]# Humidity Decimals
temperature0_bit=tmp0[16:24] # Integer temperature
temperature0_point_bit=tmp0[24:32] # temperature decimal
check0_bit=tmp0[32:40] # check data
humidity1_bit=tmp1[0:8]
humidity1_point_bit=tmp1[8:16]
temperature1_bit=tmp1[16:24]
temperature1_point_bit=tmp1[24:32]
check1_bit=tmp1[32:40]
humidity2_bit=tmp2[0:8]
humidity2_point_bit=tmp2[8:16]
temperature2_bit=tmp2[16:24]
temperature2_point_bit=tmp2[24:32]
check2_bit=tmp2[32:40]
humidity0_int=0
humidity0_point=0
temperature0_int=0
temperature0_point=0
humidity1_int=0
humidity1_point=0
temperature1_int=0
temperature1_point=0
humidity2_int=0
humidity2_point=0
temperature2_int=0
temperature2_point=0
check0=0
check1=0
check2=0
for i in range(8): # convert binary to decimal
humidity0_int+=humidity0_bit[i]*2**(7-i)
humidity1_int+=humidity1_bit[i]*2**(7-i)
humidity2_int+=humidity2_bit[i]*2**(7-i)
humidity0_point+=humidity0_point_bit[i]*2**(7-i)
humidity1_point+=humidity1_point_bit[i]*2**(7-i)
humidity2_point+=humidity2_point_bit[i]*2**(7-i)
temperature0_int+=temperature0_bit[i]*2**(7-i)
temperature1_int+=temperature1_bit[i]*2**(7-i)
temperature2_int+=temperature2_bit[i]*2**(7-i)
temperature0_point+=temperature0_point_bit[i]*2**(7-i)
temperature1_point+=temperature1_point_bit[i]*2**(7-i)
temperature2_point+=temperature2_point_bit[i]*2**(7-i)
check0+=check0_bit[i]*2**(7-i)
check1+=check1_bit[i]*2**(7-i)
check2+=check2_bit[i]*2**(7-i)
humidity0=humidity0_int+humidity0_point/10
temperature0=temperature0_int+temperature0_point/10
humidity1=humidity1_int+humidity1_point/10
temperature1=temperature1_int+temperature1_point/10
humidity2=humidity2_int+humidity2_point/10
temperature2=temperature2_int+temperature2_point/10
check0_tmp0=humidity0_int+humidity0_point+temperature0_int+temperature0_point
check1_tmp1=humidity1_int+humidity1_point+temperature1_int+temperature1_point
check2_tmp2=humidity2_int+humidity2_point+temperature2_int+temperature2_point
if check0==check0_tmp0 and temperature0!=0 and temperature0!=0 and check1==check1_tmp1 and temperature1!=0 and temperature1!=0 and check2==check2_tmp2 and temperature2!=0 and temperature2!=0 : # Determine if the data is normal
print("Temperature0 is ", temperature0,"C\nHumidity0 is ",humidity0,"%")# Print the temperature and humidity data
print("Temperature1 is ", temperature1,"C\nHumidity1 is ",humidity1,"%")
print("Temperature2 is ", temperature2,"C\nHumidity2 is ",humidity2,"%")
#ser.write(temperature0_int)
temperature00 = str(temperature0)
humidity00 = str(humidity0)
#th00 = temperature00 + ";" + humidity00
#ser.write(th00.encode())
#ser.write(temperature00.encode())
temperature11 = str(temperature1)
humidity11 = str(humidity1)
#th11 = temperature11 + ";" + humidity11
#ser.write(th11.encode())
temperature22 = str(temperature2)
humidity22 = str(humidity2)
th = temperature00 + ";" + humidity00 + ";" + temperature11 + ";" + humidity11 + ";" + temperature22 + ";" + humidity22
ser.write(th.encode())
else:
print("error")
time.sleep(1)
GPIO.cleanup()
結(jié)果
運(yùn)行結(jié)果如下圖所示:文章來源:http://www.zghlxwxcb.cn/news/detail-460460.html

大功告成!文章來源地址http://www.zghlxwxcb.cn/news/detail-460460.html
到了這里,關(guān)于DHT11溫濕度傳感器(配合樹莓派使用)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!