LoginSignup
1
0

RaspberryPi4を無線LANのアクセスポイントにしてRaspberryPiPicoWを接続する

Last updated at Posted at 2023-06-06

RasberryPi4を主体としてRaspberryPiPicoWに実装したセンサの値を読み取ったりモーターや電磁弁の制御をできるようにしたい。最終的にはおうちで育ててる花の自動水やりシステムとかにしたい。
画像1.png
全体のイメージはこんな感じ(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のオンオフとか温度センサーの値が表示されるのでそれができたら成功。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0