ラズパイでDS18B20を使って水温を測るまで[1-Wire]

空芯菜とメダカのビオトープ
空芯菜とメダカのビオトープ

この記事では、Raspberry Piと防水加工された温度センサーDS18B20を使って水温を測れるようにしていく。記事の最後では、Pythonで1-Wireデータを読み取れるようにしていく。

DS18B20はデジタル温度センサーであり、1-Wire通信方法でデータを受信する。Raspberry Piには1-Wireドライバーが装備されているので、温度を簡単に読み取ることができた。

開発環境

今回の開発環境は次の通り。

項目バージョン
ラズパイRaspberry Pi zero WH
OSRaspbian 9.13
Python2.7.13/3.7.0
温度センサーDS18B20

Arduinoと水温計の応用例

Arduinoと水温計を組み合わせて、ビオトープやアクアリウムで使えそうな商品をご紹介します。

さらに、AC100V電源をラズパイなどでコントロールできると、やりたいことの幅が広がりますね!

ラズパイと温度センサーの配線

今回はRaspberry PiとDS18B20を次のように配線した。

ラズパイと温度センサーの配線
ラズパイと温度センサーの配線

ラズパイDS18B20
3.3VVdd
GPIO4DQ
GNDGND

3.3VとGPIO4の間に、4.7kΩのプルアップ抵抗を繋ぐ。

DS18B20の各ピン役割
DS18B20の各ピン役割

DS18B20のデータシートはこちら

ラズパイで1-Wireを有効にする

1-Wireの設定

Raspberry Pi OSには、1-Wireデータを読み取れるドライバーが内蔵されているので、それを使えるように有効化してく。$ sudo vi /boot/config.txt を実行してで下記内容を追加しよう。

dtoverlay=w1-gpio,gpiopin=4,pullup=y

追加したらRaspberry Piをリブートする。$ lsmod | grep w1 で次のように表示されればOK。これで1-Wireが有効になった。

w1_therm                7330  0
w1_gpio                 3171  0
wire                   32947  2 w1_gpio,w1_therm

温度を読み取ってみよう!

それではさっそく、DS18B20の温度を読み取ってみよう。温度センサが正しく接続されていれば、$ ls /sys/bus/w1/devices/ で次のように28-から始まるディレクトリが表示されるはず。

28-0301a279ec09@  w1_bus_master1@
  • 「28-」以降の「28-0301a279ec09」はセンサーデバイスが持つ固有ID。
  • @(アットマーク)はシンボリックリンクの意味。

28-0301a279ec09ディレクトリの中には、w1_slaveファイルがあるのでそれを読み取ると温度が確認できる。

$ cat /sys/bus/w1/devices/28-0301a279ec09/w1_slave
5c 01 55 05 7f a5 a5 66 50 : crc=50 YES
5c 01 55 05 7f a5 a5 66 50 t=21750

t=21750が温度で、現在の摂氏温度が1000倍にして表示されている。つまりこの場合だと、約21.7度だ。センサーを手で握って、もう一度確認してみよう。温度が変化するはず。

Pythonで1-Wireデータを読み取る

最後にこれらの1-WireデータをPythonで読み取れるようにしてみたい。

1-Wireのデータはテキストファイルに書き込まれているので、それをPythonで読み取ってパースすれば良さそうである。しかし、すでにPythonで1-Wireデータを扱いやすくしてくれるw1thermsensorライブラリがあるので、今回はそれを使ってみることにした。

w1thermsensorのインストール

Python3で動かしたかったので、次のようにしてインストールした。2.0.0a2でないと、インポートエラーになって使えなかったため、バージョン指定している。

$ pip3 install w1thermsensor==2.0.0a2

Pythonプログラム

摂氏温度と華氏温度を、1秒おきに表示するプログラムをPythonで書いてみたので参考に。

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)
記事に関するご質問などがあればTwitterへお返事ください。
この記事で紹介した商品
人気のラズパイ
人気のラズパイ周辺機器
Raspberry Piのオススメ入門書
関連記事