ラズパイで温湿度を測定(DHT11) | そう備忘録

ラズパイで温湿度を測定(DHT11)

ラズパイで温湿度を測定

温湿度センサーをラズベリーパイに接続してIoT化を目指しているのだが一定間隔で温湿度を計るPythonのプログラムを作った時の備忘録。

尚、今回の記事中ではインターネットに接続していないので厳密にはIoT(Internet of Things)では無いが、ラズパイであれば容易にインターネットに接続が可能である。

以前にAWS IoTに接続して値をアップロード(Publish)する記事も書いているのでインターネットに接続するのであれば参考にして欲しい。

使用した温湿度のモジュールはDHT11とDHT22の2種類。

ラズパイはRaspberry Pi ZeroとRaspberryPi 3 B+の2種類を試した。

尚、今回はDHT11の記事とするが、より精度の高い温湿度が測定できるDHT22についてのこちらを参照して欲しい

DHT11モジュール

DHT11表裏

DHT11について

温湿度センサー(DHT11)のスペックは下記の通り。

尚、データシートはこちらを参照した。

尚、小数点以下の湿度を測定したい場合はDHT22にする必要があるがそれは別記事とする。

湿度測定範囲

20%~90%(0℃~50℃範囲)

湿度測定誤差:±5%

尚、データシートによると2017年3月31のVer1.3で5%~95%にアップデートされたとある

今回購入したDHT11のバージョンは分からなかった

温度測定範囲

0℃~50℃

温度測定誤差:±2℃

尚、データシートによると2017年3月31のVer1.3で-20℃~60℃にアップデートされたとある

また2つ同時に測定しても1℃程度の温度差があったので正直、個体による誤差はそれなりにあると考えた方が良いと思う

動作電圧

3.3V~5V

3.3Vを使用する時はケーブルが長すぎるとセンサーに十分な電力を供給できなくなるとあったので5Vが推奨との事

ピン

DHT11からは4つのピンが出ている

データシートによると左からVCC、I/O、NC、GND

3つ目のNCはNot Connect(接続しない)と思われ実際モジュールからはコネクタは3つしか出ていない。

前述の裏面の画像をみても接続されている様子が無い

DHT11のピンについて

購入について

アマゾンで3個で639円で購入した(2019年8月)

dht11.pyのインストール

事前にdht11関連のモジュールをダウンロードする。

データシートの6ページ目以降に信号のフォーマットやパリティチェックの仕方が載っている。

それによると温度と湿度は40bitのLow(0)とHigh(1)で値を返すのだが、このビットのエラーチェックを行い温湿度への変換を1から自分でコーディングするのは正直ちょっと骨が折れる。

ネットで検索してみるとszazo氏がライブラリー化してGithubに載せてくれているのでありがたく使わせてもらうことにした。

プログラムと同じディレクトリに移動して(← 重要)以下のコマンドでgit cloneする。

git clone https://github.com/szazo/DHT11_Python.git

DHT11_Pythonディレクトリが作成されて配下に以下のファイルがインストール(コピー)される。

├─DHT11_Python
│   LICENSE.md
│   README.md
│   __init__.py
│   dht11.py
│   dht11_example.py

dht11.pyが今回使用するモジュール。

ちなみに、

  • LICENSE.md:MITライセンス(オープンソースのライセンス)である事が書いてある
  • README.md:ReadMe、RaspberryPiで使用可能な事が書いてある
  • __init__.py:dht11.pyをimportした時に実行される(空だった)
  • dht11_example.py:dht11.pyの使用例(サンプルプログラム)

となっていた。

尚、dht11.pyの詳しい内容については別記事とする。

2021年1月10日 追記

Github上のDHT11のファイル構成が変わっており、dht11.pyの代わりに__init__.pyに今までのロジックがすべてコーディングされていた。

変更後のフォルダー構成

├─DHT11_Python
│  │ LICENSE.md
│  │ README.md
│  │ dht11_example.py
│  │      
│  ├─dht11
│  │    __init__.py

ただ使い方は変わらないのでソースコードはそのままとしている。

上記のフォルダー構成で、import dht11 とすると __init__.py が dht11モジュールとして呼び出される。

接続について

DHT11(温湿度モジュール)とRaspberryPi Zero(B+も同様)との接続は以下の通り。

DHT11とラズパイとの接続図

まずはRaspberryPi Zeroと接続した。

RaspberryPi ZeroとDHT11との接続

プログラム

RaspberryPi Zeroに接続した時のテスト用プログラム。

# -*- coding: utf-8 -*-
"""
Created on Sat Sep 28 09:17:11 2019
RaspberryPi Zero and 3 B+
温度、湿度センサーのテスト
@author: Souichirou Kikuchi
"""

import RPi.GPIO as GPIO
from time import sleep
from DHT11_Python import dht11 # 温湿度センサーモジュール

