RasberryPi4を主体としてRaspberryPiPicoWに実装したセンサの値を読み取ったりモーターや電磁弁の制御をできるようにしたい。最終的にはおうちで育ててる花の自動水やりシステムとかにしたい。
全体のイメージはこんな感じ(PicoWのUSBポートからWiFiが飛んでるような絵になってしまった)
アクセスポイントにするRaspberryPi4はGUI操作のままできるのでVNCも使えて初心者にはうれしい。
ネットワーク機器を自作するとセキュリティの問題までついてきて素人の手に余るのでアクセスポイントはブリッジせずに独立させた状態で使う。さらにPicoWのMACアドレスに固定IPを割り当てて登録済みのMAC以外は接続できない設定にすればとりあえずは大丈夫なんじゃないかなと思う。外部のネットワークと接するRaspberryPi4のセキュリティには気を付ける(とはいっても公式でサポートしてるVNCをそのまま使うだけなんだけど)。
まずはRaspberryPi4をアクセスポイント化する。
公式にチュートリアルがあるのでこれをそのまま適用した
https://www.raspberrypi.com/documentation/computers/configuration.html#setting-up-a-routed-wireless-access-point
必要なソフトウェアをインストール
sudo apt install hostapd
sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo apt install dnsmasq
sudo DEBIAN_FRONTEND=noninteractive apt install -y netfilter-persistent iptables-persistent
ネットワークルーターを設定
sudo vim /etc/dhcpcd.conf
interface wlan0
static ip_address=192.168.4.1/24
nohook wpa_supplicant
"Enable Routing and IP Masquerading"の項目は省略する。
DHCPとDNSサーバーを設定
sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
sudo nano /etc/dnsmasq.conf
interface=wlan0 # Listening interface
dhcp-range=192.168.4.2,192.168.4.20,255.255.255.0,24h
# Pool of IP addresses served via DHCP
domain=wlan # Local wireless DNS domain
address=/gw.wlan/192.168.4.1
# Alias for this router
公式のチュートリアルでは192.168.4.2から192.168.4.20をプールする設定となっていたのでそのまま使う
WiFiの有効化
sudo rfkill unblock wlan
APの設定
sudo vim /etc/hostapd/hostapd.conf
country_code=JP
interface=wlan0
ssid=NameOfNetwork
hw_mode=g
channel=7
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=AardvarkBadgerHedgehog
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
セキュリティのためSSIDとパスフレーズはちゃんと設定しよう。
hw_modeの設定については
a = IEEE 802.11a (5 GHz) (Raspberry Pi 3B+ 以降)
b = IEEE 802.11b (2.4 GHz)
g = IEEE 802.11g (2.4 GHz)
となっているおりPicoWを接続するのでhw_mode=g
とした
今回はこのアクセスポイントにPicoWを接続して使うのでPicoWのMACアドレスに対して
静的IPを割り当てる設定と登録済みMAC以外の端末の接続を拒否する設定を追記
sudo vim /etc/dnsmasq.conf
設定ファイルを開いて
### Set static IP ###
dhcp-host=AA:BB:CC:DD:EE:FF,192.168.4.20
### Ignore unknown MAC ###
dhcp-ignore=tag:!known
以上を追記する。
PicoWのMACアドレスについてはPicoWの公式ドキュメント"3.7. The MAC address"に記述があり
import network
import ubinascii
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
print(mac)
# Other things you can query
print(wlan.config('channel'))
print(wlan.config('essid'))
print(wlan.config('txpower'))
というコードを実行すれば取得できる。
MACアドレスの書き換えができるのかどうかは分からなかった。
設定ができたら再起動する。アクセスポイントが起動しない場合ばraspi-configからWiFiの設定をJPになおすとたぶん動く。
ネットワークが上手く動いてるかどうかのテストは公式のPcoWのチュートリアルにある
https://projects.raspberrypi.org/en/projects/get-started-pico-w/
PicoWでwebwerverを起動するコードで試した
import network
import socket
from time import sleep
from picozero import pico_temp_sensor, pico_led
import machine
ssid = 'NameOfNetwork'
password = 'AardvarkBadgerHedgehog'
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(5)
ip = wlan.ifconfig()[0]
print(f'Connected on {ip}')
return ip
def open_socket(ip):
# Open a socket
address = (ip, 80)
connection = socket.socket()
connection.bind(address)
connection.listen(1)
return connection
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)
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]
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()
try:
ip = connect()
connection = open_socket(ip)
serve(connection)
except KeyboardInterrupt:
machine.reset()
アクセスポイントとしているRaspberryPi4本体かアクセスポイントに接続している端末から、PicoWがネットワークに接続したときにprintされるIPにアクセスするとPicoWに組み込みのLEDのオンオフとか温度センサーの値が表示されるのでそれができたら成功。