Raspberry Pi(温度・気圧・湿度センサー)

目次Raspberry Piロボット|センサー(温度・気圧・湿度人感)|赤外線リモコン読み上げMQTT連携IFTTT連携

ここでは、デジタル温度・気圧・湿度センサを試してみます。指定の時間で、内臓のSDメモリカードに書き込み、そのデータをWebで見れる様にします。

温度・気圧・湿度センサーの仕様

BME280搭載 温度・気圧・湿度センサモジュール仕様

接続図

Raspberry Piの設定

システムメニューより設定を選択して「Raspberry Pi の設定」を選択します。 その設定画面より「インターフェイス」のタグを選択して、I2Cを有効の設定します。
リブートしてから「 i2cdetect -y 1 」コマンドで接続状態を確認します。76の位置に76と表示されます。

$ i2cdetect -y 1 
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- 76 --

温度・気圧・湿度センサーの動作確認

RPi.bme280ライブラリを使う

I2C接続でbm280のライブラリーを下記のコマンドで追加します。

pip install smbus2
pip install RPi.bme280

下記のプログラムを作成します。

import smbus2
import bme280
bus = smbus2.SMBus(1) 
#bme280.load_calibration_params(bus, 0x76) 
print(bme280.sample(bus, 0x76))

実行すると、下記の結果が得られます。

$ python3 tom/bme280-check.py
compensated_reading(id=776285ed-a721-4e07-9042-84d2c1408211,
timestamp=2022-01-08 01:36:42.595712UTC, temp=8.333 °C, pressure=1021.99 hPa, humidity=49.08 % rH)

サンプルプログラムを試す

スイッチサイエンスのGitHub BME280 より、bme280_sample.py を入手します。
https://github.com/SWITCHSCIENCE/BME280/blob/master/Python27/bme280_sample.py

bme280_sample.py を、そのまま Python3 で実行すると、エラーになります。 下記の3か所変更(print文に()を付ける)して、実行すると下記の結果が得られます。

print "pressure : %7.2f hPa" % (pressure/100) ⇒ print ("pressure: %7.2f hPa" % (pressure/100))
print "temp : %-6.2f ℃" % (temperature) ⇒ print ("temp : %-6.2f ℃" % (temperature))
print "hum : %6.2f %" % (var_h) ⇒ print ("hum : %6.2f %" % (var_h))

修正版は「bme280-sample.py」に作成しました。実行結果は下記の通りです。

$ python3 tom/bme280-sample.py
temp : 8.74 ℃
pressure : 1021.25 hPa
hum : 0.00 %

カスタマイズする場合はこのプログラムが参考になります。

ファイルに記録する

温度・気圧・湿度記録プログラム

data/sys.textに書いた記録時間間隔(秒)で温度・気圧・湿度を取得してdata/text.txtファイルに書き出します。
プログラムの終了は、ctl+cキー押下で終了します。プログラム(sensor280.py)は下記の通りです。

import time
import datetime
import smbus2
import bme280
bus = smbus2.SMBus(1) 
if __name__ == "__main__":
    while 1:
        f = open("/home/pi/tom/data/sys.txt","r")
        val = f.read()
        f.close()
        f = open("/home/pi/tom/data/text.txt","a")
        dat = bme280.sample(bus, 0x76)
#       print (dat)
        spl = str(dat).split(",")
        temp=spl[2]
        pressure=spl[3]
        humidity=spl[4][:-1]
        tmp=(str(datetime.datetime.now())[:-7] + temp+pressure+humidity)
        print(tmp)
        f.write(tmp + "/\n")
        f.close()
        time.sleep(int(val))

プログラムの実行

「python3 xxx/sensor280.py」で実行してください。

リアルタイムに表示する

簡易Webサーバ環境で試す

pythonの標準ライブラリでwebサーバを立ち上げて、作成したHTMLを表示させます。
作成したプログラム「bme280web.py」は下記の通りです。

import smbus2
import bme280
import time
import datetime
bus = smbus2.SMBus(1)
bme280.load_calibration_params(bus,0x76)
while 1:
    dat = bme280.sample(bus, 0x76)
    print (dat)
    spl = str(dat).split(",")
    temp=spl[2]
    pressure=spl[3]
    humidity=spl[4][:-1]
    tnow=str(datetime.datetime.now())[:-7]
    time.sleep(1)
    f = open('index.html','w')
    f.write('<meta charset="UTF-8"><META HTTP-EQUIV="Refresh" CONTENT="1">')
    f.write('<h1>'+str(tnow)+"<br>"+str(temp)+"<br>"+str(pressure)+"<br>"+str(humidity)+"<br>"+'</h1>')
    f.close()

プログラムの実行

Web環境(Flask)を作る

Flaskの準備・設定

Flaskがインストールされていない場合はpipコマンド「$ sudo pip3 install flask」でインストールしてください。
最新のバージョン(Raspbian GNU/Linux 11)にはインストールされております。
それぞれのファイル設置場所は下記の様に設定してください。

