ようこそお越しくださいました。
(・∀・)ノ
また、ぷっこ村そっちのけでラズパイネタをやってみようと思います。軸がぶれ始めている……、いや、プログラミングを絡めたマイクラがやりたいから頑張ってるんですよ?ちょっと小銭の臭いがするし。じ、次回はちゃんとゴーレムトラップ完成させますんで……。
さて、今回は我が家の愛するメダカちゃんの住環境を常に監視し、改善するためのアイテムをラズパイで作ってみたいと思います。ラズパイに、webカメラ、水温計、リレー回路による自動給餌機をつけて、快適空間を作ってあげよう!企画の、水温取得の部分をやってみようと思います。
こんな感じにします。あ、当ブログは本来芸術(?)を追求し、ご存知の通りいつも感覚的な表現ばかりです。たまにちょっと技術系なこと書くと「ここでグッてやってバーンってなるんだよ」みたいな意味不明な表現になります。あと専門用語は利口ぶるために使ってるので、わかんねーよって思ったら質問くださいね(答えれるとは言ってない)
取得した水温はデータベースで管理し、グラフとして出力、ブラウザで見れるようにしていきます。
最終的にこんな感じで出力できます。尚、以下の2記事↓を参考にさせていただきました。ありがとうございました。細かい前知識はそちらの方が詳しいです。
Raspberry Piで計測したデータをグラフ化 全部のせPython(SQLite + Bokeh + Flask)で作るグラフアプリ
Raspberry Piで水温を取得する。(DS18B20)
流れ解説
一連の流れですが、
- GPIO接続した水温計で温度の計測
- 計測した値をpythonで成形
- SQliteデータベースに書き込み
- SQliteデータベースからBokehでグラフを作成
- Flaskで読み込んで描画
です。
水温計を使えるように加工
水温計は「DS18B20」がたまたま家にあったので使いました。コンパクトな運用と、繋ぎっぱなしが前提だったので末端をGPIO用に加工しました。
そのまま3本の線をぶっ差してもダメで、VCCとGPIO用のコードの間に4,7KΩ~10KΩの抵抗を入れないといけないようです。詳しくはこちら。今回は10KΩの抵抗を入れてみたところ、水銀計とだいたい同じ値が出ましたので問題なさそうです。
抵抗はいっぱいあると、いざという時困りません
/boot/config.txt
の末尾にdtoverlay=w1-gpio,pullup=on
を追加することで、水温計が使えるようになります。ラズパイを再起動してみましょう。
再起動後/sys/bus/w1/devices/
に「28-○○」みたいなディレクトリが現れたら上手くつながっています。「28-○○」みたいなディレクトリに移動しcat w1_slave
とすると、ゴニョゴニョ出てきます。
これで値の取得はオッケーですね。
値の成形からグラフ描画まで一気に!
SQlite3とBokeh、Flaskのインストールは参考記事の通り、済ませておきましょう。注意なのですが、Bokehは実行の際、Original error was: libf77blas.so.3: cannot open shared object file: No such file or directory
とかいう意味不明なエラーが出てハマりました。numpyがどうとか出ますが、
sudo apt install libatlas-base-dev
で上手くいきましたので、エラーの際はこれで上手くいくかもです。
次節は参考記事を元にいじくったプログラムです。同じ組み合わせの方は使ってみてもいいかもしれません。
何となく解説
実行用クラスの他にクラスを2つ作りました。本当は各行動毎にクラスを4つに分けようとした(計測、書き込み、読み込み、グラフ描画)のですが値の受け渡しが良くわからず「計測+書き込み」と「読み込み+グラフ描画」に落ち着きました。そもそもこの書き方が正しいのかも分かりませんので、赤ペン先生チェックお願いします。
water_temp.pyでは、Measurementクラスで水温計から取得した値を1/1000にして、SQliteのデータベースに日付時間と温度の2項目として書き込むところまでを行います。その後DbReadクラスでデータベースから値を抜き出し、Bokehを利用してグラフ描画用のhtmlとして出力します。
出力されたhtmlはFlask.pyにてブラウザから閲覧可能になります。crontabにて起動時にFlask.pyを実行してFlaskを起動、water_temp.pyを10分おきに実行します。
water_temp.py
Flask.py
#! /usr/bin/env python3
# _*_ coding: utf-8 _*_
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('lines.html')
if __name__ == '__main__':
app.run(host='0.0.0.0')
コメント