Raspberry Pi Pico WとDS18B20温度センサーで温度を測ってみた(2)

Raspberry Pi

 これまでで温度測定ができるようになりましたが、このままでは「測定値を保存できない」「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.pyを保存したらケーブルを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オームの抵抗がなぜ必要なのかも私にはわかりません。

Raspberry Pi Pico WとDS18B20温度センサーで温度を測ってみた(1) に戻る。

コメント

タイトルとURLをコピーしました