Edited at

ESP8266 > watchdog resetのESP-WROOM-02調査 > WiFi.begin()のままが問題なのかもしれない

More than 1 year has passed since last update.

関連 http://qiita.com/7of9/items/e8a01d43048199ad65d6

気圧計を作っている中で、watchdog resetがかかるようになったESP-WROOM-02(以下ESP8266)。

3枚あるうちの1枚だけwatchdog resetがかかるようだ。

該当のESP8266を使用中に気圧計のICを反対に挿したことがあり、ESP8266を壊したのだろうか。

macsbugさんの記事を参考にGPIO15, GPIO0, GPIO2をAnalog Discovery 2にて計測してみた。


reset時のGPIO15とGPIO0


  • 黄色: GPIO15

  • 青色: GPIO0

qiita.png

watchdog resetがかかった時にGPIO0の電圧が下がることが分かった。


reset時のGPIO2とGPIO0


  • 黄色: GPIO2

  • 青色: GPIO0

qiita.png

同じピンのキャプチャにて時間軸を詳細にしたもの

qiita.png


6月24日時点でわかっていること


  • GPIO0の電圧が1.8V程度になる

  • GPIO2が短時間にH/L切替になる

上記のトリガになるものはまだ追えていない。


2枚目もresetするようになった

(追記 2016/06/25)

1枚目のESP8266だけresetするかと思っていたが、2枚目もresetするようになった。

再現手順は以下


  1. 気圧計のソフト(eps8266_160528_MPL115A2)を書込み

  2. helloだけシリアル出力するソフトを書込み

気圧計のソフトでresetの原因となる何かがあるのかもしれない。

resetがかかるようになったESP8266は以下に記載した通りで復旧できた。

http://qiita.com/7of9/items/e8a01d43048199ad65d6#%E8%A7%A3%E6%B1%BA


  1. udpEcho_151219を書込み

  2. helloだけシリアル出力するソフトを書込み


Clear the memory(Flash)推奨の情報

以下を見つけた。Flashに変なコードが残り、それがwatchdog resetを生じさせているのだろうか。

http://internetofhomethings.com/homethings/?tag=esp8266-unstable


