Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled

I am getting this error when I try to connect my esp 32 WIFI, continuously check connection and to reconnect if disconnected.

Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400014e8 PS : 0x00060830 A0 : 0x800d133c A1 : 0x3ffb96d0
A2 : 0xa341aa26 A3 : 0xa341aa24 A4 : 0x000000ff A5 : 0x0000ff00
A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x00000000 A9 : 0x00000001
A10 : 0x00000001 A11 : 0x00060823 A12 : 0x00060820 A13 : 0x00000020
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000000a EXCCAUSE: 0x0000001c
EXCVADDR: 0xa341aa24 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff

ELF file SHA256: 0000000000000000

Backtrace: 0x400014e8:0x3ffb96d0 0x400d1339:0x3ffb96e0 0x400d136d:0x3ffb9700 0x400d0509:0x3ffb9720 0x40089792:0x3ffb9750

// Include the necessary libraries
#include <Arduino.h>
#include "WiFi.h"

#define WIFI_NETWORK "SLT-4G"
#define WIFI_PASSWORD "Hell2020*"
#define WIFI_TIMEOUT_MS 20000 // 20 second WiFi connection timeout
#define WIFI_RECOVER_TIME_MS 30000 // Wait 30 seconds after a failed connection attempt
 
void keepWiFiAlive(void * parameter){
    for(;;){
        if(WiFi.status() == WL_CONNECTED){
            Serial.println("WiFi still connected");
            vTaskDelay(10000 / portTICK_PERIOD_MS);
            continue;
        }

        Serial.println("[WIFI] Connecting");
        WiFi.mode(WIFI_STA);
        WiFi.begin(WIFI_NETWORK, WIFI_PASSWORD);

        unsigned long startAttemptTime = millis();

        // Keep looping while we're not connected and haven't reached the timeout
        while (WiFi.status() != WL_CONNECTED && 
                millis() - startAttemptTime < WIFI_TIMEOUT_MS){}

        // When we couldn't make a WiFi connection (or the timeout expired)
      // sleep for a while and then retry.
        if(WiFi.status() != WL_CONNECTED){
            Serial.println("[WIFI] FAILED");
            vTaskDelay(WIFI_RECOVER_TIME_MS / portTICK_PERIOD_MS);
        continue;
        }

        Serial.println("[WIFI] Connected: " + WiFi.localIP());
    }
}
void setup() {
  Serial.begin(9600);

  xTaskCreatePinnedToCore(
  keepWiFiAlive,
  "keepWiFiAlive",  // Task name
  5000,             // Stack size (bytes)
  NULL,             // Parameter
  1,                // Task priority
  NULL,             // Task handle
  CONFIG_ARDUINO_RUNNING_CORE
);
}

void loop() {
  // put your main code here, to run repeatedly:

}

This is the same code from ESP32: Keep WiFi connection alive with a FreeRTOS task | Savjee.be
I tried to find the error but I couldnt.

This is what I got when I backtraced

PC: 0x400014e8 
EXCVADDR: 0xa341aa24
Decoding stack results 
0x400d1335: Print::write(char const*) at C:\Users\pramu\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32/Print.h line 67
0x400d1369: Print::println(char const*) at C:\Users\pramu\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32\Print.cpp line 89
0x400d0509: keepWiFiAlive(void*) at C:\Users\pramu\Desktop\New folder\WIFI_19JUN/WIFI_19JUN.ino line 36
0x40089792: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

Sorry not much help on that particular error. I do use a task to post data to a website but the debug prints print into to a buffer and in the main loop print from that.

Actually you should not need a RTOS task to connect/reconnect the WiFi. I have similar code but do it all from the main loop using simple method 'tasks'
See Multi-tasking in Arduino
multitaskingDiagramSmall

1 Like

I'm not sure if that while-loop in which the reconnect occurs if the system is not currently connected will be allowed by RTOS given its very long (in processing terms) maximum timespan. In any case, something doesn't feel right if you're trying to run a fairly heavy/complex task this way. Instead of using the RTOS task scheduler, I'd just call this routine directly from your code at appropriate moments.

My (limited) experience with the ESP32 watchdog systems is that they're pretty strict and trigger-happy. I'd prevent getting caught in their hands as much as possible.

1 Like

Thanks a lot. I have several other tasks to include and wants to use a RTOS. I started with WiFi connection as the first task and other tasks are to be included later.

