1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Raspberry で気温と湿度を監視しよう(DHT11)

Posted at

Raspberry と言えば、電子工作ですよね。
Lチカは、「ScratchでLチカ」や、「LチカをWebで制御する」の形で掲載したので、今回は温湿度がターゲットです。

今回の目標
DHT11で取得した温湿度を、データベース(Postgres)に記録し、照会する機能(Streamlit)を準備します。

利用する機材
① DHT11(基盤に乗っている扱いの簡単な機材を選択しました)
② ジャンパー線3本 (メス・メス)

DHT11
DHT11というと青い格子に足4本ですが、使い易い状態で基盤にはんだ付けされた物もあります。青い格子に足4本ですと、抵抗を入れる必要がある、不要な足がある等、扱いが少し面倒なので、便利な既製品を御薦めします。(回路作りを楽しみたい方は、青い格子に足4本で頑張りましょう)
データシートで性能を確認する限り、測定誤差が大きく御遊び感多々です。
私が選択した基盤にはんだ付けされた物ですが、足は3本で、
 VCC / DATA / GND
と記載があります。色々な電材で必要な知識ですので覚えましょう。

電材のデータシート
電材の説明書みたいなものです。(英語が多く面倒ですが…)
性能や必要となる電圧等、利用に重要な内容が記載されていますので、利用の際には、必ず確認しましょう。

Raspberry Pi の準備
Raspberry Pi OS は Lite を利用します。
Postgresを使いたいので、以前の 安価なWeb開発勉強環境の構築 を参照して、インストールを進めます。
SQLAlchemy まで準備し、テーブルの作成は、下記で準備しましょう。

テーブル
create table t_data (
    kizai varchar(10),
    nitiji timestamp,
    ondo numeric(4,2),
    situdo numeric(4,2),
    kiatu numeric(6,2),
primary key ( kizai, nitiji ) );

他には、以下で準備してみます。
sudo mkdir /test (作業用ディレクトリ作成)
cd /test (カレント移動)
sudo python3 -m venv venv (仮想準備)
sudo chmod 777 -R /test (扱いやすいように権限を落とす)
source /test/venv/bin/activate (仮想環境起動)
pip install psycopg2-binary (Postgresコネクターインストール)
pip3 install SQLAlchemy (SQLAlchemyインストール)
他に必要な手順としては、venvの仮想でGPIOを利用したいので、「ScratchでLチカ」の「余談」対応が必要です。
sudo apt-get install pip (デフォルトのpipを補填します)
pip install RPi.GPIO (仮想環境にGPIOのパッケージを用意します)
Git-Hub に公開されているプログラムを利用させて頂きたいと思います。
sudo apt-get install git (Gitの利用の為インストール)
git clone https://github.com/szazo/DHT11_Python.git (Gitよりクローン)
「/test/DHT11_Python」が作成されているはずです。この中に、example.py のサンプルプログラムが用意されています。
サンプルプログラムを見ると、下記のように、GPIO-14 を利用しているようです。

example.py
# read data using pin 14
instance = dht11.DHT11(pin=14)

このプログラムを、そのまま利用したいと思います。
vcc(電源)2番ピン(5v)と、data(情報の制御用)8番ピン(GPIO-14)と、GNDは数か所ありますが 14番ピンを使ってみましょう。
cd /test/DHT11_Python (カレント移動)
pyhon example.py (プログラム実行)

Last valid input: 2024-11-03 14:51:25.319791
Temperature: 24.5 C
Humidity: 53.0 %

のような処理結果が、6秒置きに表示されるはずです。<ここまで出来れば、現実世界の準備は完了です>
「CTRL+C」でプログラムを終了させます。 次にプログラム(example.py)を修正して、今回のお題を実現するプログラムを準備します。
まずは、Postgres へのアクセスを SQLAlchemy で操作するプログラムを用意します。

