温度センサーDS18B20内蔵温度プローブの動作実験

1. 概要

水産養殖などで使用する水槽の水温を測定する温度センサは、防水でかつ複数個所を同時に測定する必要がある。本投稿で動作実験を行う温度プローブは、温度センサDS18B20を内蔵した防水温度計である。DS18B20は、interfaceとして電源とGNDと1本のデータ線だけを必要する1Wire bus方式を採用している。1wire bus方式は、高速での通信は難しいが、長いケーブルでも安定した通信が可能になるのと、複数の温度計をパラレルに接続できるのが特徴である。

本投稿では、DS18B20を内蔵した温度プローブをRaspberry Piに接続して動作確認を行い、最終的に6本をパラレルに接続し、6本のデータをクラウドに送るところまでを実験する。

2. DS18B20の仕様

2.1. DS18B20とRaspberry Piの接続

温度センサDS18B20内蔵の温度プローブの写真を次に載せます。

この先端の部分に温度センサDS18B20が内蔵されています。信号線が3本出ており、赤が電源、黒がGND、黄色がデータ信号です。

温度センサDS18B20の電源電圧範囲は3.0Vから5.5Vで、測定温度範囲は-55℃から125℃です。測定精度は、±0.5℃@-10℃~85℃です。

次に、ブロック図を示します。このブロック図から、データ信号線に4.7kΩのプルアップ抵抗が必要なことが分かります。

そこで、Raspberry PiのGPIOと次のように接続します。

2.2. DS18B20のデータ読み出し

ここでは、以下の2つの方法で、DS18B20の動作の確認を行う。

  1. Raspberry Pi 4の1wire Interfaceを使用して動作確認
  2. Python のW1ThermSensor ライブラリを使用して動作確認

Node-REDに組み込む際には、b. を使用する。

2.2.1. Raspberry Pi 4の1wire Interfaceを使用して動作確認

1) Raspberry Piの1wire Interfaceを有効にする

・ バージョンアップ実施

$ sudo apt update

$ sudo apt upgrade –y

・ sudo nano /boot/config.txtで以下を追記する。

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

・ リブートする。

・ 確認

$ lsmod | grep w1

以下のようにw1_gpioが表示されれば、1wireのGPIOのインターフェースが使用可能になっている。

2) 読み出しデータの確認

DS18B20は、それぞれのデバイスが固有のID番号を持っている。

Raspberry Piの1wire GPIOを有効にすると、以下のディレクトリにその固有のID番号のディレクトリが作成される。そして、その中に温度測定結果が格納される。

・まず、以下のディレクトリを確認する。

$ ls /sys/bus/w1/devices/

28-(固有ID番号)のフォルダが確認できる。今回のID番号は、’3c01f096c4bd’である。

・28-(固有ID番号)のフォルダの中身を確認する。

$ ls /sys/bus/w1/devices/3c01f096c4bd/

フォルダがいくつか存在する。この中の’w1_slave’に測定結果が格納されている。

・測定結果を見る。見るたびにデータが読み出される。

$ cat /sys/bus/w1/devices/2c01f096c4bd/w1_slave

温度は、2行目のt=23000である。1/1000にしたのが温度で、この場合はt=23.000℃である。

ここでは、センサの金属筒を手で握り3回読み出してみた。3回目で数字が動いている(t=31.937℃)。体温で温められ、30℃を超えた。

2.2.2. Python のW1ThermSensor ライブラリを使用して動作確認

次に、PythonのW1ThermSensorライブラリを使用して動作確認を行う。

プログラム例を以下に示す。

from w1thermsensor import W1ThermSensor # W1ThermSensorライブラリの読込み
import time
sensor = W1ThermSensor() # 接続されているセンサを読む

while True: 
    for sensor in W1ThermSensor.get_available_sensors(): # 接続されているセンサの数だけ以下を実施。
        print("Sensor %s has temperature %.2f" % (sensor.id, sensor.get_temperature())) # センサIDと温度を取得

time.sleep(1.0)

このプログラムは、接続されているセンサが複数ある場合にも動作する。

以下に2個のセンサをパラレルに接続した場合の結果を示す。

センサのIDが2種類あるのが分かる。

  1. 3c01f0961a6f
  2. 3c01f096c4bd

測定結果の温度は同じ値である。

複数のDS18B20センサを接続する場合には、以下のように単純にパラレルに接続するだけでよい。

参考HP)w1thermsensor

3. Node-REDに組み込みクラウドに上げる

ここまでで、DS18B20の温度プローブをRaspberry Piに接続し温度情報を得ることができた。次に、取得した温度情報をクラウドに上げる実験を行う。

そのために、以下の3つの手順で行う。

  1. Pythonで取得したデータをRaspberry内のNode-REDに上げる
  2. Raspberry PiのNode-REDからクラウドのNode-REDに送信する
  3. クラウドのNode-REDで受信し、dashboardでグラフ表示する

3.1. pythonで取得したデータをRaspberry Pi内のNode-REDに上げる

3.1.1. pythonプログラムの作成

まず前項でPythonを使って取得したデータをRaspberry Pi内のNode-REDに上げる(送る)ことを行う。

ここでは、http-requestをを使用してデータを送る。

下図に示すように、

  1. Python3でDS18B20センサからidとdataを取得する
  2. http-reqestでNode-REDに送信する
  3. Node-REDは受信したらresponseを返す

 

http-requestのシーケンスを追加したpython3プログラムを以下に示す。

#
# DS18B20_multi_http.py
# Read DS18B20 Temperature Sensor and send data to node-red on localhost
# Rev 0.01: 2022/03/19
#
import time
import json
import urllib.request
from w1thermsensor import W1ThermSensor

