ラズベリーパイ pico wに搭載された無線(Wi-Fi)の使い方を公式サイトを参考に、実際に動かし難しかった事、また解かりずらかった点など、基本的な使い方を説明します。またthonnyは最新バージョンをお勧めします。私はthonny4.0.1でPico-Wの自動実行main.pyをstopボタンで止められませんでした。
概要
今回ははこちらの公式サイトのプログラムコードに従って動かしています。
無線(Wi-Fi)の使い方が詳しく載っていますので見てみてください。
動作環境
ラズベリーパイ Pico W
Windowsパソコン WIN10 か WIN11
開発環境Thonny(最新バージョン)4.1.3
プログラム検証
Raspberry Pi Pico W のセットアップ済み、またPicozeroの MicroPython ライブラリも設定済とします。
main.pyとして自動実行されるプログラムもthonny4.1.3は、STOPボタンで停止できました。
プログラムを停止しないとファイル書き込みや、新しいプログラムの実行ができません。
Pico WをWLANに接続する
まず初めに、各種ライブラリーをインポートします。
次に自分の環境のネットワークのssid password 設定します。
import network
import socket
from time import sleep
from picozero import pico_temp_sensor, pico_led
import machine
ssid = 'NAME OF YOUR WIFI NETWORK'
password = 'YOUR SECRET PASSWORD'
次にconnect関数を定義します。
詳細は下記です。
def connect():
#Connect to WLAN
#network.STA_IF はルーター接続モード
wlan = network.WLAN(network.STA_IF)
#ネットワークがアクティブか?
wlan.active(True)
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection…')
sleep(1)
print(wlan.ifconfig())
try:
connect()
except KeyboardInterrupt:
machine.reset()
下記のプログラムを実行して検証すると
import network
import socket
from time import sleep
from picozero import pico_temp_sensor, pico_led
import machine
ssid = 'NAME OF YOUR WIFI NETWORK'
password = 'YOUR SECRET PASSWORD'
def connect():
#Connect to WLAN
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
sleep(1)
print(wlan.ifconfig())
try:
connect()
except KeyboardInterrupt:
machine.reset()
下記の情報がプリントされれば接続成功ですが、内容は自身のネットワークより異なりります。
MPY: soft reboot
Waiting for connection…
Waiting for connection…
Waiting for connection…
(‘192.168.1.18’, ‘255.255.255.0’, ‘192.168.1.1’, ‘192.168.1.1’)
ifconfig()には IPアドレス、サブネットマスク、デフォルトゲートウェイ など合計4個が格納されているのが解ります。
またプログラムに間違えがなく、接続できない場合一度ピコWのUSB外し再接続して実行すると接続できます。
よく起こりますので注意してください。
上の接続関数は接続を試すもので、どこに接続されてるかわかるように実際はipアドレスプリントして返します。
ip = wlan.ifconfig()[0]
#configの1番目[0] ipアドレスだけとる
print(f’Connected on {ip}’)
#ipアドレスプリント
return ip
#ipアドレス
次にサーバーとブラウザーを接続するsocketを定義します。
def open_socket(ip):
# Open a socket
address = (ip, 80)
#ネットワークipアドレスと通常ブラウザーはポート80指定
connection = socket.socket()
connection.bind(address)
connection.listen(1)
return connection
# 1が返ってくれば正常接続です
ここまででピコサーバーとほかのパソコンの接続設定完了です
ウエブページ作成
ウエブページを作成します。
ピコWサーバはApacheなどと違います、他にも方法があるようですが、ここではf文字列(f”””……”””)で出力するみたいです。
そうすることで{}の中のデータを簡単に入れ変えることができます。
def webpage(temperature, state):
#Template HTML
html = f"""
<!DOCTYPE html>
<html>
<form action="./lighton">
<input type="submit" value="Light on" />
</form>
<form action="./lightoff">
<input type="submit" value="Light off" />
</form>
<p>LED is {state}</p>
<p>Temperature is {temperature}</p>
</body>
</html>
"""
return str(html)
赤文字の部分がHTML部分で、関数def webpage(temperature, state)の引数、temperature, stateの2個は{}の中の変数に置き換えてHtmlファイルを生成して返します。
ブラウザーからの情報を収集してLED制御
はじめ私は下のプログラムの部分をよく理解できませんでした。
ウエブサーバを起動して、リクエストは何かプリントしてみました。
def serve(connection):
#Start a web server
state = 'OFF'
pico_led.off()
temperature = 0
while True:
client = connection.accept()[0]
request = client.recv(1024)
request = str(request)
print(request)
client.close()
この様なことでした。
ブラウザーからピコサーバーに接続要求するとrequestには下記のような情報の文字列が入ってくるのが解ります。
b’GET / HTTP/1.1\r\nHost: 192.168.1.18\r\nConne:……. 192.168.1.18/からのリクエスト
b’GET /favicon.ico HTTP/1.1\r\nHost: 192.168.1.18\r\n
b’GET /lighton? HTTP/1.1\r\nHost: 192.168.1.18\…… 192.168.1.18/lighton?からリクエスト
b’GET /favicon.ico HTTP/1.1\r\nHost: 192.168.1.18\r…
b’GET /lightoff? HTTP/1.1\r\nHost: 192.168.1.18\r…. 192.168.1.18/lightoff?からリクエスト
b’GET /favicon.ico HTTP/1.1\r\nHost: 192.168.1.18\r….
つまりrequestのブランク区切りの文字列をlistにして 2番目の情報で判断すればLEDをオンオフできます。
サーバーを動かすときはprint(request)は必要ありません。
それで、これがrequestで判定してLEDをON、OFFするプログラムです。
def serve(connection):
#Start a web server
state = 'OFF'
pico_led.off()
temperature = 0
while True:
client = connection.accept()[0]
request = client.recv(1024)
request = str(request)
try:
request = request.split()[1]
#split()関数で文字列をlistにして[1]2番目とる
except IndexError:
pass
if request == '/lighton?':
pico_led.on()
state = 'ON'
elif request =='/lightoff?':
pico_led.off()
state = 'OFF'
temperature = pico_temp_sensor.temp
html = webpage(temperature, state)
client.send(html)
client.close()
完成したプログラム
おまけに時刻、ジャバスクリプトも入れてみました、動きました。
now = time.localtime()はパソコンに接続したピコWでソニーから動かすと正しく日、時刻など表示されますが、main.pyで自動で動かすと、はじめ2022 1 1 0 0になります。
次はmain.pyで動かした場合も正しく時刻、また他のGPIOに接続したセンサーの値も表示したいと思います。
import network
import socket
from time import sleep
from picozero import pico_temp_sensor, pico_led
import machine
import time
# Wi-Fi ルーターのSSIDとパスワード
# 自分の環境に書き換えてください。
ssid = '???????'
password = '????????'
def connect():
#Connect to WLAN
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
sleep(1)
ip = wlan.ifconfig()[0]
print(f'Connected on {ip}')
return ip
def webpage(temperature, state,nen,ma,da,ta,mi):
#Template HTML
html = f"""
<!DOCTYPE html>
<html>
<form action="./lighton">
<input type="submit" value="Light on" />
</form>
<form action="./lightoff">
<input type="submit" value="Light off" />
</form>
<p>LED is {state}</p>
<p>Temperature is {temperature}</p>
<p>date is {nen} {ma} {da} {ta} {mi}</p>
<script>
var date001 = new Date();
document.writeln(date001);
</script>
</body>
</html>
"""
return str(html)
def serve(connection):
#Start a web server
state = 'OFF'
pico_led.off()
temperature = 0
while True:
client = connection.accept()[0]
request = client.recv(1024)
request = str(request)
print(request)
try:
request = request.split()[ 1]
except IndexError:
pass
if request == '/lighton?':
pico_led.on()
state = 'ON'
elif request =='/lightoff?':
pico_led.off()
state = 'OFF'
temperature = pico_temp_sensor.temp
now = time.localtime()
html = webpage(temperature, state,now[0],now[1],now[2],now[3],now[4])
client.send(html)
client.close()
def open_socket(ip):
# Open a socket
address = (ip, 80)
connection = socket.socket()
connection.bind(address)
connection.listen(1)
return connection
try:
ip = connect()
connection = open_socket(ip)
serve(connection)
except KeyboardInterrupt:
machine.reset()
実際に接続したときのブラウザーの画面です。
実際は英語表示ですが、下はブラウザーが日本語に変換した画面で、ピコサーバーはHTMLファイルの中に日本語を入れられないようです。
間違え入れられます。
HTMLに <html lang=”ja”> <meta charset=”UTF-8″> を追記すればできます。
正しく動いています、これを基に工夫すれば色々面白いことができそうです。