db.py (データベース操作用プログラム)
from sqlalchemy import create_engine, Column, Integer, String, DateTime, Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('postgresql://flask1:パスワード@localhost:5432/flask1')
Base = declarative_base()
Ses = sessionmaker(bind=engine)
class t_data(Base):
    __tablename__ = 't_data'
    kizai = Column(String(10), primary_key=True)
    nitiji = Column(DateTime)
    ondo = Column(Float)
    situdo = Column(Float)
    kiatu = Column(Float)

cp example.py dht11p.py (サンプルプログラムをコピー作成して編集します)

dht11p.py
import RPi.GPIO as GPIO
import dht11
import time
import datetime
import db
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
instance = dht11.DHT11(pin=14)
dtCtrl = db.Ses()
try:
        while True:
            result = instance.read()
            if result.is_valid():
                print("Last valid input: " + str(datetime.datetime.now()))
                print("Temperature: %-3.1f C" % result.temperature)
                print("Humidity: %-3.1f %%" % result.humidity)
                newDt = db.t_data(
                    kizai='DHT11',
                    nitiji=datetime.datetime.now(),
                    ondo=result.temperature,
                    situdo=result.humidity,
                    kiatu=0
                )
                dtCtrl.add(newDt)
                dtCtrl.commit()
                dtCtrl.close()
                break
            time.sleep(6)
except KeyboardInterrupt:
    print("Cleanup")
    GPIO.cleanup()

一度実行してみましょう。
python dht11p.py (プログラム実行)
先程と同じように、時間・温度 が表示されて、今回はプログラムが終了するはずです。
これを、1分おきに、自動実行するように設定していきます。
sudo crontab -e (ジョブ設定に下記を追加します)

cron
* * * * * /bin/bash -c 'source /test/venv/bin/activate && python /test/DHT11_Python/dht11p.py'

ここから、以前の記事「Raspberryでstreamlitを勉強してみる②」で照会機能を準備します。
今回はサイドバーは、無しで簡単なプログラムを準備します。

graph.py
import streamlit as st
from sqlalchemy import create_engine, select, text

engine = create_engine('postgresql://flask1:パスワード@localhost:5432/flask1')
with engine.connect() as conn:
    stmt = select('*').select_from(text('t_data'))
    result = conn.execute(stmt)
    data = result.fetchall()

import pandas as pd
df = pd.DataFrame(data, columns=['器具', '日時', '温度', '湿度', '気圧'])
df['日時'] = pd.to_datetime(df['日時'])
df.set_index('日時', inplace=True)
df['温度'] = df['温度'].astype(float)
df['湿度'] = df['湿度'].astype(float)

st.title('温度・湿度')     # 気圧はDHT11では計測できないです
st.line_chart(df[['温度', '湿度']], use_container_width=True)

プログラムが完成したらテスト確認しましょう。
(仮想環境のまま)streamlit run graph.py (streamlitが実行されます)
その後、パソコンより「http://(RaspberryのIPアドレス):8501」へアクセスします。

少し時間を取られた問題発生
streamlitのデフォルトportが、8501なのですが、稀に別のポートで起動されるようです。
streamlit run すると、port番号が明示されるので、確認してから起動しましょう。

最後に、streamlitをサービス起動するように変更しましょう。
以前の記事「Raspberryでstreamlitを勉強してみる①」の「streamlitをサービス起動する方法」を利用します。
上記の問題で迷わないように、ポートは指定してサービス稼働したいと思います。
sudo vi /etc/systemd/system/streamlit_service.service

streamlit_service.service
[Unit]
Description=Streamlit Service
After=network.target
[Service]
WorkingDirectory=/test
Environment=PATH=/test/venv/bin:$PATH
ExecStart=/test/venv/bin/streamlit run --server.port 8501 /test/DHT11_Python/graph.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

編集が終わったら、サービスを起動して確認します。
sudo systemctl daemon-reload
sudo systemctl start streamlit_service
問題無ければ、サービスを登録しましょう。
sudo systemctl enable streamlit_service (サービス起動として登録)
sudo reboot (raspberryを再起動して確認しましょう)
これで、通電したら、即計測開始&即グラフ提供開始の実現です。
お疲れさまでした~。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?