GPIO制御をpigpioに変えてDHT22から温湿度値を取得します。
今後他のセンサーを制御するにあたりpigpioに移行した方が良さそうだと感じましたのでMyPyDHTで作成したものを作り直しました。
ラズベリーパイで気温・湿度監視モニターの作成
のpigpio版です。
事前準備
pigpioはこちらのWebにあるようにラズベリーパイへインストールします。
http://abyz.me.uk/rpi/pigpio/download.html
とりあえず、下のコマンドを実行すれば、良いはず。
sudo apt-get update
sudo apt-get install pigpio python-pigpio python3-pigpio
sudo pigpiod
DHTの制御コードもpigpio作成者のExamplesページにありましたでそのまま、使用します。
http://abyz.me.uk/rpi/pigpio/code/DHT.py
DHT22センサーとラズベリーパイの接続
GPIO4番にDAT端子を接続して、VCCには5Vを与えています。
ファイル構成
ファイル | 説明 |
---|---|
templates/index.html | HTMLファイル、JavaScriptで5秒ごとにデータを取得する |
dht_server.py | Pythonサーバ、DHT22のセンサー処理を含む |
DHT.py | pigpio作成者のDHTセンサ制御コード(DHT11/21/22/33/44 )に自動対応らしい |
DHT22のメイン制御
DHTの制御コード(DHT.py)を引数にGPIO値付けて実行すると2秒ごとに、GPIO値に+100をつけるとコールバック制御で温室度値を取得します。
python DHT.py 4
or
python DHT.py 104
DHT.pyからメイン処理だけ抜き出して、実行すると2秒ごとに温室度値を取得するコードを一旦記載します。
DHT.pyは同じフォルダ内に保存してください。
後ほどこのコードをサーバに転記することになります。
import time
import DHT
import pigpio
import datetime
DHT_PIN = 4
if __name__== "__main__":
pi = pigpio.pi()
if not pi.connected:
print(f"cannot connect to pigpio")
exit()
s = DHT.sensor(pi, DHT_PIN)
while True:
try:
d = s.read()
today = datetime.datetime.fromtimestamp(d[0]).strftime ("%Y/%m/%d %H:%M" )
temperature = d[3]
humidity = d[4]
dat = {"time": today, "temperature": temperature, "humidity": humidity}
print(f"json: {dat}")
time.sleep(2)
except KeyboardInterrupt:
break
s.cancel()
print(f"cancelling")
pi.stop()
html code
Pythonサーバからfetchを使用して5秒ごとに気温と湿度情報を取得する。
(前回と同じ)
<!DOCTYPE html>
<html lang="ja">
<head>
<title>気温・湿度監視モニター</title>
</head>
<body>
<div>
<div class="container">
<h1>気温・湿度監視モニター</h1>
<h2 id="time">time</h2>
<h2 id="temperature">temperature</h2>
<h2 id="humidity">humidity</h2>
</div>
</div>
<script>
// サーバから温室度値の取得
var sensor_read = function () {
fetch("/data", {
method: 'GET'
}).then((response) => {
return response.json();
}).then((data) => {
console.log(data);
var time = document.querySelector("#time")
time.innerHTML = data.time
var temperature = document.querySelector("#temperature")
temperature.innerHTML = `気温:${data.temperature}度`
var humidity = document.querySelector("#humidity")
humidity.innerHTML = `湿度:${data.humidity}%`
}).catch((err) => {
console.error(err);
});
};
// 5秒タイマー
setInterval(sensor_read, 5000);
</script>
</body>
</html>
Python code
/dataへアクセスした時にDictで気温・湿度データを渡す。
import uvicorn
from fastapi import FastAPI
from starlette.templating import Jinja2Templates
from starlette.requests import Request
import datetime
import DHT
import pigpio
app = FastAPI()
templates = Jinja2Templates(directory="templates")
jinja_env = templates.env
DHT_PIN = 4
sensor = None
@app.get("/")
def root(request: Request):
return templates.TemplateResponse('index.html',
{'request': request})
@app.get("/data")
def data():
"""温湿度値を返す"""
try:
data = sensor.read()
today = datetime.datetime.fromtimestamp(data[0]).strftime ("%Y/%m/%d %H:%M")
status = data[2]
temperature = data[3]
humidity = data[4]
if status == DHT.DHT_GOOD:
dat = {"time": today, "temperature": temperature, "humidity": humidity}
print(f"json: {dat}")
return dat
else:
raise Exception(f"dht sensor error: {status}")
except Exception as e:
print(f"err: {str(e)}")
return None
if __name__ == "__main__":
pi = pigpio.pi()
if not pi.connected:
print(f"cannot connect to pigpio")
exit()
sensor = DHT.sensor(pi, DHT_PIN)
# サーバ起動
uvicorn.run(app, host="0.0.0.0", port=8000)
sensor.cancel()
print(f"cancelling")
pi.stop()
サーバを起動する。
ラズベリーパイのIPを調べて、ブラウザでアクセスする。
0.0.0.0はラズベリーパイ上でifconfigなどで調べて置き換えてください。
$ python dht_server.py