文章程式碼顯示

2018年1月20日 星期六

《進階※應用篇》寫程式Arduino教學 - 05:Arduino (或ESP8266) 沒連上 WiFi (或BLYNK) 就卡死的解決辦法

各位如果注意看會發現我在 《進階※應用篇》寫程式Arduino教學 - 04:使用 BLYNK 監控 Arduino 並使用手機遙控冷氣 讓 Arduino 連上 BLYNK 的部分(位於setup中) 使用的函數跟小狐狸不一樣,一般而言大家(包含 BLYNK 官網的 example )使用的是

Blynk.begin(auth, wifi, ssid, pass);

這可以讓 Arduino 連上 Wifi 並且連上 Blynk (兩步合一)

但這會造成一個問題
=> 若 BLYNK 沒有成功與 Arduino 連結上,整個程式會卡死在這裡

我當時是希望就算 Arduino 沒有連結上 BLYNK 還是該進行後段的程式碼,並且在後段的程式碼中每隔一段時間再重新連結上 BLYNK 

我們可以看一下 Blynk.begin 實際上是做什麼事

//====== begin =====
void begin(const char* auth,
               ESP8266&    esp8266,
               const char* ssid,
               const char* pass,
               const char* domain = BLYNK_DEFAULT_DOMAIN,
               uint16_t    port   = BLYNK_DEFAULT_PORT)
    {
        config(esp8266, auth, domain, port);
        connectWiFi(ssid, pass);
        while(this->connect() != true) {}
    }
//====== config =====
     void config(ESP8266&    esp8266,
                const char* auth,
                const char* domain = BLYNK_DEFAULT_DOMAIN,
                uint16_t    port   = BLYNK_DEFAULT_PORT)
    {
        Base::begin(auth);
        wifi = &esp8266;
        this->conn.setEsp8266(wifi);
        this->conn.begin(domain, port);
    }
//====== connectWiFi =====
     bool connectWiFi(const char* ssid, const char* pass)
    {
        ::delay(500);
        BLYNK_LOG2(BLYNK_F("Now Connecting to "), ssid);
        /*if (!wifi->restart()) {
            BLYNK_LOG1(BLYNK_F("Failed to restart"));
            return false;
        }*/
        if (!wifi->kick()) {
             BLYNK_LOG1(BLYNK_F("ESP is not responding"));
             //TODO: BLYNK_LOG_TROUBLE(BLYNK_F("esp8266-not-responding"));
             return false;
        }
        if (!wifi->setEcho(0)) {
            BLYNK_LOG1(BLYNK_F("Failed to disable Echo"));
            return false;
        }
        String ver = wifi->ESP8266::getVersion();
        BLYNK_LOG1(ver);
        if (!wifi->enableMUX()) {
            BLYNK_LOG1(BLYNK_F("Failed to enable MUX"));
        }
        if (!wifi->setOprToStation()) {
            BLYNK_LOG1(BLYNK_F("Failed to set STA mode"));
            return false;
        }
        if (wifi->joinAP(ssid, pass)) {
            String my_ip = wifi->getLocalIP();
            BLYNK_LOG1(my_ip);
        } else {
            BLYNK_LOG1(BLYNK_F("Failed to connect WiFi"));
            return false;
        }
        BLYNK_LOG1(BLYNK_F("Connected to WiFi"));
        return true;
    }
//====== connect =====
     bool connect() {
        if (!domain || !port)
            return false;
        status = client->createTCP(BLYNK_ESP8266_MUX, domain, port);
        return status;
    }


實際上他先後執行了 config 以及 connectWiFi 函數,最後在 while 迴圈裡面不斷等待 connect 函數回傳 True 

換句話說,如果 connect 一直沒有回傳 True ,整個程式就卡在這個無窮迴圈裡面

遍尋很多人的程式碼後發現沒人提過這樣的問題,於是我就想了個法子轉個彎把三個獨立寫出來(置於前文中的 setup() 函數內)

Blynk.config(wifi, auth);
Blynk.connectWiFi (ssid, pass);
Blynk.connect();

如此一來就可以閃過無窮迴圈( wifi 沒連上 or BLYNK 沒連上 ) 造成程式卡死的問題

往回看 《進階※應用篇》寫程式Arduino教學 - 04:使用 BLYNK 監控 Arduino 並使用手機遙控冷氣

我在 5000 毫秒的 timer 中使用 Blynk.connected() 去判斷是否有連上 BLYNK

這樣一來無論是 WIFI 正常但 BLYNK 不正常;或是 WIFI 不正常 BLYNK當然也不正常 的情況,在經過 15000 毫秒,也就是重覆判定三次連結 BLYNK 失敗(見前文第183行)後就會讓 Arduino 以及 ESP8266 整個重啟


↓↓↓ 連結到部落格方針與索引 ↓↓↓

Blog 使用方針與索引