ESP32のWi-fi設定方法調査

概要

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)などで投げるのが良さそうです。

コメント

  1. n_shinichi より:

    いろいろ参考にさせて頂いてお世話になっております。
    ありがとうございます。

    WiFiとESPNOWを切り替えながら使うということは可能なものでしょうか。

    たとえば、、、ESP01(潤沢な電源あり)を使ってスマホとWiFiで通信。
    またある時は別のESP01(こちらは小さな電池で省電力としたい)とESPNOWで通信。
    といった使い方は可能でしょうか。
    やりたいこと伝わりますでしょうか…

    • たなかまさゆき より:

      同時に利用することも可能ですし、切り替えながら使うことも可能です

  2. 匿名 より:

    ありがとうございます。

    そうなんですか。
    どこかにサンプルなど載せてたりしますでしょうか。
    参考になるところなどあれば教えて頂けないでしょうか。
    以上、よろしくお願い致します。

    • たなかまさゆき より:

      ESP01(esp8266)はほぼ触ったことがないのでサンプルわからないです

      https://okiraku-camera.tokyo/blog/?p=7167

      上記とかだとesp8266はエッジ側の省電力のみで、サーバー側はESP32を使っています
      これはESP32の方が機能が多くて、使いやすいからだと思います

      ESP01は国内だと情報が少ないので、可能であればESP32かESP32 C3あたりを使うのがおすすめです