RaspberryPi
DS18B20

Raspberry Piで1-Wireの温度センサーを利用する

More than 1 year has passed since last update.


Raspbeery PiとDS18B20

今回は比較的入手しやすいDS18B20を使います。


今更聞けない1-Wireの有効化方法

まずRaspberry Pi(Raspbian)上で1-Wireドライバを有効化します。

$ sudo raspi-config

Advanced Optionを選択。

AdvancedOption

カーソルでA9 1-Wireを選択

1-Wireを選択

1-Wireを有効にする

1-Wireを有効にする

続いて、起動時に読み込まれるように /boot/config.txt の最後に以下の行を追加します。

今回はGPIO4に接続するので、GPIOに以下のように設定

dtoverlay=w1-gpio-pullup,gpiopin=4


デジタル温度センサーDS18020とその派生製品

今回使う


3本足タイプ

image

おそらくパーツ屋さんではもっとも身近な足の長い3本線のタイプ。以下2つも基本的にこれを加工したもの。

別途プルアップ抵抗(2~10kΩ程度)が必要。


基板上にプルアップ抵抗を取り付けたもの

image

上記の3本脚タイプに抵抗をとりつけ、更にブレッドボードにさしやすいようにピンヘッダを装着したタイプ。

直接VCC,GND,GPIOに配線するだけなので扱いやすい。


ステンレス先端の防水ケーブルに封入されたタイプ

image

1メートルくらいの防水ケーブルに封入されており、室外や水温などの温度を取る用途向けにはこれを使うことになるでしょう。

電源をデータピン側から取るためVCCが不要な2本線のタイプと、VCC, GND, データの3本線のタイプがありますが、入手しやすいのは3本線のタイプ。

抵抗は内蔵されてないので別途用意する必要がある。

このタイプのケーブルは柔らかすぎてブレッドボードに刺さらないので、

赤がVCC, 黒がGND, 黄色がデータになっており、赤と黄色の間にプルアップ用の抵抗を挟む必要があります。

防水ケーブルの内側の銅線は柔らかすぎてそのままではブレッドボードには挿さらないので、ジャンプワイヤやピンヘッダとはんだで接合するなどして、挿しやすいように加工する必要があります。

参考までに、抵抗と一緒にワニ口クリップで止めるという安易な解決策を試みた例。

道具を借りる前提ならワニ口よりはんだやQIコネクタのほうが安くつくので、この方法はあまりおすすめはしません。

image


3本脚の接続方法

仕様書より抜粋

image

データシートによれば本体の黒い部分が曲面になってるほうが表で、平らなほうが裏らしい。

左からGND. DQ, Vddと書かれているが、それぞれRaspberryPi側のGND, 任意のGPIOポート、3.3Vに接続すればいい。

3.3Vとデータ線の間に4.7kΩ(必ずこの抵抗値でないといけないわけではないが、目安として)を配線する。


温度を計測する

1-Wireの温度計をプログラムらしいプログラムは不要です。

Raspbianには1-Wire接続のデバイスから容易に温度を取得するためのドライバが備わっており、これを用いて温度を取る際には、プログラミングらしいプログラミングをする必要はありません

ls -l /sys/bus/w1/devices/

image

28-XXXXXXXXXXXXXなどのディレクトリが配下にできていることを確認します。この各ディレクトリの下のw1_slaveをテキスト形式で開くと、その時点での計測温度を得ることができます。

fc 01 ff ff 7f ff ff ff ee : crc=ee YES

fc 01 ff ff 7f ff ff ff ee t=31750

t=31750と表示されているのが温度(摂氏を1000倍した整数)です。

これを1000.0で割れば欲しい値が取れます。

以下はRubyでの実装例。

#/usr/bin/ruby

device = '/sys/bus/w1/devices/28-xxxxxxxxxxxx/w1_slave'
# ~~~~~~~~~~~~~~~
# ここは適宜書き換えてください

loop {
File.open(device, "r") {|f|
f.gets
temp = f.gets.split('t=')[1].to_i
f.close
puts format("%s: %.1fC", Time.now, temp / 1000.0)
}
sleep(1)
}

こんな感じで1秒ごと(正確にはループ内部処理の分だけ1秒より若干長くなる)のログが取れてればOKです。

2016-08-07 14:39:10 +0900: 28.1C

2016-08-07 14:39:11 +0900: 28.7C
2016-08-07 14:39:12 +0900: 28.7C
2016-08-07 14:39:13 +0900: 28.7C
2016-08-07 14:39:14 +0900: 28.7C
2016-08-07 14:39:15 +0900: 28.7C
2016-08-07 14:39:16 +0900: 28.7C
2016-08-07 14:39:17 +0900: 28.7C
2016-08-07 14:39:18 +0900: 28.7C