編集履歴一覧に戻る
nihsokのアイコン画像

nihsok が 2024年06月20日05時44分23秒 に編集

ファームウェアバージョンの記述を修正

タイトルの変更

-

今どきのESP32(ファームウェアv4)でのWi-Fi接続設定

+

今どきのESP32(ファームウェアv1.23.0)でのWi-Fi接続設定

本文の変更

## 前提 ESP32を使ってMiroPythonでWi-Fiに接続したい。 公式ドキュメント (https://docs.micropython.org/en/latest/esp32/quickref.html#networking) では以下のようなサンプルプログラムが載っているが、提供されている機能が活用されておらずやや物足りない。 ```python: def do_connect(): import network wlan = network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): print('connecting to network...') wlan.connect('ssid', 'key') while not wlan.isconnected(): pass print('network config:', wlan.ifconfig()) ``` ## 環境 ハードウェア:ESP32-WROOM-32D on ESP32-Devkit4

-

ファームウェア:ESP32_GENERIC-20240602-v1.23.0.bin後述するように、古いファームウェアだと設定されていない定数がある

+

ファームウェア:ESP32_GENERIC-20240602-v1.23.0.bin (https://micropython.org/download/ESP32_GENERIC/) 後述するように、古いファームウェアだと設定されていない定数があるので注意

Raspberry Pi PicoWでも同様の機能が利用できるはずだが、バージョン等細かな差異はあると思われる。 ## スクリプト ```python:wifi.py import utime def connect(r=10): import network with open('wifi.txt') as f: ssid,passwd = f.read().split("\r\n") wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.config(reconnects=1) #2.5s/1try if wlan.isconnected(): wlan.disconnect() wlan.connect(ssid,passwd) stat = wlan.status() while not wlan.isconnected(): utime.sleep(1) stat = wlan.status() if (stat == network.STAT_IDLE): continue #1000 if (stat == network.STAT_CONNECTING): continue #1001 break if (stat == network.STAT_GOT_IP): #1010 print('GOT_IP') return wlan.ifconfig() elif (stat == network.STAT_WRONG_PASSWORD): print('WRONG_PASSWORD') #202 print(ssid+' is found, but password is incorrect.') elif (stat == network.STAT_NO_AP_FOUND): print('NO_AP_FOUND') #201 print([tuple[0] for tuple in wlan.scan() if tuple[0] != b'']) else: print('unknown error: '+stat) ``` ```python:main.py import wifi print(wifi.connect()) ``` ```text:wifi.txt 任意のSSID 任意のパスワード ``` ## 動作の説明 wifi.txtに記述されているSSIDとパスワードを使いWi-Fi接続を試みる。 - network.STAT_IDLEかnetwork.STAT_CONNECTINGの状態の間はループし続ける。 - 成功した場合はIPを返す - パスワードが違う場合はその旨をコンソールに表示。返り値は無し - アクセスポイントが見つからない場合はアクセスポイントのスキャン結果一覧を表示。返り値は無し ## 注意点 - wlan.status()で得られるステータスのうち、主なものはここに書いてある (https://docs.micropython.org/en/latest/library/network.WLAN.html) - ただし、STAT_CONNECT_FAILは未定義だった - 実際の数字との対応はこちらに従っている https://mpython.readthedocs.io/en/latest/library/micropython/network.html#network.WLAN.status - 古いファームウェアだとnetwork.STAT_WRONG_PASSWORDやnetwork.STAT_NO_AP_FOUNDが定義されていなかったり、別の数字が割り当てられていたりした ==ファームウェアは最新のものを使うこと== - wlan.scan()の返答はここに書いてある通り https://docs.micropython.org/en/latest/library/network.WLAN.html タプル (ssid, bssid, channel, RSSI, security, hidden) のうちssid以外はいらないので削っている。また、なぜか空のSSIDがいくつも見つかるのでそれも捨てている。 - Python3.10で再送されたmatch-caseはMicroPythonでは使えないので、elifで場合分けしている。 - if wlan.isconnected(): wlan.disconnect() のところでいちど切断するようにしているが、完全にはリセットされずに前の状態を引き継いでいるおりエラーが解消されないことがある。ルーター側の挙動もありそう。電源を外して放置すれば解消するが、できればソフトウェア的に解消したい。(今後の課題) ## 備考 networkで定義されている定数の一覧 ```python: >>> dir(network) ['__class__', '__init__', '__name__', 'AP_IF', 'AUTH_MAX', 'AUTH_OPEN', 'AUTH_OWE', 'AUTH_WAPI_PSK', 'AUTH_WEP', 'AUTH_WPA2_ENTERPRISE', 'AUTH_WPA2_PSK', 'AUTH_WPA2_WPA3_PSK', 'AUTH_WPA3_PSK', 'AUTH_WPA_PSK', 'AUTH_WPA_WPA2_PSK', 'ETH_CONNECTED', 'ETH_DISCONNECTED', 'ETH_GOT_IP', 'ETH_INITIALIZED', 'ETH_STARTED', 'ETH_STOPPED', 'LAN', 'MODE_11B', 'MODE_11G', 'MODE_11N', 'MODE_LR', 'PHY_DM9051', 'PHY_DP83848', 'PHY_IP101', 'PHY_KSZ8041', 'PHY_KSZ8081', 'PHY_KSZ8851SNL', 'PHY_LAN8710', 'PHY_LAN8720', 'PHY_RTL8201', 'PHY_W5500', 'PPP', 'STAT_ASSOC_FAIL', 'STAT_BEACON_TIMEOUT', 'STAT_CONNECTING', 'STAT_GOT_IP', 'STAT_HANDSHAKE_TIMEOUT', 'STAT_IDLE', 'STAT_NO_AP_FOUND', 'STAT_WRONG_PASSWORD', 'STA_IF', 'WLAN', '__dict__', 'country', 'hostname', 'phy_mode']

-

```

+

```