これまでで温度測定ができるようになりましたが、このままでは「測定値を保存できない」「PCとPicoとの距離に制約がある」などの問題点があります。
これらを解決するためにPico WとWifiルータをWifiでつなぎ、PCからWifi経由で温度を測定する方法を考えました。
このシステムを構築するためにはWifiルータが必要です。インターネットに繋がってなくても大丈夫です。また、モバイルルーターでも可能です。
これまではPico WとPCをUSBケーブルでつなぎ、Thonnyから温度を測定するコードを送り戻ってきた値を表示していました。ここではPico WとPCを切り離して、温度測定することを目指します。流れとしては、
- Pico Wを充電アダプターなどの電源で起動する。
- PCのWebブラウザからPico Wにアクセスします。
- Pico Wではアクセスに基づき温度測定し、JSON形式で返す。
- PCでJSON形式のデータを受け取る。
以上を目指します。
Step 1 Pico WとWifiルータを接続する。
Pico WとPCをケーブルでつなぎ、下記のコードを実行します。ssidとパスワードはあなたが使用しているWifiルーターのssidをパスワードを入力してください。
import network
import time
ssid = "hoge" #Wifiルーターのssid
passwd = "hoge" #パスワード
wifi = network.WLAN( network.STA_IF )
wifi.active(True)
wifi.connect( ssid, passwd )
while wifi.isconnected() == False:
print("Try to connect wifi network.")
time.sleep( 1 )
wifi_status = wifi.ifconfig()
print ( "Connected network." )
print ( "IP Address:{} Netmask:{}".format( wifi_status[0], wifi_status[1] ))
print ( "Default Gateway:{} Name Server:{}".format (wifi_status[2],wifi_status[3]))
うまくつながると画面下段のシェルに下記のように表示されます。この値はWifiの環境により異なります。「”Connected network.”」の前に「”Try to connect wifi network.”」と何回か表示されることがあります。とりあえずIP Address、Netmask、Default Gateway、Name Serverの値は控えてください。
つながらない時は、ssidとパスワードを再確認してください。
Step 2 Pico WのIP Addressを固定する。
IP Addressの4番目の値(この場合”31″)はWifiルーターの接続状況によって変化します。この値が状況によって変化すると不都合なので、固定したいと思います。
Pico Wの起動時に静的IPアドレスを再設定するコードを自動的に実行することでIPアドレスを固定します。次のコードをPico Wに「boot.py
」という名前で保存します。ssidとパスワードはあなたが使用しているWifiルーターのssidをパスワードを入力してください。
import network
ssid = "hoge"
passwd = "hoge"
static_ip = "192.168.0.100"
subnet_mask = "255.255.255.0"
gateway = "192.168.0.1"
dns_server = "8.8.8.8"
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.ifconfig((static_ip, subnet_mask, gateway, dns_server))
wifi.connect(ssid, passwd)
static_ipは固定するIP Addressを入力します。仮に”31″で固定したい場合は、”100″を”31″にしてください。subnet_maskからdns_serverまでは先ほどメモした値を入力してください。
上記のコードを実行してエラーが出ないことを確認してください。次にPicoWに「boot.py
」という名前で保存することです。「boot.py
」という名前で保存するとPico Wが起動するとき最初にboot.py
が走ります。
boot.p
yを保存したらケーブルをPCから一度抜き、その後差し込みます。
その後次のコードを実行します。(再掲)
import network
import time
ssid = "hoge" #Wifiルーターのssid
passwd = "hoge" #パスワード
wifi = network.WLAN( network.STA_IF )
wifi.active(True)
wifi.connect( ssid, passwd )
while wifi.isconnected() == False:
print("Try to connect wifi network.")
time.sleep( 1 )
wifi_status = wifi.ifconfig()
print ( "Connected network." )
print ( "IP Address:{} Netmask:{}".format( wifi_status[0], wifi_status[1] ))
print ( "Default Gateway:{} Name Server:{}".format (wifi_status[2],wifi_status[3]))
IP Addressが固定したい値になっていることを確認します。私は”80″に固定しました。
Step 3 PCのWebブラウザからPico Wにアクセスし測定値を取得する。
Pico WをWebサーバーのように動かし、PCからのリクエストを受けて測定値を返します。最初はPico WにDS18B20温度センサーをセットしたもの(説明の都合上、「Pico Wセンサー」といいます。)をPCのUSB端子につなぎます。
次にThonnyで下記のコードを実行します。画面下段のシェルは次のようになります。IPアドレスのは自分が設定した値です。
from machine import Pin
import utime
import time
import socket
import network
import ds18x20
import onewire
import json # JSONモジュールをインポート
server_port = 80
#Wi-Fiネットワーク接続
ssid = "hoge"
passwd = "hoge"
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, passwd)
wifi = network.WLAN( network.STA_IF )
wifi.active( True )
wifi.connect( ssid, passwd )
while wifi.isconnected() == False:
print("Try to connect wifi network.")
utime.sleep( 1 )
wifi_status = wifi.ifconfig()
print( "Connected network." )
print( "IP Address:{} Netmask:{}".format( wifi_status[0], wifi_status[1] ) )
print( "Default Gateway:{} Name Server:{}".format( wifi_status[2], wifi_status[3] ) )
print( "-----" )
s = socket.socket()
s.bind( ( '0.0.0.0' , server_port ) )
s.listen( 1 )
dat = machine.Pin(4)
# 1-Wireバスの初期化
ds_sensor = ds18x20.DS18X20(onewire.OneWire(dat))
#RTCから現在時刻を取得するために必要
rtc = machine.RTC()
# 接続されている全センサーのROMアドレスを取得
roms = ds_sensor.scan()
print("Found DS devices:", roms)
if not roms:
print("No DS18B20 sensors found!")
raise SystemExit()
#RTCから現在時刻を取得するために必要
rtc = machine.RTC()
led = Pin("LED", Pin.OUT)
while True:
try:
( cl, addr ) = s.accept()
print( "Request form {}".format( addr ) )
req = cl.recv( 1024 )
print( "Client Request:" )
buf = str( req , 'utf-8' )
req_line = buf.split( '\r\n' )
for r in req_line:
if( r.startswith( 'GET / ' ) ):
# 温度を取得
ds_sensor.convert_temp()
utime.sleep(1) # 温度データの変換に時間がかかる
# 最初のセンサーの温度を読み取る
temp = ds_sensor.read_temp(roms[0])
# RTCから現在時刻を取得
datetime = rtc.datetime()
print("Temperature:", temp, "°C" , f" : {datetime[4]:02d}:{datetime[5]:02d}:{datetime[6]:02d}")
# JSONデータを生成
response_data = {"temperature": temp}
response_json = json.dumps(response_data)
# HTTPレスポンスを送信
cl.send("HTTP/1.0 200 OK\r\nContent-Type: application/json\r\n\r\n")
cl.send(response_json)
print("Sent JSON Response")
led.high()
time.sleep(1)
led.low()
break
cl.close()
except OSError as e:
cl.close()
print( "Disconnect form Client" )
PCのWebブラウザからPico Wセンサーにアクセスします。アドレスは「http://PicoWのIPアドレス/」です。
PCからのアクセスを受けてPico Wセンサーが測定値を返します。Pico Wセンサーが正常に動いている稼働確認するため、測定値を返したとき1秒間LEDが点灯するようにしてあります。
上のように測定値が戻ってきます。
PicoWセンサーをPCから切り離して動かす。
これまでPico WセンサーはPCから電源の供給を受けていましたが、PCから切り離したいと思います。
上記のThonnyのコードをPicoWに「main.py」という名前で保存します。
次にPico WのUSBケーブルを充電などにつなぎ、稼働させます。
PCのWebブラウザからPico Wセンサーにアクセスすると、先ほどのように測定値が戻ってきます。
戻り値にJSON形式で戻したのは、JSONファイルはデータを保続する形式として使用され、サーバーサイドからフロントエンドもしくはフロントエンドからサーバーサイドに渡せるため、データの受け渡しに最適な形式だからです。
最後に
Pico WセンサーとPCを切り離したことで、Wifiルーターの電波の届く範囲で温度測定が可能になりました。実用的にはPico Wはタッパーウェアなど防水機能のあるものに入れ、USBコードとセンサーを外に出すと良いでしょう。複数個所の温度測定を行う場合、Pico Wセンサーを必要な数を準備し、Pico WのIPアドレスの「80」を「81」などに変えてセットし、PCのWebブラウザからPico Wセンサーに「http://192.168.0.81/」アクセスすると81の測定値が戻ってきます。「boot.py
」の設定値も変更します。一つのPicoWに複数のDS18B20温度センサーをつなぐこともできますが、ここでは取り上げません。
測定したデータはPico Wに保存するスペースはほぼないので、Pico WセンサーにアクセスするPCに保存するのがベストだと思います。
PCからPico Wに一定の時間ごとにアクセスし、データを保続する処理については割愛します。
Pico WにADT7410を使った温度測定では初歩段階でつまづきましたが、偶然にもDS18B20温度センサーにたどり着き、チャットGPTなどの力を借りて無事動かすことができました。
Pico WがADT7410を認識したりしなくなったりするのはなぜなんでしょう。また4.7オームの抵抗がなぜ必要なのかも私にはわかりません。
コメント