Page 1 of 1

WDT Reset when Wi-Fi is Disconnected

Posted: Wed May 25, 2022 1:49 pm
by usr.lmnt
I am doing a project where I wanted to log or record some data in Google Firebase Realtime Database. However, each time my Wi-Fi gets disconnected due to no internet connection or the router is turned off, the WDT keeps on getting triggered.

Using:
  • FreeRTOS with ESP32 Firebase Client
  • NodeMCU ESP32S v1.1
  • PlatformIO IDE
  • I also have ArduinoIDE installed with ESP Exception Decoder
This is the sample code:

Code: Select all

#include <WiFi.h>
#include <FirebaseESP32.h>
#include <addons/RTDBHelper.h>
#include <addons/TokenHelper.h>
#include <time.h>

#define WIFI_SSID ""
#define WIFI_PASSWORD ""

#define DATABASE_URL ""
#define API_KEY ""

#define USER_EMAIL ""
#define USER_PASSWORD ""

FirebaseData fbdo;
FirebaseAuth auth;
FirebaseJson json;
FirebaseConfig config;

void wifi(void *param)
{

    String uid = "";
    String databasePath, parentPath;
    int timestamp = 0;

    bool timeSynched = false;
    unsigned long previousTimeSync = 0;
    unsigned long wifiConnectedMillis = 0;
    unsigned long wifiReconnectMillis = millis();

    for (;;)
    {

        if (WiFi.status() != WL_CONNECTED)
        {
            // connect or re-connect to WiFi
            if (wifiConnectedMillis == 0)
            {
                WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
                Serial.println();
                Serial.print("Connecting to Wi-Fi");
            }
            else
            {
                // if WiFi ever connected, reconnect at some interval
                // to prevent frequently stop and start WiFi connections.
                if (millis() - wifiReconnectMillis > 1000)
                {
                    Serial.println();
                    Serial.println("Reconnecting to WiFi");
                    wifiReconnectMillis = millis();
                    // WiFi stop and restart using saving credentials
                    WiFi.reconnect();
                }
            }

            // print waiting dot
            unsigned long wifiTmo = millis();
            while (WiFi.status() != WL_CONNECTED && millis() - wifiTmo < 5000)
            {
                Serial.print(".");
                delay(300);
            }
            Serial.println();

            // print connection result
            if (WiFi.status() == WL_CONNECTED)
            {
                wifiConnectedMillis = millis();
                Serial.print("Connected with IP: ");
                Serial.println(WiFi.localIP());
                Serial.println();
            }
            else
            {
                Serial.println("Connection timed out");
                Serial.println();
            }
        }

        if (WiFi.status() == WL_CONNECTED)
        {

            // If time is not synched, sync the time every 3 seconds
            //  to prevent frequently stop and start UDP connections.

            if (!timeSynched && millis() - previousTimeSync > 3000)
            {
                previousTimeSync = millis();
                configTime(8 * 3600, 0, "pool.ntp.org");
            }

            if (!timeSynched)
            {
                struct tm timeinfo;
                timeSynched = getLocalTime(&timeinfo);
            }
        }

        if (Firebase.ready())
        {
            uid = auth.token.uid.c_str();

            Serial.println();

            Serial.print("UID: ");
            Serial.println(uid);
            // Serial.printf("UID: %s \n", uid.c_str());

            databasePath = "/userdata/" + uid + "/readings";

            time_t now;
            struct tm timeinfo;
            if (!getLocalTime(&timeinfo))
            {
                Serial.println("Failed to obtain time");
                continue;
            }
            time(&now);
            timestamp = now;
            Serial.printf("Time: %s", asctime(&timeinfo));

            parentPath = databasePath + "/" + String(timestamp);

            json.clear(); // Clear all elements

            // When calling FirebaseJson set, the library needs to search for the key from all elements in JSON object
            // which the new node needed to add or replace  to the target element which it wasted more cpu time.

            // You will never seen this kind of FirebaseJson set operation from any JSON library.
            // Only FirebaseJson library allows this unless the performance is compromized
            // because of searching operation.

            // Use add with key instead for fastest (better performance)
            // Serial.println("json.set t");
            json.add("t", "TEST");

            // Serial.println("json.set h");
            json.add("h", "TEST");

            // Serial.println("json.set p");
            json.add("p", "TEST");

            // Serial.println("json.set f");
            json.add("f", "TEST");

            // Serial.println("json.set ts");
            json.add("ts", String(timestamp));

            // When you do some tasks continuously long enough that wasted cpu time e.g. previousely print message to serial or json.set,
            // as no cpu idle time is allowed, you need to allow cpu to do its critical system tasks e.g. feed the wdt by calling yield or delay(0).

            delay(0);

            Serial.printf("Set json... %s\n", Firebase.RTDB.setJSON(&fbdo, parentPath.c_str(), &json) ? "ok" : fbdo.errorReason().c_str());

            // Serial.printf("Delete node... %s\n", Firebase.RTDB.deleteNode(&fbdo, "userdata") ? "ok" : fbdo.errorReason().c_str());
        }

        vTaskDelay(2000 / portTICK_PERIOD_MS);
    }
}

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

    WiFi.mode(WIFI_STA);

    config.api_key = API_KEY;
    auth.user.email = USER_EMAIL;
    auth.user.password = USER_PASSWORD;
    config.database_url = DATABASE_URL;

    fbdo.setResponseSize(4096);
    config.token_status_callback = tokenStatusCallback;

    Firebase.begin(&config, &auth);

    xTaskCreatePinnedToCore(
        wifi,
        "WiFi",
        10240,
        NULL,
        1,
        NULL,
        0);
}

void loop() {}
This is the serial monitor error that I keep on receiving:

Code: Select all

E (43398) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (43398) task_wdt:  - IDLE (CPU 0)
E (43398) task_wdt: Tasks currently running:
E (43398) task_wdt: CPU 0: WiFi
E (43398) task_wdt: CPU 1: loopTask
E (43398) task_wdt: Aborting.

abort() was called at PC 0x400f904c on core 0

Backtrace:0x40083611:0x3ffbea4c |<-CORRUPTED

ELF file SHA256: 0000000000000000

Rebooting...
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1184
load:0x40078000,len:12812
load:0x40080400,len:3032
entry 0x400805e4
When decoded using ESP Exception Decoder, this is what shows up:
0x40083611: panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c line 402