プログラムからリセットをかけてリスタートを行う。
背景:
WiFi 接続が ほぼ 1回置きに失敗する。
( WiFi.begin(ssid, password); 後の
WiFi.status() で WL_CONNECTED にならない。
リセットスイッチ, 電源 ON/OFF (USB抜き差し) 共に、1回置きに失敗 )
原因は不明だが、取り敢えず、接続できない場合にリスタートを行いたい。
[2019/2/24 追記]
WL_CONNECTED にならない場合、再度 WiFi.begin(ssid,passwork); を実行すれば接続できた。接続できない場合は WiFi.begin の再実行の方がよいかも。
[2020/8/11 追記]
WiFi.begin の再実行の前に WiFi.disconnect(true,true); を実行した方が良いようです。
また、この現象(1回置きに接続失敗) は、WiFiルータ(親機) に依存する様に思えます。
可能であれば、異なる WiFiルータに接続先を変えてみても良いかもしれません。
方法:
ESP.restart();
を実行する。
例: ( 「LED 調光 (PWM)
」をベースに、失敗時のソフトウェアリセット を 追加 )
/* * WiFi LED ON/OFF TEST * PWM Control */ #include <WiFi.h> const char* ssid = "hogehoge"; const char* password = "hogehogepaswd"; IPAddress ip(192, 168, 1, 32); // for fixed IP Address IPAddress gateway(192,168, 1, 1); // IPAddress subnet(255, 255, 255, 0); // IPAddress DNS(192, 168, 1, 90); // WiFiServer server(80); // -- for ledc byte br_table[11] = {0,25,50,75,100,125,150,175,200,225,255} ; // -- for sigmaDelta //byte br_table[6] = {0,150,180,205,230,255} ; int n = 0; void setup() { int lpcnt=0 ; Serial.begin(115200); pinMode(2, OUTPUT); // set the LED pin mode WiFi.config(ip, gateway, subnet, DNS); // Set fixed IP address delay(10); // We start by connecting to a WiFi network ----------------------------- Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); lpcnt +=1 ; if (lpcnt>10) { ESP.restart(); } Serial.print("."); } Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); server.begin(); // for LED PWM Control --------------------------------------------------- // -- for ledc ledcSetup(0, 5000, 13); // setup channel 0 with frequency 5000 Hz, 13 bit precission for LEDC timer ledcAttachPin(2,0); // attach pin 2 to channel 0 ledcWrite(0, 0); // initialize channel 0 to off // -- for sigmaDelta //sigmaDeltaSetup(0, 312500); // setup channel 0 with frequency 312500 Hz //sigmaDeltaAttachPin(2,0); // attach pin 2 to channel 0 //sigmaDeltaWrite(0, 0); // initialize channel 0 to off n=0 ; } void loop(){ WiFiClient client = server.available(); // listen for incoming clients if (client) { // if you get a client, Serial.println("***** Client access start *****"); // print a message out the serial port while (client.connected()) { // loop while the client's connected if (client.available()) { // if there's bytes to read from the client, String line = client.readStringUntil('\n'); // Get Line data until '\n' Serial.println(line); if (line.indexOf("GET /?on") != -1) { // Client request was "GET /?on" n += 1 ; // incliment table no. if (n>10) n=0 ; Serial.print("brightness value : "); Serial.println(br_table[n],DEC); // -- for ledc ledcWrite(0, 8191*br_table[n]/255) ; // set PWM value to channel#0 // -- for sigmaDelta //sigmaDeltaWrite(0, br_table[n]) ; } if (line.indexOf("GET /?off") != -1) { // Client request was "GET /?off" n = 0 ; // clear bright no. Serial.print("brightness value : "); Serial.println(br_table[n],DEC); // -- for ledc ledcWrite(0, 8191*br_table[n]/255) ; // set PWM value to channel#0 // -- for sigmaDelta //sigmaDeltaWrite(0, br_table[n]) ; } if (line.length() == 1 && line[0] == '\r'){ // end of HTTP request send_response(client) ; // send response to client break; // break while loop } } } delay(1); // give the web browser time to receive the data // close the connection: client.stop(); Serial.println("Client Disconnected."); Serial.println("--------------------------------------------------"); } } // ------------------------------------------------------------------ void send_response(WiFiClient client) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println(); // the content of the HTTP response follows the header: client.print("<!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'>" ) ; client.print("<style>input {margin:8px;width:100px;}div {font-size:16pt;text-align:center;width:250px;border:solid 4px #93ff93;}</style>" ) ; client.print("<title>Color LED Controller</title></head>" ) ; client.print("<body><div><p>LED ON/OFF</p><form method='get'>" ) ; client.print("<input type='submit' name='on' value='ON' /><input type='submit' name='off' value='OFF' /></form>" ) ; client.print("</div></body></html>" ) ; client.println(); Serial.println( " --- send responce --- "); }
以下、覚書など。
( 行# 26 )
失敗判定の為の 確認回数カウント用。
( 行# 44 )
WiFi.status() 確認回数が 10回を超えたら、ソフトウェアリセットを発行。
[2020/8/11 追記]
尚、 再接続する場合は 行#41-46 を以下の様にする。
再接続時の例
while (WiFi.status() != WL_CONNECTED) { // 接続確認
delay(500); // 0.5秒毎にチェック
lpcnt += 1 ; //
if (lpcnt > 6) { // 6回目(3秒) で切断/再接続
WiFi.disconnect(true,true) ; //
WiFi.begin(wifi_ssid, wifi_pass); //
lpcnt = 0 ; //
lpcnt2 += 1 ; // 再接続の回数をカウント
} //
if (lpcnt2 > 3) { // 3回 接続できなければ、
ESP.restart() ; // ソフトウェアリセット
} //
Serial.print("."); //
} //
こんばんは。参考にさせていただきました。
返信削除>>WiFi 接続が ほぼ 1回置きに失敗する。
当方でも同じ現象が発生し、困っておりました。ネットで探しても同じ症状の方はほとんど見つからず、ソフトリセットで乗り切ろうと、このページに辿り着きました。
アドバイスにある通り、再度 WiFi.begin(ssid,passwork)を実行すると、たしかに接続できるようになりましたが、今度は、1回おきではなく、毎回、接続しなくなり、上記の2回めの WiFi.begin(ssid,passwork)でつながるようになりました。
画面には毎回「..........」が表示されます。
まずは、毎回、接続できるようになりましたので、良いとは言え、ちょっと気持ち悪いですね。
他に何か良い対策などございましたらご教示いただければ幸いです。
おはようございます。
削除私も、1回毎置きに失敗する様な情報が見つけらず、試行錯誤しました。
未だに原因は分かっておらず、対症療法として タイムアウト時の WiFi.begin 再発行で対応しています。
毎回 「....」が表示されるのは、
OFF/ON(リセット)で接続失敗(「....」表示)→ WIFI.bigin再発行 で接続成功
の様に 1回のOFF/ON(又は リセット) で 失敗→成功 となるため、毎回 「...」が表示されるのかと思います。
( 結局、失敗と成功を 1回置きに繰り返している )
コメントありがとうございました。さらにいろいろと試行錯誤してみました。
返信削除当方は、処理の後にDeepSleepに入れていますが、DeepSleepに入る前に以下を追加してみたところ、「..........」が出なくなりました。
WiFi.disconnect(true,true);
正しい処理なのかどうかはわかりませんが、これでスッキリする感じになりました。
どこかの英語のサイトに「connectを連続で繰り返すのは良くない。Disconnectしてから再接続」と書いてありましたので、一旦切ればいいのかな、という感じで上記の記述です。(ただ、これだと1回おきに接続できたのがなぜだかわかりませんが・・・)
お試しいただければと思います。ありがとうございました。
ご教示ありがとうございます。
削除リセット前に WiFi.disconnect を行ってみたところ、リセット後に接続失敗すること接続できました。
終了処理でのWiFi.disconnectは行った方が良いですね。
ただ、終了処理がなく(LED調光のサンプルの様に)、いきなりリセットや、OFF する場合では WiFi.disconnect するタイミングがありませんので、接続時の再接続処理が必要と思います。
ただ、再接続前に WiFi.disconnect を入れるべきかもしれません。
(実は、WiFi.begin を続けて発行する事は気になっていたのですが、再接続だけで 接続できていたのでそのままとしていました。)
ところで、ふと気になったので、接続先のアクセスポイント (WiFi親機) を別の物 に変えたところ、現象が発生しなくなりました。この現象の発生は、WiFiルータ(親機) に依存するかもです。
ご教示ありがとうございます。
返信削除たしかに、終了処理ができない場合は、どうしよう?と思っておりましたが、接続前にDisconnectを入れておくのはありかもしれませんね。試してみます。
この不具合は、ルータにもよるんですね(だから、調べても同じような人がほとんどいないんでしょうか)。当方はSynologyのルータを使っておりました。
今回は、貴重な知見が得られました。何度もありがとうございました。
これからも拝見いたします。
Disconnectを接続前に入れてみましたが、上手くいきませんでした。。。
返信削除ルータとの相性もあるとなると、なかなか完全解決は難しそうですね。
すみません。誤解させたかもです。
削除Disconnect は、最初の接続(WiFi.begin) で接続できない(タイムアウト)場合に、再度 WiFi.begin を発行する前に WiFi.Disconnect を入れた方が良いかなと思った次第です。(接続できていないので 意味無いかもですが、、)
ちなみに、こちらの環境では、
WN-AX1167GR2 (IO DATA) : 現象発生
Atern BL900HW (KDDI(NEC)) : 現象発生無し
でした。
大変参考になりました.
返信削除M5Stack ATOM Liteで似たような現象に見舞われ,問題を回避できました.
ESP-WROOM-02ではこのような現象に見舞われたことがありませんでした.
参考にして頂き、ありがとうございます。
削除未だ、原因は判っていませんが、回避策としています。
ルータとデバイスの相性みたいなものがあるのかもしれませんね。
ESP32は 起動時に 最初に接続した時のSSID情報を保持しいるそうです。
返信削除その情報で、自動で再接続してしまうそうです。
ですので、Disconnect()の必要があるようです。
最初というのは、購入後に、最初に設定した SSIDなど情報です。
情報ありがとうございます。
削除そうすると、起動時に最初に Disconnect()はした方が良いということですね。
上手くいかないという話もありましたが、起動後に Disconnect() するタイミングもあるかもしれません。