硬體安裝:
參考ref.1的Figure.1 (page 5)在pin 2的部份與RPi的GPIO 4連接,並使用一電阻與VCC相連
python程式:
1. 快速上手方式:
在RPi已經安裝好pip的狀態下,只需要額外安裝Adafruit_DHT (ref.2)sudo pip install Adafruit_DHT接著,在python環境中輸入:
import Adafruit_DHT as dht sensor = dht.DHT11 gpio = 4 print( dht.read_retry(sensor, gpio) )可以快速得到DHT11偵測到的相對濕度與溫度:
(76.0, 29.0)
在Googled結果,可以看到許多類似的maker分享,許多是從git clone Adafruit_DHT 開始,安裝Adafruit_DHT,有興趣的可以參考ref.4。
要透過GPIO操控DHT11,基本上要了解DHT11的運作機制 (ref.1):2. 透過GPIO方式:
RPi GPIO控制階段:
a. pin 2針腳在高電位下時,給予不少於18ms長的低電位,讓DHT11能截取到電壓變化
b. 恢復pin 2針腳回高電位
DHT11初始化階段:
c. DHT11將pin 2針腳調整為低電壓,持續80μs
d. DHT11將pin 2針腳調整為高電壓,持續80μs
DHT11訊號傳回階段:
e. DHT11會連續的將pin 2針腳,在低電壓與高電壓之間變換共40個循環;
低電位維持50μs,高電位維持26~28μs時,表示為0
低電位維持50μs,高電位維持70μs時,表示為1
f. DHT11將pin 2針腳調整為低電位50μs後,結束控制pin 2針腳電位控制
DHT11輸出的40個bits,共由5個8 bits所組成:
1~8 bits: 相對濕度整數部位
9~16 bits: 相對濕度小數部位
17~24 bits: 溫度整數部位
25~32 bits: 溫度小數部位
33~40 bits: checksum檢查碼,等於前4個數字的總和
在了解DHT11的訊號控制方式,可以寫相對應的GPIO控制來讀取訊號
import RPi.GPIO as GPIO
import time
PIN = 4
# initial GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()
# step a, b
GPIO.setup(PIN, GPIO.OUT)
GPIO.output(PIN, GPIO.LOW)
time.sleep(0.0181)
GPIO.output(PIN, GPIO.HIGH)
# step c, d
GPIO.setup(PIN, GPIO.IN, GPIO.PUD_UP)
while GPIO.input(PIN) == GPIO.LOW:
continue
while GPIO.input(PIN) == GPIO.HIGH:
continue
# step e
bits = []
MAXCount = 3000
for n in range(40):
lowCount = 1
highCount = 1
while GPIO.input(PIN) == GPIO.LOW:
lowCount += 1
while GPIO.input(PIN) == GPIO.HIGH:
highCount += 1
if highCount > MAXCount:
print("missing data")
exit(1)
if lowCount < highCount:
bits.append(1)
else:
bits.append(0)
# bits to bytes
RH = 0
RHD = 0
T = 0
TD = 0
checksum = 0
for bit in bits[:8]:
RH = (RH << 1) | bit
for bit in bits[8:16]:
RHD = (RHD << 1) | bit
for bit in bits[16:24]:
T = (T << 1) | bit
for bit in bits[24:32]:
TD = (TD << 1) | bit
for bit in bits[32:40]:
checksum = (checksum << 1) | bit
# checksum
if RH+RHD+T+TD != checksum:
print("checksum error")
exit(1)
print("RH: {}%, T: {}C".format(RH+0.1*RHD, T+0.1*TD))
執行結果:RH: 76.0%, T: 29.6C
程式下載:
https://github.com/1412chen/rpi_learning/tree/master/dht11- dht11.py: 直接呼叫Adafruit_DHT讀取溫濕度值
- dht11_gpio_direct.py: 透過GPIO讀取溫濕度值
- dht11_gpio.py: 透過GPIO讀取溫濕度值,一次讀取完DHT11電壓變化後才解析。
討論:
1. 在寫這個document的時候,我發現到使用Adafruit_DHT跑出來的結果,不會有小數點,讓我在確認GPIO結果一直充滿疑問。我想這個應該是Adafruit_DHT故意忽略小數位輸出,DHT11本身的誤差太大(相對濕度±5%,溫度±2°C),描述到小數點,確實沒有太大意義。2. 控制GPIO擷取資料,蠻容易出現missing data與checksum error的結果。
3. 相對於Adafruit_DHT是python呼叫C的GPIO控制,ref.3中的dht11是python透過GPIO對DHT11進行操作,該程式為了避免python在擷取pin 2電位過程中額外的操作的時間差導致電位資料遺失或延遲,先將所有電位資料擷取下來後再解析。這樣也許能比較穩定得到結果,我有參照這個邏輯重新撰寫,參考程式下載的dht11_gpio.py。
參考:
1. https://www.mouser.com/ds/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf2. https://github.com/adafruit/Adafruit_Python_DHT
3. https://github.com/szazo/DHT11_Python
4. https://kknews.cc/zh-tw/digital/ea26b4q.html
沒有留言:
張貼留言