水温の自動計測
https://scrapbox.io/files/61212760dc7414001d94544c.png
Raspberry Piで温度センサを制御してアクアリウムの水温を自動的に計測する
スマートアクアリムとして最初にやることと言えば大抵は水温計測だと思う
要件
アクアリウムの水温を摂氏温度で取得できる
水温を指定した時刻(間隔)で自動取得できる
仕様
仕様1:Raspberry Piからプログラムを実行すると、現在の水温が摂氏温度で記録される
仕様2:Raspberry Piで指定した間隔ごとに、上記の水温記録プログラムが実行される
使用したもの
あしゅりーアクアリウムの場合
table:使用したもの
ラズパイ Raspberry Pi 4 ModelB 4GB
温度センサ 防水温度センサ (DS18B20)
抵抗器 4.7kΩ × 1個
はんだごて 最悪無くても何とかなるか…
ワイヤ ラズパイ-センサ間の接続用
ブレッドボード 基板に実装の場合は不要
防水温度センサ:DS18B20
水に入れて計測するため、防水であることが必須
防水じゃないDS18B20もあるので注意
「DS18B20」というのがセンサそのものであり、これを覆うように防水仕様にしたものを各メーカーが出している
GPUと各グラボ製品みたいな感じ
https://scrapbox.io/files/62199748f54e66001fb40578.jpg
設計
全面的に以下を参考にした
注意:上記記事にて配線に一部誤りあり ⇒ 以下で説明しているので要確認
流れは以下の通り
温度センサとワイヤをはんだ付け
温度センサと抵抗器とラズパイを配線
1-Wireを有効化
温度記録プログラムを作成
定期的に温度記録ができるようにする
温度センサとワイヤをはんだ付け
ニッパーなどで温度センサの赤黄黒の3本の被膜を剥がし、中の銅線の束を露出させる
この銅線の束をそれぞれワイヤにはんだ付けする
中の銅線の束は細すぎてそのままブレッドボードに挿すことができないため、ワイヤに取り次いでもらう
はんだ付け環境が無い場合…最悪ワニ口クリップとかで銅線とワイヤ固定して導通させとけばなんとかなるかもしれないが、常設する場合はちゃんとはんだ付けしてほしい
はんだ付けした部分は絶縁テープなどで巻いて保護
↓ではさらにその上から3本まとめて巻いている
https://scrapbox.io/files/6121d84503ffe0001db229a2.jpg
温度センサと抵抗器とラズパイを配線
ラズパイの電源をオフにする(壊れるので)
まずはDS18B20のデータシートを確認
ブレッドボード上に以下の通り配線する
table:配線
Raspberry Pi DS18B20
3.3V Vdd(赤)
GPIO4 DQ(黄)
GND GND(黒)
データシートによると抵抗は4.7kΩ
注意:参考にしたサイトでは電源ラインの配線が誤っていたので以下の通り配線する
https://scrapbox.io/files/61221797d97c8000214372bd.jpg
https://scrapbox.io/files/61221d3d15ddc30023a094a4.jpg
奥のLEDは無関係
もちろんユニバーサル基板にはんだ付けでも可(先に確認はしてくれ)
以下で記載する1-wireはDQのデフォルトがGPIO4になっているためこれを使う(別のピンに変更もできる)
1-Wireを有効化
ラズパイの電源を入れる
1-Wireを有効化する
DS18B20は1-Wireという規格のインタフェースで動作する
sudo raspi-config を実行しInterface Options > 1-Wire > Yes で有効化
エディタで/boot/config.txt を開き、以下が記載されていることを確認する
code:config.txt
dtoverlay=w1-gpio
プルアップ電圧の設定が必要となるため、上記config.txtに以下のように追記する
code:config.txt
dtoverlay=w1-gpio,pullup=on
これをしておかないと測定値が異常な値となる
ラズパイを再起動する
温度記録プログラムを作成
まずはラズパイで温度を取得できているか確認する
ここまで正しく作業できていれば、以下により28-から始まるディレクトリが確認できる
code:Terminal
$ cd /sys/bus/w1/devices/
$ ll
total 0
lrwxrwxrwx 1 root root 0 Aug 15 23:50 28-3c01dxxxxxxx -> ..
lrwxrwxrwx 1 root root 0 Aug 15 23:17 w1_bus_master1 -> ..
このディレクトリ内の w1_slave に温度の情報が記載されている
code:Terminal
$ cat 28-3c01dxxxxxxx/w1_slave
b6 01 55 05 8f a5 41 66 5a : crc=75 YES
b6 01 55 05 8f a5 41 66 5a t=27375
最後の t=27375 が温度情報であり、摂氏温度を1000倍した値として出力される
つまり27.375℃が現在の温度である
この w1_slave は内容はリアルタイムで変動しているため、常に最新の情報を取り出せる
センサ部分を手で握るなどして温度が変わっていくのを確認する
あとはここで得られる情報を各自好きなように活用すれば良いので以降は参考とする
これをプログラム実行により取得して記録する
28- から始まるディレクトリは温度センサごとの固有値であり、不変であるため定数としてプログラム内で準備しておく
以下はエラー処理等無い最小限のコードであり、必要に応じて処理を追加してほしい
code:get_temperature.py
import datetime
# 自身のセンサの固有値「28-xxxxxxxx」で書き換える
PATH_TEMP_SENSOR = '/sys/bus/w1/devices/ここにセンサの固有値/w1_slave'
# 取得した温度データの保存先を指定(自身の環境のパスに書き換える)
OUTPUT = '/home/asyley/temperature.log'
def get_temperature():
now_dt = datetime.datetime.now()
timestamp = now_dt.strftime('%Y-%m-%d %H:%M:%S')
with open(PATH_TEMP_SENSOR, 'r') as f:
lines = f.readlines()
target_line = lines1.strip() target_data_list = target_line.split(' ')
temp_str = target_data_list-1 # 「t=」の後ろから最後までの文字を取得して1000で割る
temp = int(temp_str2:)/1000 with open(OUTPUT, 'a') as f:
log_str = timestamp + ',' + str(temp) + '\n'
f.write(log_str)
if __name__ == '__main__':
get_temperature()
上記を実行する
code:Terminal
$ python3 get_temperature.py
OUTPUT に指定したパスの temperature.log をcat等で確認する
code:temperature.log
2021-08-22 20:47:33,27.437
プログラムを実行するたびにその時の温度情報が記録されていく
水槽にセンサを設置する
https://scrapbox.io/files/612302c7cb73ff001f64e381.jpg
プログラムを実行してみて、温度計とだいたい同じ値が出力されていることを確認する
完了 ⇒ 仕様1:Raspberry Piからプログラムを実行すると、現在の水温が摂氏温度で記録される
定期的に温度記録ができるようにする
crontabで上記プログラムを定期的に実行する
例えば毎時0分、10分、20分、30分、40分、50分にて10分おきに実行したい場合を想定
python3の場所を確認
code:Terminal
$ which python3
/usr/bin/python3
上記の get_temperature.py を例えば /home/asyley/ に置いている場合、 $ crontab -e を実行して以下を追記する
code:crontab
*/10 * * * * /usr/bin/python3 /home/asyley/get_temperature.py
これにより10分おきに温度が記録され、以下のようなログが得られることを確認する
code:temperature.log
2021-08-22 20:50:00,27.437
2021-08-22 21:00:00,27.682
2021-08-22 21:10:00,28.146
2021-08-22 21:20:00,28.315
完了 ⇒ 仕様2:Raspberry Piで指定した間隔ごとに、上記の水温記録プログラムが実行される
活用
システム構成図
「Water temp sensor」が実現できたことになる
システム構成図.icon