ラズベリーパイでDHT11の温湿度データをPythonで読み取る

ラズベリーパイ4でPythonを使用してGPIOを通じてDHT11温湿度センサーからデータを読み取る

はじめに

DHT11は、校正済みのデジタル信号出力を持つ温湿度センサーです。湿度精度は±5%RH、温度精度は±2℃で、測定範囲は湿度20~90%RH、温度0~50℃です。精度はそれほど高くありませんが、価格が非常に安いです。DHT11はシングルバス通信方式を採用しており、動作電圧は3.3~5Vです。

ArduinoでDHT11、DHT22、SHTC3の温湿度データを読み取る方法:https://blog.zeruns.com/archives/527.html
Pythonでマイクロ秒単位の遅延を実現する方法:https://blog.zeruns.com/archives/623.html

DHT11データシートのダウンロード先:https://url.zeruns.com/DHT11 パスワード: qefk

ソースコード

配線接続:

私はラズベリーパイ4を使用しています。他のバージョンをご使用の場合は、各自で確認して調整してください。

ラズベリーパイ4のGPIOピン配置:https://url.zeruns.com/RPI4_GPIO

DHT11		ラズベリーパイ
 VCC---------5V(2番ピン)
 DATA-------BCM18(BCM番号の18番ピン、つまり物理ピン12番)
 GND--------Ground(6番ピン)

ソースコード:

import RPi.GPIO as GPIO
import time

def delayMicrosecond(t):    # マイクロ秒単位の遅延関数
    start,end=0,0           # 変数を宣言
    start=time.time()       # 開始時間を記録
    t=(t-3)/1000000     # 入力tを秒単位に変換(-3は時間補正)
    while end-start<t:  # 時間差が設定値以上になるまでループ
        end=time.time()     # 終了時間を記録

tmp=[]      # 読み取ったデータを格納するリスト

data = 18   # DHT11のDATAピンが接続されたラズベリーパイのGPIOピン(BCM番号)
# https://blog.zeruns.com  
a,b=0,0

def DHT11():
    GPIO.setup(data, GPIO.OUT)  # GPIOピンを出力モードに設定
    GPIO.output(data,GPIO.HIGH) # GPIOを高電平に出力
    delayMicrosecond(10*1000)   # 10ミリ秒遅延
    GPIO.output(data,GPIO.LOW)  # GPIOを低電平に出力
    delayMicrosecond(25*1000)   # 25ミリ秒遅延        
    GPIO.output(data,GPIO.HIGH) # GPIOを高電平に出力
    GPIO.setup(data, GPIO.IN)   # GPIOピンを入力モードに設定
# https://blog.zeruns.com     
    a=time.time()           # ループ開始時間を記録
    while GPIO.input(data): # 入力が低電平になるまでループ
        b=time.time()       # 終了時間を記録
        if (b-a)>0.1:       # ループ時間が0.1秒を超えたか確認(無限ループ防止)
            break           # ループを抜ける
          
    a=time.time()
    while GPIO.input(data)==0:  # 入力が高電平になるまでループ
        b=time.time()
        if (b-a)>0.1:
            break
                 
    a=time.time()
    while GPIO.input(data): # 入力が低電平になるまでループ
        b=time.time()
        if (b-a)>=0.1:
            break   
             
    for i in range(40):         # 40回ループして温湿度データを受信
        a=time.time()
        while GPIO.input(data)==0:  # 入力が高電平になるまでループ
            b=time.time()
            if (b-a)>0.1:
                break
# https://blog.zeruns.com                         
        delayMicrosecond(28)    # 28マイクロ秒遅延
             
        if GPIO.input(data):    # 28マイクロ秒後にまだ高電平か確認
            tmp.append(1)       # 受信したビットを1と記録
                 
            a=time.time()
            while GPIO.input(data): # 入力が低電平になるまでループ
                b=time.time()
                if (b-a)>0.1:
                    break
        else:
            tmp.append(0)       # 受信したビットを0と記録
             
while True:
    GPIO.setmode(GPIO.BCM)      # BCM番号モードに設定
    GPIO.setwarnings(False)
    del tmp[0:]                 # リストをクリア
    time.sleep(1)               # 1秒遅延
# https://blog.zeruns.com     
    DHT11()
  
    humidity_bit=tmp[0:8]       # リストを分割:0~7ビットは湿度整数部分
    humidity_point_bit=tmp[8:16]# 湿度小数部分
    temperature_bit=tmp[16:24]  # 温度整数部分
    temperature_point_bit=tmp[24:32]    # 温度小数部分
    check_bit=tmp[32:40]        # チェックビット
  
    humidity_int=0
    humidity_point=0
    temperature_int=0
    temperature_point=0
    check=0
# https://blog.zeruns.com  
    for i in range(8):          # 2進数を10進数に変換
        humidity_int+=humidity_bit[i]*2**(7-i)
        humidity_point+=humidity_point_bit[i]*2**(7-i)
        temperature_int+=temperature_bit[i]*2**(7-i)
        temperature_point+=temperature_point_bit[i]*2**(7-i)
        check+=check_bit[i]*2**(7-i)
  
    humidity=humidity_int+humidity_point/10
    temperature=temperature_int+temperature_point/10
  
    check_tmp=humidity_int+humidity_point+temperature_int+temperature_point
  
    if check==check_tmp and temperature!=0 and temperature!=0:  # データが正常か確認
        print("Temperature is ", temperature,"C\nHumidity is ",humidity,"%")# 温湿度データを出力
        print("https://blog.zeruns.com")
    else:
        print("error")
  
    time.sleep(1)
    GPIO.cleanup()

実行結果


関連記事

「いいね!」 2