稼働中

Raspberry Pi Pico(s_04)DHT22 / AM2302 用モジュール

DHT22 / AM2302 DHT22c.py

DHT22/AM2302用モジュール
DHT22はデジタル温湿度センサーです。※詳細はDHT22 / AM2302のデータシートを参照ください。
DHT22 / AM2302センサーモジュールで使う自作の’DHT22c.py’を作成しました。使い方だけを記載します。
‘DHT22c.py’は末尾にあります。
※DHT22を実際に使って検証していません。DHT11とほぼ同じです。異なる部分を修正して仮データで動作確認をしています。

使い方

■ファイル転送
Raspberry Pi Picoへ’DHT22c.py’を送った後でimportして使います。
※DHT22c.pyの末尾に、使用例(DHT22_ex.py)の## example以降をコピペ追加しても動作確認できます。
■メソッド
‘DHT22c’をimportすると「meas」のメソッドが使えるようになります。
DHT22(pin_num)で初期化します。
(01)meas()
DHT22で測定した5バイト(40bit)のデータ、計算した後の湿度温度値、測定した回数をリストで返します。
※繰返し間隔を2秒にしているので遅いです。概ね2回目の値になります。

使用例

DHT22で温湿度を測定します。


DHT22c_ex.py
#!/usr/bin/env python
# -*- coding: utf-8 -*
from DHT22c import DHT22

## exapmle
# DHT22/AM2302で温湿度を測定
a=DHT22(22)             # instance GPIO22 DATA-PIN
r_data, c_data, num_meas=a.meas()

print('40bit-DATA=',r_data)
print('H,T=',c_data)

print('num measure=',num_meas)
print('HumidityRH%=',c_data[0])
print('Temperature=',c_data[1])

実行結果

RH 65.2%、TC 10.1C になる仮データで算出しています。
実行すると以下のようになりました。※Thonnyのshellに表示されます。


>>> %Run -c $EDITOR_CONTENT
40bit-DATA= [2, 140, 128, 101, 90]   # RH0,RH1,T0,T1,CK
H,T= (65.2, 10.1)       #16bitデータから算出した湿度、温度
num measure= 2      #2回目(1回目はエラー)
HumidityRH%= 65.2   #湿度65.2%
Temperature= 10.1   #摂氏10.1℃

DHT22モジュール用


DHT22c.py
#!/usr/bin/env python
# -*- coding: utf-8 -*
from machine import Pin, time_pulse_us
import time
##Temperature and humidity module DHT22 (DHT22 also named as AM2302)
class DHT22:
    def __init__(self,pin=22):
        # init Pin(22) out 'H'
        self.pio=pin
        Pin(self.pio, mode=Pin.OPEN_DRAIN, pull=Pin.PULL_UP)
        sig=Pin(self.pio,Pin.OUT)
        sig.value(1)
    # 8ケの'0','1'リストデータをbin 0b_xxxx_xxxxにする
    def b_data(self,l_data):
        b='0b'
        for s in l_data:
            b = b+str(s)
        return b

    # 開始信号 HOST OUT'0' DHT22(at least 1~10ms) DHT11(18ms<)
    def start_sig(self):
        sig=Pin(self.pio,Pin.OUT)
        sig.value(1)
        time.sleep(2) # 繰返し周期は 2sec<=
        sig.value(0)
        time.sleep_ms(2) # DHT22 least 1~10ms DHT11(18ms<)
        sig.value(1)
        #Pulled up to waite 20-40us
        time.sleep_us(20)

    # 受信データ パルス幅測定 recive 1 + 40bit data 
    def dat_recive(self):
        cnt=0
        dat=[]
        sig=Pin(self.pio,Pin.IN)
        while True:
            # measurepulse width 200us< timeout error -1
            d = time_pulse_us(Pin(22),1,200)
            if d==-1:
                #print(d,Pin(22))
                break
            dat.append(d)
            cnt=cnt+1
        return cnt,dat

    # 開始信号 HOST OUT'1' 18msec<
    def start_sig(self):
        sig=Pin(self.pio,Pin.OUT)
        sig.value(1)
        time.sleep(2) # 繰返し周期は2sec<=
        sig.value(0)
        time.sleep_ms(18) # 18ms< NG(10ms) sig.value(1) #Pulled up to waite 20-40us time.sleep_us(20) # 測定 DTH11 mesuare (mesuare-main) def meas(self): e_cnt=0 while True: e_cnt=e_cnt + 1 # 測定回数 #print('e_cnt=',e_cnt) self.start_sig() cnt,data = self.dat_recive() #print(cnt,data) # 41 data recived 41 != retry if cnt==41: r_bit=[] # pulsewidth data >> '0'or'1' list data
                for i in data:
                    if 20 < i <=28:
                        r_bit.append(0)
                    if 68 <= i <=72:
                        r_bit.append(1)
                    else:
                        pass
                #print(len(r_bit),r_bit) # mosi 40 != retry
                
                if len(r_bit)==40:        
                    # 8bitにスライスする
                    h0=r_bit[0:8]
                    h1=r_bit[8:16]
                    t0=r_bit[16:24]
                    t1=r_bit[24:32]
                    cs=r_bit[32:40]

                    # リストデータをbin 0b_xxxx_xxxxに変換する
                    b_h0=int(self.b_data(h0))
                    b_h1=int(self.b_data(h1))
                    b_t0=int(self.b_data(t0))
                    b_t1=int(self.b_data(t1))
                    
                    b_cs=int(self.b_data(cs))

                    # calculate check sum 
                    c_sum=b_h0+b_h1+b_t0+b_t1
                    
#仮のデータでテストするには#1列目の「#」コメントアウトを外します。
#                     ## test data ---------仮のデータ
#                     # RH 65.2% 
#                     b_h0=0b_0000_0010
#                     b_h1=0b_1000_1100
#                     # 35.1C
#                     #b_t0=0b_0000_0001
#                     #b_t1=0b_0101_1111
#                     # TC 10.1C
#                     b_t0=0b_1000_0000
#                     b_t1=0b_0110_0101
#                     ## ---------------------------
                    
                    r_list=[b_h0, b_h1, b_t0, b_t1, b_cs]
                    
                    # calculate H T
                    hu= (b_h0 <<8) | b_h1
                    tc= (b_t0 & 0b0111_1111)<<8 | b_t1
                    c_list=(hu/10, tc/10)

                    if c_sum ==b_cs:
                        return r_list, c_list, e_cnt #RH,T,Csum, count
            # 5回エラーで測定中止
            if e_cnt >=5:
                return print('Error',e_cnt)