TEMP_SENSOR_PIN = 4 # 温湿度センサーのピンの番号
INTERVAL = 10 # 監視間隔(秒)
RETRY_TIME = 2 # dht11から値が取得できなかった時のリトライまので秒数
MAX_RETRY = 20 # dht11から温湿度が取得できなかった時の最大リトライ回数

class EnvSensorClass: # 温湿度センサークラス
    def GetTemp(self): # 温湿度を取得
        instance = dht11.DHT11(pin=TEMP_SENSOR_PIN)
        retry_count = 0
        while True: # MAX_RETRY回まで繰り返す
            retry_count += 1
            result = instance.read()
            if result.is_valid(): # 取得できたら温度と湿度を返す
                return result.temperature, result.humidity
            elif retry_count >= MAX_RETRY:
                return 99.9, 99.9 # MAX_RETRYを過ぎても取得できなかった時に温湿度99.9を返す
            sleep(RETRY_TIME)

GPIO.setwarnings(False) # GPIO.cleanup()をしなかった時のメッセージを非表示にする
GPIO.setmode(GPIO.BCM) # ピンをGPIOの番号で指定

#main
try:
    if __name__ == "__main__":
        env = EnvSensorClass()
        while True:
            temp, hum = env.GetTemp() # 温湿度を取得
            print("温度 = ", temp, " 湿度 = ", hum, "%")
            sleep(INTERVAL)
except KeyboardInterrupt:
    pass
GPIO.cleanup()

実行結果

プログラムの実行結果は以下の通り。

10秒間隔で温湿度を取得してprintしている。

RaspberryPi ZeroとDHT11実行結果

