ESP8266ボードでのSSID文字列長について

概要

ESP8826搭載の格安ボードでIoTもどきをやってみようと思ったのですが、思いのほか数点ハマってしまったので、備忘録としてメモしておきます。

環境

  • ボード
    • HiLetgo NodeMcu Lua ESP8266 CH340G ESP-12E ワイヤレス WIFI インターネット 開発ボード (Amazonでの商品名そのまま記載)
  • Arduino IDE
    • Ver. 1.8.1 with esp8266パッケージ (バージョン2.3.0)

やりたいこと

スケッチのsetup関数内でWiFiに接続したいと思います。

void setup() {
  Serial.begin(115200);
  delay(100);
 
  Serial.println();
  Serial.println();
  Serial.println("Starting setup");

  //////////////////////////////
  WiFi.disconnect(true);
  //////////////////////////////

  Serial.print("Scan start ... ");
  int n = WiFi.scanNetworks();
  Serial.print(n);
  Serial.println(" network(s) found");
  for (int i = 0; i < n; i++)
  {
    Serial.println(WiFi.SSID(i));
  }
  Serial.println();  
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(my_ssid);

  WiFi.begin(my_ssid, my_pass);
  WiFi.mode(WIFI_STA);
  while(WiFi.status() != WL_CONNECTED){
    delay(1000);
    Serial.print("WiFi.status() = ");
    Serial.println(getWlStatus(WiFi.status()));
    WiFi.printDiag(Serial);
  }
 
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

ここで、my_ssid変数はグローバル変数で、自宅のAOSS対応ルーターでは32文字のSSID名を格納しています。my_passは63文字。 getWlStatus関数は、ステータスのint値に対応するステータス文字列を返す自作関数です。

まずやったこと

このスケッチをボードに書き込み、いざ動作させてみると、シリアルモニタでは下記のようなログが。

Starting setup
Scan start ... 9 network(s) found
SSID-1
SSID-2
...

SSID-9

Connecting to (my_ssidの文字列)
WiFi.status() = WL_IDLE_STATUS
Mode: STA
PHY mode: G
Channel: 1
AP id: 0
Status: 0
Auto connect: 0
SSID (0): 
Passphrase (0): 
BSSID set: 0
WiFi.status() = WL_IDLE_STATUS
Mode: STA
PHY mode: G
Channel: 1
AP id: 0
Status: 0
Auto connect: 0
SSID (0): 
Passphrase (0): 
BSSID set: 0
…(以下同)

IDLEのままで接続しようとしていません。接続できなかったらFAIL的な状態になると思うのですが。。。

で、シリアルモニタでのログをよく見てみます。 (黒塗りは他のお家のSSIDです) f:id:hrshishym:20170306120643p:plain 赤塗がうちのSSIDなのですが、よく見るとお尻に変な文字が表示されています。 この文字、ボードを起動するたびに変化していました。

ESP8826WiFiのソースを確認

使用しているライブラリはESP8826WiFiなので、ちょっとソースを覗いてみます。 モードはSTAなので、ESP8266WiFiSTA.cpp がそれっぽい。

ESP8266WiFiSTAClass::begin 関数を覗いてみると、strlen(ssid) > 31 でFAILとなるように制御されていました。

wl_status_t ESP8266WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) {

    if(!WiFi.enableSTA(true)) {
        // enable STA failed
        return WL_CONNECT_FAILED;
    }

    if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) {
        // fail SSID too long or missing!
        return WL_CONNECT_FAILED;
    }

    if(passphrase && strlen(passphrase) > 64) {
        // fail passphrase too long!
        return WL_CONNECT_FAILED;
    }

これでは、32文字あるSSIDに接続は一生出来ません。

やってみたこと

試しにESP8266WiFiSTAClass::begin 関数で、strlen(ssid) > 32 と変えてみます。

//  if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) {
    if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) {
        // fail SSID too long or missing!
        return WL_CONNECT_FAILED;
    }

すると、しばらく WiFi.status() = WL_DISCONNECTED が続いた後、下記のように接続できました。

WiFi.status() = WL_CONNECTED
Mode: STA
PHY mode: G
Channel: 1
AP id: 0
Status: 5
Auto connect: 0
SSID (95): (my_ssid文字列 + my_pass文字列)
Passphrase (63): (my_pass文字列)
BSSID set: 0

WiFi connected
IP address: 
192.168.11.9

SSIDが95文字となっていて怪しいですが、接続は出来ました。

あとがき

ライブラリでは、SSIDが31文字までしか受け付けなかったので、接続出来ませんでした。 32文字まで受け付けるように変更すれば接続はできましたが、ステータスのSSIDが95文字となってしまい、ちょっといただけません。 今回はここまでとしますが、うちのSSIDを31文字までのものに変えたほうが良いかもしれませんね。

ちなみに、SSIDが32文字だからWiFiライブラリが使えないよ!という内容は、Arduino Forumにもあがっていました。

ESP8266 SSID/PWD too long

ルーターによっては、末尾にNull Terminationを使用するため31文字までのSSIDを使用しているものもあるようです。