`2. Clear the memory

Along with securing connections, flashing some of the original binaries back into the module has always worked for me to clear the reset problem, so far.



PWR ON時のGPIO 15とGPIO 0

macsbugさんの記事

の以下を確認してみた。


起動時のGPIO状態:(以下画像を参照させてい頂きます)。

GPIO 0は 起動時に出力になり 起動40ms後にGPIO0ラインは

約100ms間 約350Hzの信号が出力される。



watchdog resetしないESP8266のPWR ON時


  • 黄色: GPIO15

  • 青色: GPIO0

qiita.png

0mから39msの間Hになり、その後H/Lの高速切替が発生している。


watchdog resetするESP8266のPWR ON時


  • 黄色: GPIO15

  • 青色: GPIO0

qiita.png

watchdog resetしないESP8266と波形の違いは見られない。


PWR ON時のGPIO 2とGPIO 0

macsbugさんの記事に起動時のGPIO 2とGPIO 0の波形を掲載していただいた。同じものをこちらで波形観測してみた。


watchdog resetしないESP8266のPWR ON時


  • 黄色: GPIO 2

  • 青色: GPIO 0

qiita.png


watchdog resetするESP8266のPWR ON時

qiita.png


気になる点 GPIO 2の信号

上記2つの画像の差異は見られない。

一方で、macsbugさんの波形と違う点は以下の通り

- GPIO 2の波形(-4Vから-1Vの間の振動)がこちらの環境で見られない

こちらはReset端子に100nFを未実装、EN端子に100nFを未実装。

GPIO 2を測定するつもりがGPIO 12を見てしまっていた。波形を測定し直すと上記のようになった。

macsbugさんの波形と同じようにGPIO 2の信号が見える。


Reset端子とEN端子にコンデンサ100nF

Reset端子に100nFを実装。EN端子に100nFを実装した。

watchdog resetはやはり発生している。


問題のプログラムの簡易版


気圧計のプログラムの簡易版 v0.1

気圧計のプログラムをロードした後に、別のソフト(helloWorld出力)をロードしてもwatchdog resetがかかっている。

気圧計のプログラムをコメントアウトしていき、簡易版にしたものが以下となる。

v0.1 @ github


eps8266_160625_watchdogReset

#include <ESP8266WiFi.h>

#include <WiFiUDP.h>

/*
* This program may cause watchdog reset even after being overwritten by other EPS8266 program
*
* Environment: Arduino 1.6.6
* ESP-WROOM-02
*/

/*
* v0.1 2016 Jun. 25
* - add WiFi_setup()
*/

static WiFiUDP wifiUdp;
static const int kPortUdp_logger = 7000;

static const char *kWifiSsid = "esp8266";
static const char *kWifiPass = "12345678";

static const char *kLoggerIP = "192.168.79.2";

void WiFi_setup()
{
WiFi.begin(kWifiSsid, kWifiPass);
while ( WiFi.status() != WL_CONNECTED) {
delay(500); // msec
}
wifiUdp.begin(kPortUdp_logger);
}

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

WiFi_setup();
}

void loop() {

}


上記で気になるのは、setup()内でコールされるWiFi_setup()がAccessPointが有効でない時に延々とwhile()につかまってしまうこと。

こうするとloop()にたどり着かない。

こういう実装がまずいのかもしれない。

よくわからないのは、このプログラムを別のプログラムで上書きしても、このプログラムの影響によりwatchdog resetがかかっているようだということ。何かの情報がFlashに残ったままなのか、OSが管理する別ソフトとして残っているのか、そしてOSがそのソフトのハングを検知してwatchdog resetをかけているのだろうか。


気圧計のプログラムの簡易版 v0.2 > 問題の回避

問題を回避するコードにしてみた。

v0.2 @ github


esp8266_160625_watchdogReset.ino

#include <ESP8266WiFi.h>

#include <WiFiUDP.h>

/*
* This program may cause watchdog reset even after being overwritten by other EPS8266 program
*
* Environment: Arduino 1.6.6
* ESP-WROOM-02
*/

/*
* v0.2 2016 Jun. 25
* - disconnect WiFi when WiFi connection failed
* - modify WiFi_setup() to avoid endless while loop
* v0.1 2016 Jun. 25
* - add WiFi_setup()
*/

static WiFiUDP wifiUdp;
static const int kPortUdp_logger = 7000;

static const char *kWifiSsid = "esp8266";
static const char *kWifiPass = "12345678";

static const char *kLoggerIP = "192.168.79.2";
static bool s_isWiFiConnected = false;

/*
* in WiFi_setup(), changing "#if 1" to "#if 0" will cause watchdog reset
*/

void WiFi_setup()
{
bool bfOk = false;
WiFi.begin(kWifiSsid, kWifiPass);
#if 1
for(int loop = 0; loop < 3; loop++) {
if (WiFi.status() == WL_CONNECTED) {
s_isWiFiConnected = true;
break;
}
delay(500); // msec
}
if (s_isWiFiConnected) {
wifiUdp.begin(kPortUdp_logger);
} else {
WiFi.disconnect();
}
#else
while ( WiFi.status() != WL_CONNECTED) {
delay(500); // msec
}
wifiUdp.begin(kPortUdp_logger);
#endif
}

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

WiFi_setup();
}

void loop() {

}


(追記 2016/06/26) 上記ではconnectionのリトライを3としているが、10程度にする方がいいかもしれない。気圧計のソフトで試したところ3回ではconnectionを失敗する場合があった。

上記において以下の変更をした


  • while()での無限ループをやめて3回までのループにした

  • s_isWiFiConnected を追加。

  • s_isWiFiConnected == false時に WiFi.disconnect() を実行

以上によりwatchdog resetは発生しなくなったようだ。

http://qiita.com/exabugs/items/2f67ae363a1387c8967c#comment-50fe5d22ce84cc1c0fdd

に書かれている 7E000h のWiFi設定が書き込まれていることと関係があるのかもしれない。

http://qiita.com/Kaz_Macintosh/items/898e1f63d967a13e39d6

の以下も関係あるかもしれない。


なぜか指定したSSIDではなく、リセット前に接続していたSSIDで接続をしているようでした。これは仕様なのでしょうか・・・。


以下は問題についての推測。

あるソフトでWiFi.begin()を実行し、アクセスポイントが無効の状態でWiFi.disconnect()をしないとする。7E000hにWiFi設定が書かれた状態になる。

別のソフトではWiFiについての記載がないとする。7E000h が使われてなんらかの現象によりwatchdog resetが発生する。

対策としては上記のようにWiFi.begin()失敗時にきちんとWiFi.disconnect()すること。

WiFiを使わないソフトの最初にWiFi.disconnect()を実行するのは有効だろうか。