概要
ESP32のWi-Fi設定をどのようにすればよいのかを調査しました。
当初はESP-TOUCH(SmartConfig)の調査でしたが、Wi-Fi設定の全般的な動きを調べました。
Wi-Fi接続先指定
[非推奨] スケッチに直書き
const char *wifi_ssid = "SSID"; const char *wifi_key = "Password"; void setup() { WiFi.begin(wifi_ssid, wifi_key); }
SSIDとKEYをスケッチに直接埋め込みます。他の環境で接続する場合には書き換えて転送し直します。
上記みたいなやつです。ブログなどでこのように紹介してあることがありますが、非推奨です。
[非推奨] NVSの独自項目に事前設定
void setup() { preferences.begin("Wi-Fi", true); preferences.getString("ssid", wifi_ssid, sizeof(wifi_ssid)); preferences.getString("key", wifi_key, sizeof(wifi_key)); preferences.end(); WiFi.begin(wifi_ssid, wifi_key); }
過去このブログでの推奨方法でしたが、今回調査した結果を踏まえると、次の方法がよいのかなと思いました。
[推奨] 無指定で前回設定を利用する
void setup() { WiFi.begin(); }
無指定で接続すると、前回接続したときの設定で接続します。一度他のスケッチなどで接続しておけば、このスケッチでは一切設定はいりません。
Wi-Fi接続設定の保存方法
無指定で接続する場合には、接続先情報をあらかじめ保存しておく必要があります。代表的な方法を紹介します。
スケッチに直書きで設定する
#include "WiFi.h" void setup() { WiFi.begin("SSID", "KEY"); } void loop() { }
接続に失敗しても内部に保存されます。一番お手軽です。
softAPモードで設定する
アクセスポイントモードでESP32を起動して、ブラウザ経由で設定します。ブラウザで設定できるので、環境依存が少ないです。
しかしながら、結構ブラウザ画面上から設定値を受け取るのは面倒なので、不特定多数に配布するようなデバイスは仕方ないですが、それ以外だと他の方法の方が実装は楽です。
上記はちょっと違いますが、ブラウザから設定した値を取得する例です。
ESP-TOUCH(SmartConfig)で設定する
ESPの標準的な機能で、スマホからWi-Fi設定をする機能が提供されています。
スケッチ例(GitHub)
#include "WiFi.h" void setup() { // シリアル初期化 Serial.begin(115200); // 前回接続時情報で接続する Serial.println("WiFi begin"); WiFi.begin(); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); // 10秒以上接続できなかったら抜ける if ( 10000 < millis() ) { break; } } Serial.println(""); // 未接続の場合にはSmartConfig待受 if ( WiFi.status() != WL_CONNECTED ) { WiFi.mode(WIFI_STA); WiFi.beginSmartConfig(); Serial.println("Waiting for SmartConfig"); while (!WiFi.smartConfigDone()) { delay(500); Serial.print("#"); // 30秒以上接続できなかったら抜ける if ( 30000 < millis() ) { Serial.println(""); Serial.println("Reset"); ESP.restart(); } } // Wi-fi接続 Serial.println(""); Serial.println("Waiting for WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); // 60秒以上接続できなかったら抜ける if ( 60000 < millis() ) { Serial.println(""); Serial.println("Reset"); ESP.restart(); } } Serial.println(""); Serial.println("WiFi Connected."); } Serial.print("IP Address: "); Serial.println(WiFi.localIP()); } void loop() { }
最初は無指定で接続して、10秒間Wi-Fiに接続できなかった場合には、WiFi.beginSmartConfig()を呼び出して、ESP-TOUCH(SmartConfig)の設定待ちに入っています。
この状態のときにiOSかAndroidの「Espressif Esptouch」アプリから設定を送信します。このときに位置情報の取得を許可しないとWi-FiのSSIDが取得できません。このアプリ以外でもESP-TOUCHに対応しているアプリはありますので、そちらですとSSIDを手で入力したり、過去に送信した設定を保存しておく機能などがあります。
ただし、このWi-Fi接続先情報は平文で通信しているので、情報セキュリティー的には好ましくありませんので注意してください。
Wi-Fi接続先設定の読み出し方法
SSIDの情報をスケッチに埋め込む場合に、どう暗号化しようか悩むのですが、それ以前の問題として、最後に接続したWi-Fi接続先情報がNVSから読み出すことができます。。。
スケッチ例(GitHub)
#include <Preferences.h> Preferences preferences; void setup() { Serial.begin(115200); delay(2000); char wifi_ssid[37] = {}; char wifi_key[66] = {}; preferences.begin("nvs.net80211", true); preferences.getBytes("sta.ssid", wifi_ssid, sizeof(wifi_ssid)); preferences.getBytes("sta.pswd", wifi_key, sizeof(wifi_key)); Serial.printf("sta.ssid : %s\n", &wifi_ssid[4]); Serial.printf("sta.pswd : %s\n", wifi_key); } void loop() { }
ESP32のフラッシュを抜き出して解析してみたのですが、上記のコードで読み出すことができました。
なので、スケッチにWi-Fiなどの情報を暗号化して保存しても、こちらの情報で中身がバレるので意味がありませんでした。
Wi-Fi接続先設定の削除方法
中古の端末を人に譲る場合には、念の為情報を削除してから譲ることをおすすめします。
esptool.py --port COM3 erase_flash
基本的には上記のようなコマンドで消せます。CLIがよくわからない人に関してはM5Burnerなどのツールを使って消すのがよいと思います。
あとは、作った本人も存在をほぼほぼ忘れていた上記ツールを使うと、Arduino IDEから消すこともできます。
まとめ
無指定最強でした。しかしながら、すぐに読み出せてしまう問題があり、これは回避する方法がないのでESP32を使っている以上諦めるしか無い気がします。
自宅環境などは直指定のスケッチで設定、外の環境に持っていって書き換える場合にはESP-TOUCH(SmartConfig)などで投げるのが良さそうです。
コメント
いろいろ参考にさせて頂いてお世話になっております。
ありがとうございます。
WiFiとESPNOWを切り替えながら使うということは可能なものでしょうか。
たとえば、、、ESP01(潤沢な電源あり)を使ってスマホとWiFiで通信。
またある時は別のESP01(こちらは小さな電池で省電力としたい)とESPNOWで通信。
といった使い方は可能でしょうか。
やりたいこと伝わりますでしょうか…
同時に利用することも可能ですし、切り替えながら使うことも可能です
ありがとうございます。
そうなんですか。
どこかにサンプルなど載せてたりしますでしょうか。
参考になるところなどあれば教えて頂けないでしょうか。
以上、よろしくお願い致します。
ESP01(esp8266)はほぼ触ったことがないのでサンプルわからないです
https://okiraku-camera.tokyo/blog/?p=7167
上記とかだとesp8266はエッジ側の省電力のみで、サーバー側はESP32を使っています
これはESP32の方が機能が多くて、使いやすいからだと思います
ESP01は国内だと情報が少ないので、可能であればESP32かESP32 C3あたりを使うのがおすすめです