ESP8266ボードでのSSID文字列長について
概要
ESP8826搭載の格安ボードでIoTもどきをやってみようと思ったのですが、思いのほか数点ハマってしまったので、備忘録としてメモしておきます。
環境
やりたいこと
スケッチの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です) 赤塗がうちの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にもあがっていました。
ルーターによっては、末尾にNull Terminationを使用するため31文字までのSSIDを使用しているものもあるようです。