ESP8266 看門狗 觀念更新

看門狗很重要
所以我長期是用 這種方法

void WDog_Act()//啟動 dog 每秒會執行一次
{
    os_timer_setfn(&myTimer, (os_timer_func_t *)DogLed, NULL);
    os_timer_arm(&myTimer, 1000, true);
}

void DogLed(void *arg) {
MyDogObj.Dog_count++; //外部會歸0
//Serial.print("Timer Call:"); Serial.println(ci);
if (MyDogObj.Dog_count > MyDogObj.Wait_sec) //如超過就RESET
{
Serial.println("***** RESET ******");
Serial.println(MyDogObj.Dog_count);
Serial.println(MyDogObj.Wait_sec);
Serial.println("***** RESET ******");
//ESP.reset();
//ESP.restart();
MyDogObj.Soft_Rest();
}
}
Soft_Rest(); 其實就是用一個 pin 去接 RST接腳 ,硬是將他 RESET
這方法用很久...

但為啥放著 ESP.restart() 不用?
因為 會出現 wdt reset 訊息就卡住了.....並沒有重啟動
所以用 硬體方式解決 一直以來也沒啥問題
但最近 研究到 OTA 無線傳輸程式的問題
發現  RST 接腳 接著 不管是用 USB 還是 OTA 上傳程式都不會成功
這就是個大問題了
總不能 每次傳 都去將 RST 接腳拔掉 那跟拿下來改程式 有啥不同?

於是重新再來想  看門狗 的方法.......
終於看到個討論串 https://github.com/esp8266/Arduino/issues/1017
問題跟我一樣.....
看到最後是說是因為接著 USB 線 才會這樣
想想 我一開始第一版好像也是用  ESP.restart()  主板也沒感覺死掉過
倒是 MFC522 偶爾死掉(放外頭風吹日曬的+傳輸距離是有點長)
為何改硬體 reset 就是看到  wdt reset 訊息
於是做了個實驗
另接電源 reset 改回 ESP.restart() .....
測試結果是 OK 的 不要接 USB 就可運作了......

這樣不僅解決 看門狗問題 也解決 萬一遠端改板子設定就直接  ESP.restart()
不須程式在那連來連去改來改去的
又搞清楚了一件事

*************************************
**********以下是之前做法*********************
**************************************
明明是用
ESP.wdtEnable(2000);
但是實測 沒有做
ESP.wdtFeed(); // Reset the WatchDog
他還是沒有重開機 不知還要設定哪裡?
Esp.h
  // TODO: figure out how to set WDT timeout
        void wdtEnable(uint32_t timeout_ms = 0);
        // note: setting the timeout value is not implemented at the moment
        void wdtEnable(WDTO_t timeout_ms = WDTO_0MS);
不是很懂 好像是還沒寫好

但是
ESP.reset(); ESP.restart(); 這兩個可以用

*********************************************
所以真有需要就自己做 用 Timer
以下是當 D0 去碰一下 接地
10秒後重啟
**************************

#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}

const int D[] = { 16, 5, 4, 0, 2, 14, 12, 13, 15, 3, 1, 9, 10 };//照板子 D0-D12 的GPIO
os_timer_t myTimer;//定義一個 Timer
const int led_Timer = D[1];
const int Reset_Btn = D[0];
int Led_stat = HIGH;
// the setup function runs once when you press reset or power the board
void setup() {
pinMode(Reset_Btn, INPUT);//測試燈
pinMode(led_Timer, OUTPUT);//測試燈
digitalWrite(led_Timer, HIGH);
Serial.begin(115200);
Serial.println("*********************************************");
Timer_init();
Serial.println("ready");
Serial.println("*********************************************");

}

// the loop function runs over and over again until power down or reset
void loop() {
if (digitalRead(Reset_Btn) == LOW)
{
delay(50);
return;
}

if (Led_stat == HIGH)
{
Led_stat = LOW;
}
else
{
Led_stat = HIGH;
}
digitalWrite(led_Timer, Led_stat);
delay(1000);
Timer_Feed();
}

**************************************************************
//中斷處理

volatile int ci = 0;
volatile int max_sec = 10;


void Timer_init(void) {
os_timer_setfn(&myTimer, (os_timer_func_t *)timerLed, NULL);
os_timer_arm(&myTimer, 1000, true);
}

void Timer_Feed(void)
{
ci = 0;
}

void timerLed(void *arg) {
ci++;
Serial.print("Timer Call:");
Serial.println(ci);
if (ci > max_sec)
{
Serial.println("***** RESET ******");
ESP.reset();
//ESP.restart();
}
}



留言

熱門文章