M5StickC(ESP32)にいちばん強いWifiに接続してほしい



WiFiMultiというクラスがありました↓
https://qiita.com/takeru@github/items/a5c7f370165e12dff39a

---------------------------
---------------------------
---------------------------
---------------------------
---------------------------
---------------------------


タイトル通りのことをしたかったのでやってみたらできました。


SSIDとパスワードをどうやって設定するのがよいかに関しては、いろいろ言われていますが、
https://lang-ship.com/blog/?p=1563#GitHub-2
ここで書かれているようにガバガバなのでスケッチに書いちゃってもいいんじゃないでしょうか。



```M5StickC_WifiScan.ino.c
#include <M5StickC.h>
#include "WiFi.h"
#include <Preferences.h>
//#include "secret.h"
//#define WRITE_SECRETS() \
//  writeWiFiInfoToInsecureStorageItIsNotRecommended(0, "ssid0", "password0"); \
//  writeWiFiInfoToInsecureStorageItIsNotRecommended(1, "ssid1", "password1"); \
//  writeWiFiInfoToInsecureStorageItIsNotRecommended(2, "ssid2", "password2"); \

void setup() {
  M5.begin();
  //WRITE_SECRETS();
}

void loop() {
  M5.Lcd.setRotation(1);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(1);


  uint8_t mac[6];
  WiFi.macAddress(mac);
  printf("mac=%s\n", mac_string(mac).c_str());
  M5.Lcd.printf("mac=%s\n", mac_string(mac).c_str());

  String ssid;
  String key;
  selectBestSSID(ssid, key);
  printf("ssid=%s\n", ssid.c_str());
  M5.Lcd.printf("ssid=%s\n", ssid.c_str());

  bool connected = wifi_connect(10 * 1000, ssid, key);
  printf("connected=%d\n", connected);
  M5.Lcd.printf("connected=%d\n", connected);

  IPAddress ipAddress = WiFi.localIP();
  printf("%s\n", ipAddress.toString().c_str());
  M5.Lcd.printf("%s\n", ipAddress.toString().c_str());

  for(int i=0; i<10; i++){
    M5.Lcd.print("*");
    delay(1000);
  }
}

void selectBestSSID(String& best_ssid, String& best_key)
{
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  best_ssid = "";
  best_key  = "";
  int best_rssi = -99999;
  int index = -1;
  while (true) {
    String ssid = "";
    String key  = "";
    if (index == -1) {
      readWiFiInfoLastConnected(ssid, key);
    } else {
      readWiFiInfoFromInsecureStorageItIsNotRecommended(index, ssid, key);
      if (ssid == "") {
        break;
      }
    }
    int rssi = getRssiBySsid(ssid);
    if (best_rssi < rssi) {
      best_rssi = rssi;
      best_ssid = ssid;
      best_key  = key;
    }
    index++;
  }
}

int getRssiBySsid(String ssid)
{
  int n = WiFi.scanNetworks();
  for (int i = 0; i < n; i++) {
    if (ssid == WiFi.SSID(i)) {
      return WiFi.RSSI(i);
    }
  }
  return -99999;
}

void writeWiFiInfoToInsecureStorageItIsNotRecommended(int index, const char* ssid, const char* key)
{
  // https://lang-ship.com/reference/unofficial/M5StickC/UseCase/NVS_Wi-fi/
  Preferences preferences;
  preferences.begin("Wi-Fi", false);
  preferences.putString((String("ssid") + String(index)).c_str(), ssid);
  preferences.putString((String("key" ) + String(index)).c_str(), key);
  preferences.end();
}

void readWiFiInfoFromInsecureStorageItIsNotRecommended(int index, String& ssid, String& key)
{
  char wifi_ssid[33] = {0};
  char wifi_key[65] = {0};
  Preferences preferences;
  preferences.begin("Wi-Fi", true);
  preferences.getString((String("ssid") + String(index)).c_str(), wifi_ssid, sizeof(wifi_ssid));
  preferences.getString((String("key") + String(index)).c_str(), wifi_key,  sizeof(wifi_key));
  ssid = wifi_ssid;
  key  = wifi_key;
}

void readWiFiInfoLastConnected(String& ssid, String& key)
{
  // https://lang-ship.com/blog/?p=1563#Wi-Fi-3
  char wifi_ssid[37] = {};
  char wifi_key[66] = {};
  Preferences preferences;
  preferences.begin("nvs.net80211", true);
  preferences.getBytes("sta.ssid", wifi_ssid, sizeof(wifi_ssid));
  preferences.getBytes("sta.pswd", wifi_key, sizeof(wifi_key));
  ssid = &wifi_ssid[4];
  key  = wifi_key;
}

bool wifi_connect(int timeout_ms, String ssid, String key)
{
  if (WiFi.status() == WL_CONNECTED) {
    return true;
  }

  WiFi.begin(ssid.c_str(), key.c_str());
  unsigned long start_ms = millis();
  bool connected = false;
  while (1) {
    connected = WiFi.status() == WL_CONNECTED;
    if (connected || (start_ms + timeout_ms) < millis()) {
      break;
    }
    delay(1);
  }
  return connected;
}

String mac_string(const uint8_t *mac)
{
  char macStr[18] = { 0 };
  sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  return String(macStr);
}

```