はじめに
RaspberryPi5で、Python(Cpython)を使って「DS18B20」を使う方法を解説したいと思います。
「DS18B20」は接続が簡単で、短いプログラムで使用できる「防水の」温度センサーです。屋外や水槽、畑などの温度を測りたい方におすすめです。
~ この記事の内容 / Contents ~
DS18B20
通信線が1本だけの「1-Wire」方式を採用した、安くて高性能な温度センサーです。測定範囲も -55℃~+125℃までとかなり広く、0.5℃精度で測定できます。
今回使用するものは防水タイプなので、ベランダ・庭・花壇・畑・水槽など、屋外のDIYに最適です。
アナログからデンタルなどの変換は不要で、RaspberryPi5に直接データが取り込めるので、データのロギング・グラフ化、遠隔監視など、IoT化にも相性もばっちりです。
接続基板付きキット
記事ではDS18B20を加工なしでそのまま接続できる「Gravity: 防水 DS18B20 温度センサーキット」を使用しています。
DS18B20の配線は少々細めで、ブレッドボードにはそのまま挿せません。また1-Wireは電源線とデータ線の間に4.7kΩのプルアップ抵抗の取り付けが必要です。
その点、このキットは端子台とプルアップ抵抗が内蔵された接続基板が付いているので、配線加工なしでラズパイとつなぐことができます。
UnPack
開封時の画像です。梱包やラベリングもキレイ、基板はお菓子のようなパッケージに密封されています。外観や使用時の異常もなく安心して使うことができました。
キット内容
- DS18B20(1m)
- 端子台・プルアップ抵抗付き 接続基板
- メス-メスのコネクタ付配線
※ メス-メスコネクタとRaspberryPiを繋ぐには、別途メス-オスのジャンパワイヤが必要です。
環境
この記事で使用する環境は以下の通りです。
環境 | 内容 | 備考 |
OS | RaspberryPi OS | bookworm |
言語 | Python | Ver.3.11.2 |
ライブラリ | w1thermsensor | Ver.2.3.0 |
ボード | RaspberryPi 5 |
RaspberryPiとDS18B20の接続
RaspberryPi5とDS18B20の接続方法は以下の通りです。
上の図は「接続基板」を省略しています。センサを直接つなぐ場合はプルアップ抵抗が必要です
ピンアサイン
※ RaspberryPi 公式のGitHubより引用
使用する部品
RaspberryPi5
RaspberryPi 5技適も取得されて、国内販売品もだいぶ出回るようになりました。マイクロSDも忘れずに用意してください。
RaspberryPi 5 電源
RaspberryP 5は、5v5Aという特殊な仕様の電源アダプタが必要です。公式は少し高いので私はPSEマーク付きのこちらのものを使っています。
DS18B20温度センサー
前述した温度センサーキットです。記事で使っているものは、実際に以下のAmazonのリンクから購入しています。
※付属のセンサは1mです。センサ単体の2m版はこちらです。
プログラム概要
今回のプログラムの概要は以下の通りです。
- 温度センサのオブジェクトを作成
- 温度取得
1-Wireの有効化
1-Wireはデフォルトでは無効化されているため、有効化の設定を行います。以下のコマンドで設定画面を表示します。
ここでは端末から実行する方法を解説しますが、デスクトップ左上の「ラズパイマーク」→「設定」→「RaspberryPiの設定」から設定もできます。
sudo raspi-config
「3 Inteface Options」→「17 1-Wire」の順に選択(Enterキー)します。
1-Wireを有効化(Enable)してよいか聞かれるので「Yes」を選択します。選択すると有効化完了のメッセージが表示されるので「Ok」を選択します。
最初の画面に戻るので、一番下の「Finish」を選択します。再起動(reboot)してよいかの確認画面が表示されるので「Yes」を選択します。
選択後、自動的に再起動が始まります。再起動が完了したら1-Wireの有効化は完了です。
1-Wireの動作確認
有効化が完了後、以下のコマンドで1-Wireの動作確認を行います。
※DS18B20を接続した状態で実行してください。
ls /sys/bus/w1/devices/
下記ように「28-XXXXXXXX」のようなディレクトリが表示されていれば有効化は完了です(数字はセンサーごとに違います)。
28-00000f8ba9f6 w1_bus_master1
ディレクトリが表示されていたのに、突然消えた(表示されなくなる)という方は、以下のカーネルのアップデートを行ってください。
カーネルのアップデート
「センサのディレクトリが表示されなくなる」「プログラム実行時に頻繁に読み取りに失敗する」という方は、以下のコマンドでカーネルのアップデートを試してみてください。
※ 問題が出ていない場合は、以下の操作は不要です。
sudo apt update -y
sudo apt upgrade -y
私は以下のバージョンを使用していた際に、前述の現象が発生。最新バージョンにすることで、現象が発生しなくなりました。
更新前 | Linux raspberrypi 6.1.0-rpi7-rpi-2712 |
更新後 | Linux raspberrypi 6.6.31+rpt-rpi-2712 |
Python仮想環境の構築
以下のコマンドでPythonの仮想環境を構築します。
cd ~/
python3 -m venv env --system-site-packages
構築完了後、以下のコマンドで仮想環境を有効化してください。
source ~/env/bin/activate
コマンドの実行後、以下のように「(env)」と表示されれば有効化は完了です。そのままの状態でライブラリのインストールに進んでください。
esu@raspberrypi:~ $ source ~/env/bin/activate
(env) esu@raspberrypi:~ $
前述の仮想環境の有効化後に端末を閉じてしまったり、中断してライブラリのインストールを再開した時は、再度以下のコマンドを実行してから、インストールを再開してください。
source ~/env/bin/activate
仮想環境を終了したい時は、以下の「deactivate」コマンドで終了できます。
(env) esu@raspberrypi:~ $ deactivate
esu@raspberrypi:~ $
ライブラリのインストール
以下のコマンドでPythonプログラムから使うライブラリをインストールします。
仮想環境を有効化した状態で、以下のコマンドを実行してください。
pip install w1thermsensor
実行結果
後述するコードの実行結果は以下の通りです。
他の防水型のセンサを持っていないので比較はできていませんが、25度設定の室内に1時間程置いた水なので、おおむね正しい値が出ていると思います。
26.75度
26.6875度
26.75度
26.75度
26.75度
26.75度
26.75度
26.75度
全体コード
全体コードは以下の通りです。詳細な内容は後述する「コードのポイント」で解説します。
from w1thermsensor import W1ThermSensor, Unit, Sensor
import time, sys
# IDを指定して、温度センサーのオブジェクトを作成
sensor = W1ThermSensor(sensor_type=Sensor.DS18B20, sensor_id="00000f8ba9f6")
while True:
try:
# 温度を取得
temperature_in_celsius = sensor.get_temperature()
# 温度値をコンソールに出力
print( str(temperature_in_celsius) + "度" )
except Exception as e:
print( e.args )
print("読み取りに失敗しました"+ e.args )
# 1秒待つ
time.sleep(1)
プログラムの実行方法
プログラムのあるディレクトリで以下のコマンドを実行してください。
source ~/env/bin/activate
python3 ds18b20.py
コードのポイント
オブジェクトの作成
センサの型式とIDを指定して、センサ用のオブジェクトを生成します。
1-Wireのデバイスには64bitの固有のIDが振られているため、そのIDを指定してオブジェクトを生成します。
IDは動作確認時に使用した、/sys/bus/w1/devicesの下のディレクトリ名(先頭の28-を除いたもの)を指定してください。
# IDを指定して、温度センサーのオブジェクトを作成
sensor = W1ThermSensor(sensor_type=Sensor.DS18B20, sensor_id="00000f8ba9f6")
温度を取得して表示
get_temperature関数で温度(摂氏)を取得して表示します。
# 温度を取得
temperature_in_celsius = sensor.get_temperature()
# 温度値をコンソールに出力
print( str(temperature_in_celsius) + "度" )
失敗時の例外処理
前述したカーネルの問題による温度取得に失敗すると、例外が送出されてプログラムが停止してしまいます。
そのため、以下の「try-except」の記述でプログラムの停止ではなく、エラー発生と内容表示のみを行うようにしています。
try:
# ~~~~~ 中略 ~~~~~
except Exception as e:
print( e.args )
print("読み取りに失敗しました"+ e.args )
まとめ
RaspberryPi5で、Python(Cpython)を使って1-Wire方式の防水温度計「DS18B20」を使う方法を解説しました。
キットを使えば配線も簡単、コード短く書けるので、屋外の管理をDIYしたい方はぜひ使ってみてください。
参考になればうれしいです。
おすすめの最新書籍
今月号の日経Interfaceは「Linuxチューニング術50」
今月号のInterfaceは『Linux チューニング術 50』です。
Linuxを組み込んだ機器を”本格的”に作ろうとすると「起動を早くしたい」「いきなり電源を切られてもデータを守りたい」など、対応が必要なチューニングはおおいですよね。
今回の記事は、「カーネルをいじらない」方法でチューニングを行う方法が解説されています。
こういった”実用的”な特集はレアですし、知っておいても損はない情報だと思います。
私も仕事でこの手の問題に何度も遭遇していますが、こういったOSレベルの難しそうな設定を、さらっとできちゃう人はかっこいいですよね。
興味のある方は、以下のリンクから確認できます。
質問・要望 大歓迎です
「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。
使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。