ユーザディレクトリ/flask
          ┣ templates(ディレクトリー名は固定)
          ┃  ┣ gettemp.html(温度・気圧・湿度を取得するHTML)
          ┃  ┗ acttemp.html(測定履歴を表示するHTML)
          ┗ web.py(pythonプログラムの処理)       

温度・気圧・湿度の取得

温度・気圧・湿度を取得するHTMLを作成します。

温度・気圧・湿度の表示プログラム(gettemp.html)です。


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>温度・気圧・湿度の表示</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<script>
</script>
</head>
<body>
<a href="top">top</a>
<h1 style="text-align:center;">温度・気圧・湿度の表示</h1>
<hr>
<table style="margin:0px auto;"><tr><td>
<form name="form">
<p><input type="button" value="再表示"   onclick="location.reload()">
   <input type="button" value="履歴表示" onclick="window.open('acttemp',target='_self')"></p>
</form>
<div id="msg">
{{temp[0]}}<br>
{{temp[1]}}<br>
{{temp[2]}}<br>
{{temp[3]}}<br>
</div>
</td></tr></table>
</body>
</html>

測定履歴の表示

測定履歴を表示するHTMLを作成します。

測定履歴の表示プログラム(acttemp.html)です。


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>測定履歴の表示</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
<a href="top">top</a>
<H1 style="text-align:center;">測定履歴の表示</H1>
<hr>
<table style="margin:0 auto;"><tr><td>
<form name="myform">
<p><input type="button" value="温度・気圧・湿度表示"   onclick="window.open('/',target='_self');">
   <input type="button" value="測定履歴の表示"   onclick="location.reload()"></p>
現在の測定時間間隔は{{ivl}}秒です。 
<p><input type="text" name="intval" value="" size="3">秒
   <input type="button" value="測定時間間隔設定" onclick="act( 'set' ,myform.intval.value);"></p>
<p><input type="button" value="測定履歴の消去"   onclick="act( 'clr' ,0);"></p>

</form>
<pre><code>{{msg}}</code></pre>
</td></tr></table>
<script>
function callbackValue( macro,arg,data) {
  re = new RegExp("/", "g");
  msg.innerHTML = data.replace(re,"<br>") ;
}
function act(c,v) {
  if ( c == "set" && (v == "" || v < 60 )) { alert("入力エラー") ; return ; }
  form.cmd.value = c ;
  form.val.value = v ;
  form.submit() ;
}
</script>
<form name="form" action="/acttemp" method="post">
<input type="hidden" name="cmd" value="">
<input type="hidden" name="val" value="">
</form>
</body>
</html>

python処理プログラム

pythonプログラムは下記の通りです。

「/」にアクセスしたときの処理

「/acttemp」にアクセスしたときの処理

その他の処理

pythonプログラムソース(web.py)は下記の通りです。


# -*- coding: utf-8 -*-
from flask import Flask, render_template, request
import subprocess
import os
import time
import datetime
import smbus2
import bme280
bus = smbus2.SMBus(1) 

# Flaskのインスタンスの作成
app = Flask(__name__)

# 「/」にアクセスしたときの処理
@app.route("/")
def gettemp():
    dat = bme280.sample(bus, 0x76)
    spl = str(dat).split(",")
    temp=spl[2]
    pressure=spl[3]
    humidity=spl[4][:-1]
    now = str(datetime.datetime.now())[:-7]
    tmp=[now,temp,pressure,humidity] 
    return render_template("gettemp.html",temp = tmp)
# 「/acttemp」にアクセスしたときの処理
@app.route("/acttemp", methods=["GET","POST"])
def acttemp():
    f = open("/home/pi/tom/data/sys.txt","r")
    ivl = f.read()
    f.close()
    f = open("/home/pi/tom/data/text.txt","r")
    msg = ""
    while True :
        data = f.readline()
        if data == "" :
            break
        msg = msg + data
    f.close()
    if "POST" == request.method:
        cmd = request.form["cmd"]
        val = request.form["val"]
        if cmd == "clr":
            f = open("/home/pi/tom/data/text.txt","w")
            f.write("")
            f.close()
        if cmd == "set":
            f = open("/home/pi/tom/data/sys.txt","w")
            f.write(str(val))
            f.close()
    return render_template("acttemp.html",ivl=ivl,msg=msg)

# 「Ctrl + C」による終了時の処理
def sigint_handler(signal, frame):
    #app.logger.debug("Closed")
    sys.exit(0)

# メイン関数
if __name__ == "__main__":
    proc = subprocess.Popen(["python3","tom/sensor280.py"])
    print("温度・気圧・湿度・測定開始")

    # Flaskインスタンス実行
#   app.run("0.0.0.0", port=5000,debug=True) # デバッグ出力する実行
    app.run("0.0.0.0", port=5000) # デバッグ出力しない実行

プログラムの実行

プログラムの実行は「python3 flask/web.py」で実行して、PC、スマートフォンのブラウザより「http://Raspberry PiのIPアドレス:5000」でアクセスして下さい。

目次Raspberry Piロボット|センサー(温度・気圧・湿度人感)|赤外線リモコン読み上げMQTT連携IFTTT連携