I see; well, I can't offer much help unfortunately; I hope you get it to work somehow. But I think at this point I'd call it a day with the task scheduler unless there was a good reason that would preclude any other option.

Yeah, Thank you

Due to the exception type could be the stack size too small.
Furthermore i think it's better feed the watchdog in the while loop with yield or vTaskDelay.

1 Like

This works for me. The "disconnectWiFi" task is there just to periodically disconnect the WiFi and demonstrate automatic reconnection. You obviously wouldn't include it in your real application. In order to see the log prints, set the debug level (Tools menu) to 'Info'.

#include "Arduino.h"
#include <WiFi.h>

void connectToWiFi();
void wifiEvent(WiFiEvent_t event);
void handleWiFiEvent(void *pvParameters);
void disconnectWiFi(void *pvParameters);

QueueHandle_t wiFiEventQueue;

void setup() {
  uint8_t mac[6];

  Serial.begin(115200);
  delay(1000);
  log_i("GFV - Starting");
  wiFiEventQueue = xQueueCreate(5, sizeof(WiFiEvent_t));
  xTaskCreatePinnedToCore(handleWiFiEvent, "WiFi Event", 5000, NULL, 2, NULL, 0);
  xTaskCreatePinnedToCore(disconnectWiFi, "Disconnect WiFi", 5000, NULL, 1, NULL, 0);
  WiFi.macAddress(mac);
  log_i("GFV - mac address %d.%d.%d.%d.%d.%d", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  WiFi.onEvent(wifiEvent);
  connectToWiFi();
}

void loop() {
}

void connectToWiFi() {
  const char SSID[] = "XXXXX";
  const char PASSWORD[] = "YYYYYYY";
  const TickType_t xTicksToWait = pdMS_TO_TICKS(4000);

  while (WiFi.status() != WL_CONNECTED)
  {
    WiFi.disconnect();
    WiFi.begin(SSID, PASSWORD);
    log_i("GFV - Waiting on wifi connection");
    vTaskDelay(xTicksToWait);
  }
}

void wifiEvent(WiFiEvent_t event) {
  xQueueSendToBackFromISR(wiFiEventQueue, &event, 0);
}

void handleWiFiEvent(void *pvParameters) {
  WiFiEvent_t event;
  IPAddress ip;

  for (;;) {
    xQueueReceive(wiFiEventQueue, &event, portMAX_DELAY);
    switch (event) {
      case SYSTEM_EVENT_STA_DISCONNECTED:
        log_i("GFV - WiFi Disconnected");
        connectToWiFi();
        break;

      case SYSTEM_EVENT_STA_CONNECTED:
        log_i("GFV - WiFi Connected");
        break;

      case SYSTEM_EVENT_STA_GOT_IP:
        ip = WiFi.localIP();
        log_i("GFV - Got IP Address %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
        break;

      default:
        log_i("GFV - WiFi Event: %d", (uint16_t )event);
        break;
    }
  }
}

void disconnectWiFi(void *pvParameters) {
  const TickType_t xTicksToWait = pdMS_TO_TICKS(30000);
  for (;;) {
    vTaskDelay(xTicksToWait);
    log_i("GFV - Disconnecting WiFi");
    WiFi.disconnect();
  }
}


1 Like

This does not do what you think it does. The string literal (between double quotes) decays to a pointer to the first character, and the IP address is implicitly converted to uint32_t, so when you add that to the pointer, you end up with a pointer that points way beyond the string.

Print the IP address separately.

Serial.print("[WIFI] Connected: ");
Serial.println(WiFi.localIP());

IMO, this is a bug in the ESP32's IPAddress class, it shouldn't implicitly be converted to an integer, this conversion should be marked explicit: arduino-esp32/cores/esp32/IPAddress.h at 21947ebe76cf6380fe06aa885390b86cc477709a · espressif/arduino-esp32 · GitHub

1 Like

@cotestatnt , @gfvalvo , @PieterP Thank You.

Yeah, the code worked as expected when

was removed.

1 Like

I recommend against using the String + operator (Taming Arduino Strings )
It uses twice the memory and often does not work as expected.
To work the String + operator needs at least one side of the + to be a String.
However at noted above, in this case neither side was a String.
Confusing because

Serial.print("[WIFI] Connected: ");
Serial.println(WiFi.localIP());

works
but that is only because IPAddress implments the printable interface.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.