ESP32におけるWiFiスレッド接続(Arduino IDE)

,

ESP32を使用する場合、WiFiを常に接続し、切断されたら再接続するという場合が多くみられます。

メインルーチンで監視し、WiFiが切断したら再接続するという方法でも良いのですが、WiFi接続には時間を要す場合があるため、データを取得したり、サーバへデータを送信したりとうメインルーチンでの作業に影響がある可能性があります。

その場合、WiFi接続を別のスレッドに定義することが有効です。

また複数の接続ポイントに対応したWiFiMultiというクラスが用意されています。一度設定したSSID/PASSWORDはESP32の不揮発性メモリに記憶させておきます。

下のサンプルではM5 stack core2を使用しています(ボードマネージャー esp32 by Espresslf 2.0.17 / Arduino IDE 2.3.2)。

 

<_header.h>

C++
#ifndef HEADER_H
#define HEADER_H

#include <M5Core2.h>

//! タスクハンドル(マルチスレッド)
TaskHandle_t thp[1];

//! WiFiアクセスポイント設定
String ssid = "Your SSID";
String pass = "Your PASSWORD";

#endif

 

<main.ino>

C++
#include "_header.h"

void setup() {
  M5.begin();
  writePref(ssid, pass);
  //! スレッドを実行...
  xTaskCreatePinnedToCore(connectWiFi, "connectWiFi", 4096, NULL, 5, &thp[0], 0);
}

void loop() {
  Serial.println("WiFi signal strength :" + String(getRSSI()));
  delay(3000);
}

 

<T_WiFi.ino>

C++
#include <Preferences.h>  // 不揮発性メモリへの記録(Wi-Fi情報)
#include <WiFiMulti.h>

WiFiMulti wifiMulti;

Preferences preferences;      // declare class object
const char* prefKey = "mms";  //! 不揮発性メモリのキー値

/* =================================================================================
   機能:preferencesにWIFI情報を書き込む...
   引数:第一引数 SSID
      第二引数 パスワード
   戻値:なし
   ================================================================================= */
void writePref(String PrefSSID, String PrefPass) {
  // Serial.println("Write Pref " + PrefSSID + "/" + PrefPass);
  preferences.begin("multi_wifi", false);
  //! 何個、情報が書き込まれているか...
  int cnt = preferences.getInt("cnt", 0);
  //! 1個以上の情報があり、すでに書き込まれていたらすでに書き込まれているか確認...
  bool duplication = false;
  if (0 < cnt) {
    for (int i = 0; i < cnt; i++) {
      String tempA = preferences.getString(("ssid_" + String(i + 1)).c_str(), "");
      String tempB = preferences.getString(("psk_" + String(i + 1)).c_str(), "");
      if ((tempA == PrefSSID) and (tempB == PrefPass)) {
        duplication = true;
      }
    }
  }
  //! 重複せずSSIDが空でなかったら書き込み...
  if (!duplication && PrefSSID != "") {
    preferences.putString(("ssid_" + String(cnt + 1)).c_str(), PrefSSID);
    preferences.putString(("psk_" + String(cnt + 1)).c_str(), PrefPass);
    preferences.putInt("cnt", cnt + 1);
    Serial.println("ADD SSID/PSK " + PrefSSID + "/" + PrefPass);
  }
  preferences.end();
}

/* =================================================================================
   機能:WiFiに接続する...
   引数:汎用ポインタ
   戻値:なし
   ================================================================================= */
void connectWiFi(void* args) {
  while (1) {
    if (wifiMulti.run() != WL_CONNECTED) {
      // WiFi.mode(WIFI_MODE_NULL);
      WiFi.disconnect();
      preferences.begin("multi_wifi", true);
      //! 何個、情報が書き込まれているか...
      int cnt = preferences.getInt("cnt", 0);
      Serial.println("WiFi COUNT is " + String(cnt));
      delay(1000);
      //! 1個以上の情報があり、すでに書き込まれていたらすでに書き込まれているか確認...
      Serial.println("========= WiFi List =========");
      if (0 < cnt) {
        for (int i = cnt; 0 < i; i--) {
          String tempA = preferences.getString(("ssid_" + String(i)).c_str(), "");
          String tempB = preferences.getString(("psk_" + String(i)).c_str(), "");
          if (tempA != "" && tempB != "") {
            Serial.println(tempA + "/" + tempB);
            wifiMulti.addAP(tempA.c_str(), tempB.c_str());
          } else {
            Serial.println("--- Empty account, ignore. ---");
          }
        }
      }
      preferences.end();
      delay(1000);
      if (wifiMulti.run() == WL_CONNECTED) {
        Serial.println("[WiFi] WiFi connected [" + WiFi.SSID() + "]");
      } else {
        Serial.println("[WiFi] Could not connect to wifi");
      }
    }
    delay(3000);
  }
}

/* =================================================================================
   機能:WiFiのステータスを得る
   引数:<なし>
   戻値:接続していたらtrue そうでないならfalse
   ================================================================================= */
boolean get_wifi_status() {
  return WiFi.status() == WL_CONNECTED;
}

/* =================================================================================
   機能:WiFiの電波強度を得る(一般的には-75dBmより大きい数字が理想・切断時は0)
   引数:<なし>
   戻値:電波強度(dBm)
   ================================================================================= */
long getRSSI() {
  if (WiFi.status() != WL_CONNECTED) {
    return 0;
  } else {
    return WiFi.RSSI();
  }
}


PAGE TOP