概ね、問題なく表示されているのだが表示間隔が10秒以上空いていたりすることが散見されたのでもう少し詳しく原因を調べてみることにした。(それについては後述

プログラムの説明

その前にプログラムの大まかな説明。

INTERVAL(10秒)間隔で温湿度を取得&表示している。

result = instance.read()で温湿度を取得して失敗したらRETRY_TIME(2秒)間隔を空けて最大MAX_RETRY(20回)再取得を試みる。

MAX_RETRYを超えて失敗した場合に温度、湿度に99.9を返している。

継続して動かし続けていると10回~20回に1回程度だが99.9を返すことが分かった。

MAX_RETRYを超えてエラーになっている

エラーになる原因

プログラムを見直したりネットを検索してみたのだがどうにも良く分からない。

試しに同じプログラムをRaspberryPi 3 B+の方で動かしてみたところ、MAX_RETRYを超えて失敗する事はほぼ無い。

またdht11.pyにprint文を入れて調べた所、DHT11から40ビットを取得できない時(39ビットの時が多い)や最後の8ビットはParity bit(データの整合性をチェックするためのビット)なのだがパリティチェックでエラーになっているケースがZeroの方で圧倒的に多い事が判明した。

※RaspberryPi 3 B+でもエラーは発生しているが頻度が少ないのでMAX_RETRY(20回)まで達しない

下記はdht11.pyにprint文を入れてエラーを表示した結果。

”len error”はDHT11から40ビット返って来ていない場合のエラー、checksum errorは40ビット返って来たのだが先頭から32ビットと残りの8ビットでパリティチェックでのエラー。

エラーがない時は温度、湿度が表示されている。

エラーの詳細をprint

RaspberryPi 3 B+ではエラー頻度が少ないことからリソース(メモリーやCPU使用量)が少ない事がエラー率の高い原因の可能性があるのでRaspberryPi ZeroでCLI起動に切り替えて同じプログラムを動かしてみる。

下記が実行結果。

心なしエラー頻度が少ない気がしないでも無いが誤差の範囲かも知れない。

またDHT11は3個購入したので他の個体でも試したが結果は似たりよったりだった。

CLIで起動した結果

もしかしたら別のモジュールを試せばもっとエラーが少ないのかも知れないが、RaspberryPi ZeroでDHT11を使用する時はエラーが起きる前提でリトライ回数を増やして温湿度を取得するのが良い様に思った。

Start signalの調整

ちなみにデータシートによるとStart signalとして「LOWを少なくとも18ミリ秒(最大30ミリ秒以下)センサーに通知する」とある。

dht11.pyでは40行目付近に以下のコードがあるが、この値を0.025等に変えてみた所、多少エラー率が減少した様に思う(比較結果の明確な数値は取得できていない)

self.__send_and_sleep(RPi.GPIO.LOW, 0.02)

もちろん上記の変更は自己責任であるという事とRaspberryPi 3 B+では0.02のままで問題が無い事を追記しておく。

以上で今回の記事を終了とする。

最後に

この記事が何処かで誰かの役に立つことを願っている。

尚、当記事中の商品へのリンクはAmazonアソシエイトへのリンクが含まれています。Amazonのアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

おすすめ

12件のフィードバック

  1. ゆーじ より:

    最近、ラズパイを始めた者です。わたしは、元機械エンジニアなので、電気はおろかPCプログラムについて知識が乏しいです。それでも、本ページを参考にさせて頂いて、温湿度の表示が出せました。ありがとうございます。プログラムのコマンドの使い方も分からないのに、ちゃんとPCを動かせたので、うれしくなりました。これからも参考にさせて頂きたいと思います。
    今回分かった事は、DHT11センサーを使うのに、事前にdht11.pyのプログラムをPC内に入れておかないと使えない、という事が分かりました。
    それまでは、PCが3番ピンのsiganl bus?の信号を勝手に読んでくれるのだと、思っていました。
    また、恐らくそうなんだろうな、と思っているのが、dht11.pyのプログラムが、モニタへの表示させる動作もやってくれているんだろうな、と思っています。
    まだまだ、プログラムのことはよくわかりませんが、PCが思った通りに動作してくれるとうれしいですね。
    将来的には、クラウドサーバーみたいなところにデータを集約させて、どこからでもデータを見れるようになりたいと思っています。
    ありがとうございました。

    • souichirou より:

      ゆーじさん
      コメントありがとうございます。
      また温湿度の表示が出来たとの事、良かったですね。
      プログラムの動作について補足しますね。

      おっしゃる通りピンの信号をラズパイで読んでいるのですが信号はこちらのデータシート
      (http://akizukidenshi.com/download/ds/aosong/DHT11_20180119.pdf)の6ページ目以降の
      のフォーマットの信号を元に数値に変換する必要があります。
      このデータシートのロジックを自分でコーディングしても良いのですが既に先人の方が
      dht11.pyというモジュールをgithubに用意してくれていたので、ありがたく使わせて
      もらったという事です。
      自分のプログラムから既に用意してもらったモジュール(プログラム)を11行目で読み込み(インポート)しています。

      from DHT11_Python import dht11 # 温湿度センサーモジュール

      ちなみにモニターへの表示は自分のプログラムの中でやっています。
      記事中のソースコードの40行目の

        print("温度 = ", temp, " 湿度 = ", hum, "%")

      がモニターへの表示のコーディングです。

      プログラミングを楽しんで下さい。

  2. ヤッチャ より:

    こんにちは。
    いつも参考にさせていただいております。
    これまでラズパイzeroを使用していましたが、この度ラズパイ4Bにグレードアップしました。
    しかしzeroで動作していたdht11ですが、4Bでは動作してくれません。
    温度、湿度共に99.9が永遠に表示されます。GPIOピンを変更しても変わりませんでした。
    4Bになり動作速度がかなり速くなっていると思いますが、それが原因でしょうか?
    他のサンプルプログラムでも同様に4Bでは動作しませんでした。
    何かヒントがありましたら教えていただけないでしょうか?

    よろしくお願いします。

    • ヤッチャ より:

      おはようございます。
      自己解決しました。 4BではGPIOピンにプルアップが必要だったようです。
      プルアップを付けたら問題なく動作しました。

      • souichirou より:

        ヤッチャさん
        コメントありがとうございます。既に自己解決しているとの事ですが、
        GPIO.setmode の下に、

        GPIO.setup(TEMP_SENSOR_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

        を入れた方が良いかも知れませんね。
        ご指摘ありがとうございます。

  3. ホアン より:

    こんにちは
    いつも参考にさせていただいております。
    今日はラズパイ4でテストをやってみましたが、”ModuleNotFoundError: No module named ‘DHT11_Python’” という異常を出てしまった。どうすればいいですか?
    よろしくお願いします。

    • souichirou より:

      ホアンさん
      こんにちは

      git clone https://github.com/szazo/DHT11_Python.git

      のコマンドをプログラムと同じディレクトリで実行するとDHT11_Python配下にdht11ディレクトリが作成される思いますが、ディレクトリは作成されていますか?

      • ホアン より:

        はい、作成しましたが、その異常を出ました

        • souichirou より:

          ホアンさん

          今回のプログラムの場所とディレクトリ構造とファイル名を教えて下さい。
          今回のスクリプト と __init__.py はどの様な位置関係にありますか?

  1. 2020年8月13日

    […] 温湿度センサーはDHT11を使っています。KKHMF DHT11 湿度センサーモジュール 温度センサーが安価です。コードはラズパイで温湿度を測定(DHT11) | そう備忘録を参考にさせてもらいました。 […]

  2. 2022年7月3日

    […] ラズパイで温湿度を測定(DHT11) | そう備忘録 https://www.souichi.club/raspberrypi/temperature-and-humidity/ […]

  3. 2023年3月14日

    […] 温湿度センサーはDHT11を使っています。KKHMF DHT11 湿度センサーモジュール 温度センサーが安価です。コードはラズパイで温湿度を測定(DHT11) | そう備忘録を参考にさせてもらいました。 […]

質問やコメントや励ましの言葉などを残す

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。