url = ‘http://127.0.0.1:1880/temperature’

# main code
def main():
    sensor = W1ThermSensor()
    data = { # 辞書型データ
        ‘sensor’: ‘sensor_id’,
        ‘temp’: 20.0
    }

    while True:
        for sensor in W1ThermSensor.get_available_sensors():
            sensor_id = sensor.id # read id from sensor
            sensor_temp = sensor.get_temperature() # read data from sensor
            print(“Sensor %s has temperature %.2f” % (sensor_id, sensor_temp))
           data[‘sensor’] = sensor_id
           data[‘temp’] = round(sensor_temp, 2)
           res = contact(data) # send temperature data

        time.sleep(1.0) # wait 1 second

def contact(data): # Node-REDとの通信
    headers = {‘Content-Type’: ‘application/json’,}

    req = urllib.request.Request(url, json.dumps(data).encode(), headers)
    try:
        with urllib.request.urlopen(req) as res:
        body = res.read()
    except urllib.error.HTTPError as err:
        print(err.code)
    except urllib.error.URLError as err:
        print(err.reason)

    print(‘code’,res.getcode())

    return(body)

if __name__ == “__main__”:
    main()

3.1.2. Node-REDへのpythonプログラムの組み込み

以下に、Raspberry PiのNode-REDでの記載に関してまとめる。

上側のインジェクトノードからexecノードのラインが、DS18B20からのidとdataを受けるためのプログラムをpython3で実行するためのフロー。execノードの実行コマンドの注意事項は、プログラムのパスをフルパスで記載すること。

下側のhttp inノードとhttp responseノードがデータを受け取るフロー。http inノードの注意事項は、メソッドをPOSTにすること。http responseノードは変更する必要なし。

3.2. Raspberry PiのNode-REDからクラウドのNode-REDに送信する

Raspberry Piからクラウドに上げる(送る)のもhttp-reqestを使う。

クラウドのNode-REDに送信するためのRaspberry Pi側のNode-REDの記述に関して次にまとめる。

下側のフローにswitchノード、changeノード、流量制限ノード、http-requestノードを追加する。

注意事項としては、ここでのhttp-requestのメソッドはGETにする。

3.3. クラウドのNode-REDで受信し、dashboardでグラフ表示する

クラウドにNode-REDを立ち上げる方法に関しては、応用事例の記事の以下を参照ください。

  1. GCPのアカウント作成
  2. GCP上にUbuntuを立ち上げる
  3. GCPのUbuntuを使ってみる
  4. Node-REDのセキュリティ対策

クラウド側のNod-REDで受信して、dashboardでグラフ表示するNode-REDの記述を下記に示す。

上側がデータ入力のフローである。http inノードとhttp reqponseノードで構成する。http inノードのメソッドはGETとする。URLは、Raspberry PiのNode-REDのhttp requestノードの記載と合わせる。ここでは、’/DS18B20’である。

下側が、グラフ表示のフローである。一つ目のchangeノードで送られてきたmsg.payload.data1のデータをmsg.payload.temp.valに代入し、単位degを、msg.payload.temp.unitsに追加している。2つ目のswitchノードで、センサの名前(msg.payload.sensor)で分ける。3つ目のchangeノードは、チャート表示のためにデータを移し替える作業を行っている。

 

上記のダッシュボードの設定の結果が以下である。

4. クラウド上でデータベースに記録する

クラウド上にMySQLを立ち上げる方法に関しては、下記記事を参考にしてください。

「クラウド上のデータベース構築(MySQL版)

クラウド上のデータベース(MySQL)に6本のDS18B20のデータを蓄える。

4.1. データベースの追加

クラウド上のMySQLにデータベースを追加する。

データベース名:aqacul_db

$ sudo mysql –u root –p

mysql > create database aqacul_db;

4.2.ユーザーの作成

上記で作成した’aqacul_db’のみを使用できるユーザーを作成する。

$ sudo mysql –u root –p
mysql> create user aqacul@’%’ identified by ‘パスワード’;
mysql> grant create, alter, drop, insert, update, delete, select, references on aqacul_db.* to aqacul@'%’;

3行目のon aqacul_db.*の部分の記述が、データベースを限定する記述である。

以下では、作成したユーザー一覧と権限の確認を行っている。

4.3. テーブルの作成

次に、テーブルの作成を行う。まず、テーブルを設計する。

4.3.1. DS18B20用基本テーブルの設計

基本構成は、「クラウド上のデータベース構築(MySQL版)と同じであるが、例1と例2の列のように中身は異なる。

4.3.2 アトリビュート(属性)テーブルとデータテーブルの設計

アトリビュートテーブルとデータテーブルを設計する。これも基本は、「クラウド上のデータベース構築(MySQL版)と同じである。

1) アトリビュートテーブル

2) データテーブル

4.3.3. テーブルの作成

新規に作成した’aqacul’ユーザーでログインし、アトリビュートテーブルとデータテーブルを作成する。

次に、アトリビュートテーブルにデータを登録する。

4.4. データの登録

4.4.1. DS18B20を6本パラレルに接続

DS18B20を以下のように6本パラレルに接続する。

4.4.2. Raspberry Pi側のNode-REDの記述の修正

次のNode-REDのフローに示すように、受信したデータを6本のセンサのIDを確認してクラウド上にデータを上げる。

4.4.3. クラウド側のNode-REDの記述修正

クラウド側のNode-REDの記述の修正は、以下のようにダッシュボード側の追加修正だけになる。データベース側のフローの修正は必要ない。

次に、データベースに登録が開始された状態でのデータベースの確認結果を示す。DS12B80_00~DS12B80_05の6個の種類のデータが確認できた。

6個の温度センサのダッシュボード画面を以下に示します。