ラズパイ3とDS18B20で温度を測定してFirestoreにアップする
概要
お古のラズパイ3を譲り受けたので折角なら何か電子工作始めてみようと思い、飼育しているペットのケージ内の温度を測定できたらなあとやってみました。。
取得までの手順は以下のページをとても参考にさせていただきました。ありがとうございます。
上記サイト様を参考にpythonで温度取得をできるようにし、その後データをFirestoreに保存するようにします。
準備したもの
電子工作自体が初めてのため、基本的に参考サイト様で紹介されていたものを購入しています。
- RaspberryPi 3
- SSH設定済み
- Python 3.9.2
- DS18B20
-
ブレッドボードとジャンパワイヤーのセット
- ブレッドボードはこのセットのだとちょっと大きかったです
- ジャンパワイヤーはラズパイのピンに繋ぐためのオスメスも必要だったので購入しました。
- 抵抗セット
やってみた
1-Wireの有効化
/boot/config.txt
に下記の値を追記します。
iniファイルのようになっていますが、セクション無しの箇所に追記しました。
dtoverlay=w1-gpio,gpiopin=4,pullup=y
以下のmodprobeコマンドでカーネルモジュールをロードします。
$ sudo modprobe w1-gpio
$ sudo modprobe w1-therm
lsmodでロード済みを確認します。
$ lsmod | grep w1
w1_therm 28672 0
w1_gpio 16384 0
wire 36864 2 w1_gpio,w1_therm
配線
ラズパイの電源を切り、参考サイト記載のように配線を行います。
初めてで非常に汚いんですが....以下のようになりました。
疎通確認
ラズパイに再び電源を入れsshし、疎通確認をしていきます。
DS18B20のディレクトリの場所を確認します。
28-から始まるセンサデバイスUIDのシンボリックリンクがあればok
$ ls /sys/bus/w1/devices/
28-03009779ec2d w1_bus_master1
ディレクトリ内のw1_slaveファイルをcatして、温度を確認します。
t=の値が摂氏温度で1000倍にされた温度になっており、今回はt=23187でおよそ23.1℃とのことでした。5月初旬の室内なので確からしい値です。
$ cat /sys/bus/w1/devices/28-03009779ec2d/w1_slave
73 01 55 05 7f a5 a5 66 02 : crc=02 YES
73 01 55 05 7f a5 a5 66 02 t=23187
Pythonで温度取得する
先ほどのファイルからではなく、pythonでライブラリを使用して取得してみます。
w1thermsensorというライブラリで、pipでインストールができます。
$ pip install w1thermsensor
参考サイト様の実装を参照しつつ、問題なく摂氏と華氏を表示させることができました。
from w1thermsensor import W1ThermSensor, Unit
import time
sensor = W1ThermSensor()
while True:
temperature_in_celsius = sensor.get_temperature()
temperature_in_fahrenheit = sensor.get_temperature(Unit.DEGREES_F)
print("celsius: {0:.3f}".format(temperature_in_celsius))
print("fahrenheit: {0:.3f}".format(temperature_in_fahrenheit))
time.sleep(1.0)
$ python main.py
celsius: 22.125
fahrenheit: 72.050
celsius: 22.188
fahrenheit: 72.050
...
Firestoreにデータを保存する
今後の学習等で別のクライアントからデータを取得できるように、Firestoreに温度データを打ち上げるようにします。
Firestore初期設定
Firebaseでプロジェクトを作成 > Cloud Firestore > 本番モードでDBを作成します。
(プロジェクトは今回はそれっぽくThermWatcherとかつけておきました。)
stat
というコレクションを作成しておきます。
ラズパイからFirestoreにアクセスできるように、サービスアカウントを利用します。
Cloud Firestoreサイドメニュー > ギアアイコン > プロジェクトの設定 > サービスアカウント で設定画面に移動し、Firebase Admin SDKのPythonにチェックを入れて「新しい秘密鍵の生成」でJSONをダウンロードします。
ダウンロードしたJSONはラズパイにscpで送りました。
Firestoreへの書き込み
以下のコードで取得と書き込みを行います。
温度データに加え、センサーIDとタイムスタンプをDBに保存するようにしました。
実行時には、ダウンロードしたサービスアカウントのJSONファイルのパスをSA_FILE_PATHで指定します。
import os
import time
from w1thermsensor import W1ThermSensor, Unit
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
# Firestoreクライアント生成
cred = credentials.Certificate(os.getenv('SA_FILE_PATH'))
app = firebase_admin.initialize_app(cred)
db = firestore.client()
# センサークライアント生成
sensor = W1ThermSensor()
while True:
# 摂氏と華氏の取得
temperature_in_celsius = sensor.get_temperature()
temperature_in_fahrenheit = sensor.get_temperature(Unit.DEGREES_F)
# 保存するドキュメントの生成
data = {
'sensor_id': sensor.id,
'reporting_time': int(time.time()),
'temperature': {
'celsius': sensor.get_temperature(),
'fahrenheit': sensor.get_temperature(Unit.DEGREES_F),
}
}
# DBに保存
doc_ref = db.collection('stat').document()
doc_ref.set(data)
time.sleep(1.0)
JSONのファイルパスを指定して実行します。
$ SA_FILE_PATH=$HOME/sa.json python main.py
Firestoreを確認すると、無事書き込みができていました!
最後に
無事測定ができたので、今度はペットのケージに温度計入れて、取得したデータをDB経由でモバイルから参照...とかしていきたいです。
また今回は1つのセンサーのみでしたが、複数センサーを並列で扱うことも試せたらなと思います。
最後まで読んでいただき、ありがとうございました。
Discussion