Arduino + DS18B20で温度モニタ

連日30℃を超える日々により、ただただ作業部屋が暑い。
部屋に温度計がないのでしばらくは体感温度だけで様子を見ていたが、暑い日が続くと
エアコンや扇風機やらの冷房機器がちゃんと効いているか室温をモニタしたくなった。

Amazonで温度計を購入してくればここで終わりなのだが、せっかくなので手持ちの工具で
温度が測れないかみたところ、以前Aliexpressで購入した温度センサ(DS18B20)が
一つ見つかったので、Arduinoと繋げてPCから温度をモニタするよう工作することに。

DS18B20は最大12bitの分解能、1-Wire通信で温度計測ができるIC。
1-WireとDS18B20のArduinoのライブラリが以下のgithubのURLで公開されているのでこれを利用することにした。

https://github.com/PaulStoffregen/OneWire
https://github.com/milesburton/Arduino-Temperature-Control-Library

配線は以下の通り。回路が簡単なので、ブレッドボードを使って手組みし動作を確認してみることにした。

各々のURLからzipファイルをダウンロードし、ArudinoのIDEから
「ファイル」→「スケッチ」→「ライブラリをインクルード」→「.ZIP形式のライブラリをインストール」を選んで
ライブラリを登録する。

ソースコードは以下のものを用意してコンパイルして書き込み。12bit分解能で約2秒毎ごとに温度を計測するようにした。

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 10 // port number D10
#define TEMPERATURE_PRECISION 12 // sensor resolution: 9 - 12bit

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;

void setup(void) {
  Serial.begin(38400); //set baudrate
  
  sensors.getAddress(tempDeviceAddress, 0); // get device0 address
  sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION); // set resolution

  sensors.begin();
}

void loop(void) {
  sensors.requestTemperatures(); // request temp.
  Serial.println(sensors.getTempCByIndex(0)); // get temp. from device 0 and send serial
  delay(2000); // 2sec wait
}

シリアルモニタで動作しているか見てみると、ちょうど最小分解能(0.0625℃)で計測している様子。

Arduinoでの温度ICとの通信は完了。
ただ、モニタするのにシリアルターミナルを開いて…、という面倒なことは普段しないので、
次にPython+GUIでダブルクリックで起動、モニタできる簡易アプリケーションを作ることに。

GUIは標準のtkinterを使ってDS18B20の温度結果をシンプルにテキストで毎回更新するだけにし、Arudinoとのシリアル通信にはpyserialを使って通信させることにした。

# gui_DS18B20.py

import tkinter as tk
import time
import serial as ser

class App(tk.Frame):
    
    def __init__(self, master=None):
        super().__init__(master)
        
        # init Serial
        self.com = ser.Serial('COM3', 38400)
        self.temp = 23.00
        self.temp_text = "{:5.2f}℃"
        
        #_tmp = self.com.readlines() # clear
        
        master.title("DS18B20 Temp.")
        
        master.geometry("250x50")
        master.protocol("WM_DELETE_WINDOW", self.delete_window)
        
        self.timer_on = False
        self.pack()
        
        self.label = tk.Label(master, text="",font=("Helvetica",32))
        self.label.pack(fill='both')
        #self.canvas_time.pack(fill='x')
        
        self.after(2000, self.read_temp )
        
    def delete_window(self):
        self.com.close()
        self.master.destroy()
        
    def read_temp(self):
        # read temp
        #tmpdata = self.com.readlines()
        self.temp = float(self.com.readline().strip())
        self.com.read(0 or self.com.in_waiting)
        self.label["text"]=self.temp_text.format(self.temp)
        self.after(2000,self.read_temp )

root = tk.Tk()

app = App(master=root)
app.mainloop()

実行すると以下のアプリが起動。

GUIの起動が確認できたので、後ははpyinstallerを使ってoneファイルのEXE実行形式にする。

pyinstaller gui_DS18B20.py -onefile -noconsole

distフォルダに「gui_DS18B20.exe」が生成されるので、これを実行すると上の同じGUIが起動。

これでひとまず室内温度をPCからモニタすることができるようになったので、満足。

 


※しかし、朝の6時台ですでに31℃近くあるとは。。。
室内の温度をモニタしていると水分補給と早めの冷房ONは必要だというのがわかってくるので、室温を測るのは大事。