Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32 restart if using websockets. #325

Closed
JacoFourie opened this issue Feb 11, 2018 · 72 comments
Closed

ESP32 restart if using websockets. #325

JacoFourie opened this issue Feb 11, 2018 · 72 comments
Labels

Comments

@JacoFourie
Copy link

JacoFourie commented Feb 11, 2018

Hi all. I get different types of errors and restarts at random. I use the webserver to send out a html page. In this page there is a connection to a websocket and then the ESP32 will send out the temperature to all clients. It will work fine for a while and then it will crash at random with diffrent errors.

here are the errors I see.

error 1

assertion "heap != NULL && "free() target pointer is outside heap areas"" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/./heap_caps.c", line 274, function: heap_caps_free
abort() was called at PC 0x400e9947 on core 1

Backtrace: 0x40087f20:0x3ffde910 0x4008801f:0x3ffde930 0x400e9947:0x3ffde950 0x40083d67:0x3ffde980 0x400842f9:0x3ffde9a0 0x4000bec7:0x3ffde9c0 0x4011c2ed:0x3ffde9e0 0x4011c3af:0x3ffdea00 0x400d79f6:0x3ffdea20 0x400d7ce5:0x3ffdea60 0x400d7d57:0x3ffdea90

error 2

Guru Meditation Error: Core  1 panic'ed (InstrFetchProhibited)
. Exception was unhandled.
Register dump:
PC      : 0x00000020  PS      : 0x00060b30  A0      : 0x800d7a31  A1      : 0x3ffdea20  
A2      : 0x3ffe1504  A3      : 0x2d636553  A4      : 0x3ffe14ec  A5      : 0x3ffdead0  
A6      : 0x3ffedf0c  A7      : 0x00000000  A8      : 0x800d79b9  A9      : 0x3ffdea00  
A10     : 0x3ffe1504  A11     : 0x3ffdea2c  A12     : 0x3ffdea28  A13     : 0x3ffecd5c  
A14     : 0x00000000  A15     : 0x00000001  SAR     : 0x00000019  EXCCAUSE: 0x00000014  
EXCVADDR: 0x00000020  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  

Backtrace: 0x00000020:0x3ffdea20 0x400d7a2e:0x3ffdea50 0x400d7ce5:0x3ffdea90 0x400d7d57:0x3ffdeac0

error3

Guru Meditation Error: Core  1 panic'ed (LoadProhibited)
. Exception was unhandled.
Register dump:
PC      : 0x40153cf7  PS      : 0x00060730  A0      : 0x800d78a4  A1      : 0x3ffdea00  
A2      : 0x00000000  A3      : 0x3ffe1468  A4      : 0x000004d0  A5      : 0x3ffe1548  
A6      : 0x3ffe14f9  A7      : 0x3ffdcb80  A8      : 0x80085c8c  A9      : 0x3ffdea10  
A10     : 0x00000003  A11     : 0x00060723  A12     : 0x00060720  A13     : 0x00000001  
A14     : 0x00060723  A15     : 0x00000000  SAR     : 0x00000019  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  

Backtrace: 0x40153cf7:0x3ffdea00 0x400d78a1:0x3ffdea20 0x400d95b9:0x3ffdea40 0x400d9611:0x3ffdea60 0x400d79b6:0x3ffdea80 0x400d7cfe:0x3ffdeab0 0x400d7d57:0x3ffdeae0

If I replace the websever with the Arduino-Core one and use another websocket lib all works fine. But I would love to use this one as it handles a lot for me. But it is not stable at this point.

This code works 100%


#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <WebSocketsServer.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <RunningMedian.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>


#define COMMAND_START_CHAR  'U'
#define COMMAND_END_STRING  "\r\n"
int cmdEndStrLen = strlen(COMMAND_END_STRING);
String cmdBuf = "";

TaskHandle_t wifi_tasks;
SemaphoreHandle_t baton;

int feeder_relay_pin = 32;
int stoker_relay_pin = 33;

OneWire oneWire_1(18);
DallasTemperature sensor_t1(&oneWire_1);

RunningMedian s_temp = RunningMedian(11); //Smooth Stoker Temp probe 1
float temp_c = 0, old_temp = 0, temp_value = 0;
int sensor_loop = 0;
int wificounter = 0;
char desp_temp[6];
long rssi;
long wifi_quality;

const char* ssid     = "Pandora-studio";
const char* password = "xxx";
const char* mqtt_server = "10.64.9.34";

//String WebPage = "<!DOCTYPE html><html><style>input[type=\"text\"]{width: 90%; height: 3vh;}input[type=\"button\"]{width: 9%; height: 3.6vh;}.rxd{height: 90vh;} textarea{width: 99%; height: 100%; resize: none;}</style><script>var Socket;function start(){Socket=new WebSocket('ws://' + window.location.hostname + ':81/'); Socket.onmessage=function(evt){ document.getElementById(\"rxConsole\").value +=evt.data; }}function enterpressed(){Socket.send(document.getElementById(\"txbuff\").value); document.getElementById(\"txbuff\").value=\"\";}</script><body onload=\"javascript:start();\"> <div><input class=\"txd\" type=\"text\" id=\"txbuff\" onkeydown=\"if(event.keyCode==13) enterpressed();\"><input class=\"txd\" type=\"button\" onclick=\"enterpressed();\" value=\"Send\" > </div><br><div class=\"rxd\"> <textarea id=\"rxConsole\" readonly></textarea> </div></body></html>";
String WebPage = "<!DOCTYPE html><html><style>input[type=\"text\"]{width: 90%; height: 3vh;}input[type=\"button\"]{width: 9%; height: 3.6vh;}.rxd{height: 90vh;}textarea{width: 99%; height: 100%; resize: none;}</style><script>var Socket;function start(){Socket=new WebSocket('ws://' + window.location.hostname + ':81/'); Socket.onmessage=function(evt){ document.getElementById(\"rxConsole\").value +=evt.data; document.getElementById(\"temp_val\").value=evt.data; }}function enterpressed(){Socket.send(\"Hallo Jaco. You pressed the button !!\"); document.getElementById(\"txbuff\").value=\"\";} function relayon(){Socket.send(\"U1\");} function relayoff(){Socket.send(\"U2\");}   </script><body onload=\"javascript:start();\"> <div><input class=\"txd\" type=\"text\" id=\"txbuff\" onkeydown=\"if(event.keyCode==13) enterpressed();\"><input class=\"txd\" type=\"button\" onclick=\"enterpressed();\" value=\"Send\" ></div> <div><input type = \"text\" id = \"temp_val\" value = \"0.0\" /></div><br><div class=\"rxd\"> <input class=\"txd\" type=\"button\" onclick=\"relayon();\" value=\"Relay On\" > <input class=\"txd\" type=\"button\" onclick=\"relayoff();\" value=\"Relay Off\" >   <textarea id=\"rxConsole\" readonly></textarea> </div></body></html>";

WebSocketsServer webSocket = WebSocketsServer(81);
WiFiServer server(80);

// instance of MQTT client
WiFiClient espClient;
PubSubClient mqtt_client(espClient);
WiFiClientSecure sec_client;

// Initialize Telegram BOT
#define BOTtoken "xxx"  // your Bot Token (Get from Botfather)
UniversalTelegramBot bot(BOTtoken, sec_client);


void setup_wifi() {
     
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  if(WiFi.status() == WL_CONNECTED){
    WiFi.disconnect();
  }

 
   if(WiFi.status() != WL_CONNECTED){
     WiFi.persistent(false);
     WiFi.mode(WIFI_OFF); 
     WiFi.mode(WIFI_STA);     
     WiFi.begin(ssid, password);
   }
  

  wificounter = 0;
  while (WiFi.status() != WL_CONNECTED && wificounter < 10) {    
    for (int i = 0; i < 500; i++) {     
      delay(1);
    }
    Serial.print(".");       
    wificounter++;
  }


  if(wificounter >= 10){
     Serial.println("Restarting ...");
     ESP.restart();
  }

  delay(10);
  // We start by connecting to a WiFi network
  
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
}



void on_message(char* topic, byte* payload, unsigned int length) {

  char message[length];
  Serial.print("Message arrived [");
  Serial.print(topic);
  
  
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);    
    message[i] = (char)payload[i];
  }
  Serial.println();
  //message[length + 1] = '\0';
    
  mqtt_client.publish("Esp32", message , length );
  
  
 
}


void reconnect() {

  //Check if the wifi is connected
  if(WiFi.status() != WL_CONNECTED) {
    setup_wifi();
  }
  // Loop until we're reconnected
  while (!mqtt_client.connected()) {
    Serial.print("Attempting MQTT connection...");
    
    // Attempt to connect
    if (mqtt_client.connect("ESP32Client")) {
      Serial.println("connected");      
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqtt_client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
      
    }
  }
}


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

    // We start by connecting to a WiFi network
    setup_wifi();
   
    //Start the web serber
    server.begin();
    //Start the web sockets    
    webSocket.begin();
    webSocket.onEvent(webSocketEvent);

    //Connect to the MQTT server
    Serial.println("Setting MQTT server");
    mqtt_client.setServer(mqtt_server, 1883);
    mqtt_client.setCallback(on_message);

    //Set relay mode
    pinMode(feeder_relay_pin, OUTPUT);
    pinMode(stoker_relay_pin, OUTPUT);

    ArduinoOTA
    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH)
        type = "sketch";
      else // U_SPIFFS
        type = "filesystem";

      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
    })
    .onEnd([]() {
      Serial.println("\nEnd");
    })
    .onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    })
    .onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
      else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
      else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
      else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
      else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });

  ArduinoOTA.begin();



    //Start the bot  
    bot.sendMessage("xxx", "Esp32 Booted");

    baton = xSemaphoreCreateMutex();
    xTaskCreatePinnedToCore(codeForWiFiTask,"WiFiTask",10000,NULL,1,&wifi_tasks,0);
    
}




//We want to run all WiFi on CPU 0
void codeForWiFiTask( void * parameter )
{
  //Endless for loop 
  for (;;) {

          //Handle Over the air updates
          ArduinoOTA.handle();
      
          //Handle the websoctes
          webSocket.loop();

          //Handle the web server
          WiFiClient client = server.available();   // listen for incoming clients

          // as long as the mqtt client is not connected, reconnect.
          if (!mqtt_client.connected()) {
              reconnect();
          }
          // on each iteration of loop, mqtt client would check the bus for new messages
          mqtt_client.loop();  
        
          if (client) {                             // if you get a client,
            Serial.println("New Client.");           // print a message out the serial port
            String currentLine = "";                // make a String to hold incoming data from the client
            while (client.connected()) {            // loop while the client's connected
              if (client.available()) {             // if there's bytes to read from the client,
                char c = client.read();             // read a byte, then
                Serial.write(c);                    // print it out the serial monitor
                if (c == '\n') {                    // if the byte is a newline character
        
                  // if the current line is blank, you got two newline characters in a row.
                  // that's the end of the client HTTP request, so send a response:
                  if (currentLine.length() == 0) {
                    // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
                    // and a content-type so the client knows what's coming, then a blank line:
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-type:text/html");
                    client.println();
        
                    // the content of the HTTP response follows the header:
                    //client.print("Click <a href=\"/H\">here</a> to turn the LED on pin 5 on.<br>");
                    //client.print("Click <a href=\"/L\">here</a> to turn the LED on pin 5 off.<br>");
        
                    // The HTTP response ends with another blank line:
                    client.println(WebPage);
                    // break out of the while loop:
                    break;
                  } else {    // if you got a newline, then clear currentLine:
                    currentLine = "";
                  }
                } else if (c != '\r') {  // if you got anything else but a carriage return character,
                  currentLine += c;      // add it to the end of the currentLine
                }
        
                
              }
            }
            // close the connection:
            client.stop();
            Serial.println("Client Disconnected.");
          }

        if(old_temp != temp_c) {
         old_temp = temp_c;
         Serial.print("Temp :");
         Serial.println(temp_c , 2);
         //char desp_temp[];
         dtostrf(temp_c,0,2,desp_temp);         
         webSocket.broadcastTXT(desp_temp);

         // Prepare a JSON payload string
         String payload1 = "{";          
         payload1 += "\"temp\":"; payload1+= temp_c;
         payload1 += "}";

         // Send payload
         char attributes1[100];
         payload1.toCharArray( attributes1, 100 );      
         mqtt_client.publish( "TempLogger/AllValues", attributes1 );

       }
    
    if (Serial.available() > 0){
      char c[] = {(char)Serial.read()};
      webSocket.broadcastTXT(c, sizeof(c));
    }

  delay(10);
  //end of the for loop  
  }
}



//Loop run on CPU 1
//We do all the sensor stuff on CPU 1
void loop() {

  portDISABLE_INTERRUPTS();
  sensor_t1.requestTemperatures(); 
  temp_value = sensor_t1.getTempCByIndex(0);
  portENABLE_INTERRUPTS();
  
  
  //If the buffer has more than 5 values in
  if(s_temp.getCount() >= 5){

     //Check if the temp values is in range
     
     //If we have a spike
     if(abs(s_temp.getMedian() - temp_value)  > 5 ){

         Serial.println("We have a spike");
         sensor_loop = 0;
        //Read new values
        //Sit in a loop until we get a valid value or after 10 tries
        while( abs(s_temp.getMedian() - temp_value) > 5 && sensor_loop < 10) {
            portDISABLE_INTERRUPTS();
            sensor_t1.requestTemperatures(); 
            temp_value = sensor_t1.getTempCByIndex(0);
            portENABLE_INTERRUPTS();
            sensor_loop++;
            Serial.print("Loop count : ");
            Serial.println(sensor_loop);
            delay(500);
        }

        if(sensor_loop >= 10) {
           //If we did not get a valid value then do nothing
           //We have to alert that the sensor is faulty but for now we will have a flat line
           Serial.println("We did not get a new value");
        }else {
          Serial.println("We got a new value");
        }
                
     }else {

         //The value is in range                
          s_temp.add(temp_value);
       
     }


    
  }else {
             
    s_temp.add(temp_value); 
    
  }


 temp_c = s_temp.getMedian();

       
}

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length){   
   if (type == WStype_TEXT){
    for(int i = 0; i < length; i++) Serial.print((char) payload[i]);
    Serial.println();
   }

  cmdBuf = "";
  int len = length;
  for (int i = 0; i < len; i ++) {
    cmdBuf += (char) payload[i];
  }  
  processCommand(cmdBuf);
  


     
}



// process the command
void processCommand(String cmd) {
  //logAsHex(cmd);
  Serial.println("Process Command");  
  Serial.println(cmd);
  
  if (cmd.length() > 1) {
    byte cmdId = cmd.charAt(1);
    Serial.println(cmdId);
    switch (cmdId) {     
      //U1 Switch Relays On
      case 0x31:
           digitalWrite(feeder_relay_pin, HIGH);
           digitalWrite(stoker_relay_pin, HIGH);               
        break;
      //U2  Switch Relays Off
      case 0x32:        
           digitalWrite(feeder_relay_pin, LOW);
           digitalWrite(stoker_relay_pin, LOW);                
        break;
      
    }
  }
}

and this code will crash at random.


#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <RunningMedian.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <FS.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>




TaskHandle_t wifi_tasks;
SemaphoreHandle_t baton;

int feeder_relay_pin = 32;
int stoker_relay_pin = 33;

OneWire oneWire_1(18);
DallasTemperature sensor_t1(&oneWire_1);

RunningMedian s_temp = RunningMedian(11); //Smooth Stoker Temp probe 1
float temp_c = 0, old_temp = 0, temp_value = 0;
int sensor_loop = 0;
int wificounter = 0;
char desp_temp[6];
long rssi;
long wifi_quality;

const char* ssid     = "Pandora-studio";
const char* password = "xxx";
const char* mqtt_server = "10.64.9.34";

//String WebPage = "<!DOCTYPE html><html><style>input[type=\"text\"]{width: 90%; height: 3vh;}input[type=\"button\"]{width: 9%; height: 3.6vh;}.rxd{height: 90vh;} textarea{width: 99%; height: 100%; resize: none;}</style><script>var Socket;function start(){Socket=new WebSocket('ws://' + window.location.hostname + ':81/'); Socket.onmessage=function(evt){ document.getElementById(\"rxConsole\").value +=evt.data; }}function enterpressed(){Socket.send(document.getElementById(\"txbuff\").value); document.getElementById(\"txbuff\").value=\"\";}</script><body onload=\"javascript:start();\"> <div><input class=\"txd\" type=\"text\" id=\"txbuff\" onkeydown=\"if(event.keyCode==13) enterpressed();\"><input class=\"txd\" type=\"button\" onclick=\"enterpressed();\" value=\"Send\" > </div><br><div class=\"rxd\"> <textarea id=\"rxConsole\" readonly></textarea> </div></body></html>";
//String WebPage = "<!DOCTYPE html><html><style>input[type=\"text\"]{width: 90%; height: 3vh;}input[type=\"button\"]{width: 9%; height: 3.6vh;}.rxd{height: 90vh;}textarea{width: 99%; height: 100%; resize: none;}</style><script>var Socket;function start(){Socket=new WebSocket('ws://' + window.location.hostname + ':81/'); Socket.onmessage=function(evt){ document.getElementById(\"rxConsole\").value +=evt.data; document.getElementById(\"temp_val\").value=evt.data; }}function enterpressed(){Socket.send(document.getElementById(\"txbuff\").value); document.getElementById(\"txbuff\").value=\"\";} function relayon(){Socket.send(\"U1\");} function relayoff(){Socket.send(\"U2\");}   </script><body onload=\"javascript:start();\"> <div><input class=\"txd\" type=\"text\" id=\"txbuff\" onkeydown=\"if(event.keyCode==13) enterpressed();\"><input class=\"txd\" type=\"button\" onclick=\"enterpressed();\" value=\"Send\" ></div> <div><input type = \"text\" id = \"temp_val\" value = \"0.0\" /></div><br><div class=\"rxd\"> <input class=\"txd\" type=\"button\" onclick=\"relayon();\" value=\"Relay On\" > <input class=\"txd\" type=\"button\" onclick=\"relayoff();\" value=\"Relay Off\" >   <textarea id=\"rxConsole\" readonly></textarea> </div></body></html>";
String WebPage = "<!DOCTYPE html><html><style>input[type=\"text\"]{width: 90%; height: 3vh;}input[type=\"button\"]{width: 9%; height: 3.6vh;}.rxd{height: 90vh;}textarea{width: 99%; height: 100%; resize: none;}</style><script>var Socket;function start(){Socket=new WebSocket('ws://' + window.location.hostname + '/ws'); Socket.onmessage=function(evt){ document.getElementById(\"rxConsole\").value +=evt.data; document.getElementById(\"temp_val\").value=evt.data; }}function enterpressed(){Socket.send(document.getElementById(\"txbuff\").value); document.getElementById(\"txbuff\").value=\"\";} function relayon(){Socket.send(\"U1\");} function relayoff(){Socket.send(\"U2\");}   </script><body onload=\"javascript:start();\"> <div><input class=\"txd\" type=\"text\" id=\"txbuff\" onkeydown=\"if(event.keyCode==13) enterpressed();\"><input class=\"txd\" type=\"button\" onclick=\"enterpressed();\" value=\"Send\" ></div> <div><input type = \"text\" id = \"temp_val\" value = \"0.0\" /></div><br><div class=\"rxd\"> <input class=\"txd\" type=\"button\" onclick=\"relayon();\" value=\"Relay On\" > <input class=\"txd\" type=\"button\" onclick=\"relayoff();\" value=\"Relay Off\" >   <textarea id=\"rxConsole\" readonly></textarea> </div></body></html>";


//Web server and sockets
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

// instance of MQTT client
WiFiClient espClient;
PubSubClient mqtt_client(espClient);
WiFiClientSecure sec_client;

// Initialize Telegram BOT
#define BOTtoken "xxx"  // your Bot Token (Get from Botfather)
UniversalTelegramBot bot(BOTtoken, sec_client);


void setup_wifi() {
     
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  if(WiFi.status() == WL_CONNECTED){
    WiFi.disconnect();
  }

 
   if(WiFi.status() != WL_CONNECTED){
     WiFi.persistent(false);
     WiFi.mode(WIFI_OFF); 
     WiFi.mode(WIFI_STA);     
     WiFi.begin(ssid, password);
   }
  

  wificounter = 0;
  while (WiFi.status() != WL_CONNECTED && wificounter < 10) {    
    for (int i = 0; i < 500; i++) {     
      delay(1);
    }
    Serial.print(".");       
    wificounter++;
  }


  if(wificounter >= 10){
     Serial.println("Restarting ...");
     ESP.restart();
  }

  delay(10);
  // We start by connecting to a WiFi network
  
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
}



void on_message(char* topic, byte* payload, unsigned int length) {

  char message[length];
  Serial.print("Message arrived [");
  Serial.print(topic);
  
  
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);    
    message[i] = (char)payload[i];
  }
  Serial.println();
  //message[length + 1] = '\0';
    
  mqtt_client.publish("Esp32", message , length );
     
}


void reconnect() {

  //Check if the wifi is connected
  if(WiFi.status() != WL_CONNECTED) {
    setup_wifi();
  }
  // Loop until we're reconnected
  while (!mqtt_client.connected()) {
    Serial.print("Attempting MQTT connection...");
    
    // Attempt to connect
    if (mqtt_client.connect("ESP32Client")) {
      Serial.println("connected");      
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqtt_client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
      
    }
  }
}


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

    // We start by connecting to a WiFi network
    setup_wifi();
   
    //Set the paths
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){request->send(200, "text/html", WebPage);});

    ws.onEvent(onWsEvent);
    server.addHandler(&ws);
    
    //Start the web server
    server.begin();
       
    //Connect to the MQTT server
    Serial.println("Setting MQTT server");
    mqtt_client.setServer(mqtt_server, 1883);
    mqtt_client.setCallback(on_message);

    //Set relay mode
    pinMode(feeder_relay_pin, OUTPUT);
    pinMode(stoker_relay_pin, OUTPUT);

    ArduinoOTA
    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH)
        type = "sketch";
      else // U_SPIFFS
        type = "filesystem";

      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
    })
    .onEnd([]() {
      Serial.println("\nEnd");
    })
    .onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    })
    .onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
      else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
      else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
      else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
      else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });

  ArduinoOTA.begin();



    //Start the bot  
    bot.sendMessage("xxx", "Esp32 Booted");

    baton = xSemaphoreCreateMutex();
    xTaskCreatePinnedToCore(codeForWiFiTask,"WiFiTask",10240,NULL,1,&wifi_tasks,0);
    
}




//We want to run all WiFi on CPU 0
void codeForWiFiTask( void * parameter )
{
  //Endless for loop 
  for (;;) {

        //Handle Over the air updates
        ArduinoOTA.handle();
                  
        // as long as the mqtt client is not connected, reconnect.
        if (!mqtt_client.connected()) {
            reconnect();
        }
          
        // on each iteration of loop, mqtt client would check the bus for new messages
        mqtt_client.loop();  
        
        if(old_temp != temp_c) {
         old_temp = temp_c;
         Serial.print("Temp :");
         Serial.println(temp_c , 2);
         //char desp_temp[];
         dtostrf(temp_c,0,2,desp_temp);                  
         ws.textAll(desp_temp);

         // Prepare a JSON payload string
         String payload1 = "{";          
         payload1 += "\"temp\":"; payload1+= temp_c;
         payload1 += "}";

         // Send payload
         char attributes1[100];
         payload1.toCharArray( attributes1, 100 );      
         mqtt_client.publish( "TempLogger/AllValues", attributes1 );

       }
    
    if (Serial.available() > 0){
      char c[] = {(char)Serial.read()};      
      ws.textAll(c);
    }

    delay(10);
  
  //end of the for loop  
  }
}



//Loop run on CPU 1
//We do all the sensor stuff on CPU 1
void loop() {

  portDISABLE_INTERRUPTS();
  sensor_t1.requestTemperatures(); 
  temp_value = sensor_t1.getTempCByIndex(0);
  portENABLE_INTERRUPTS();
  
  
  //If the buffer has more than 5 values in
  if(s_temp.getCount() >= 5){

     //Check if the temp values is in range
     
     //If we have a spike
     if(abs(s_temp.getMedian() - temp_value)  > 5 ){

         Serial.println("We have a spike");
         sensor_loop = 0;
        //Read new values
        //Sit in a loop until we get a valid value or after 10 tries
        while( abs(s_temp.getMedian() - temp_value) > 5 && sensor_loop < 10) {
            portDISABLE_INTERRUPTS();
            sensor_t1.requestTemperatures(); 
            temp_value = sensor_t1.getTempCByIndex(0);
            portENABLE_INTERRUPTS();
            sensor_loop++;
            Serial.print("Loop count : ");
            Serial.println(sensor_loop);
            delay(500);
        }

        if(sensor_loop >= 10) {
           //If we did not get a valid value then do nothing
           //We have to alert that the sensor is faulty but for now we will have a flat line
           Serial.println("We did not get a new value");
        }else {
          Serial.println("We got a new value");
        }
                
     }else {

         //The value is in range                
          s_temp.add(temp_value);
       
     }


    
  }else {
             
    s_temp.add(temp_value); 
    
  }


 temp_c = s_temp.getMedian();

       
}



void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){
  if(type == WS_EVT_CONNECT){
    Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
    client->printf("Hello Client %u :)", client->id());
    client->ping();
  } else if(type == WS_EVT_DISCONNECT){
    Serial.printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id());
  } else if(type == WS_EVT_ERROR){
    Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data);
  } else if(type == WS_EVT_PONG){
    Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:"");
  } else if(type == WS_EVT_DATA){
    AwsFrameInfo * info = (AwsFrameInfo*)arg;
    String msg = "";
    if(info->final && info->index == 0 && info->len == len){
      //the whole message is in a single frame and we got all of it's data
      Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len);

      if(info->opcode == WS_TEXT){
        for(size_t i=0; i < info->len; i++) {
          msg += (char) data[i];
        }
      } else {
        char buff[3];
        for(size_t i=0; i < info->len; i++) {
          sprintf(buff, "%02x ", (uint8_t) data[i]);
          msg += buff ;
        }
      }
      Serial.printf("%s\n",msg.c_str());
  
      processCommand(msg);
      
    } else {
      //message is comprised of multiple frames or the frame is split into multiple packets
      if(info->index == 0){
        if(info->num == 0)
          Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary");
        Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len);
      }

      Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT)?"text":"binary", info->index, info->index + len);

      if(info->opcode == WS_TEXT){
        for(size_t i=0; i < info->len; i++) {
          msg += (char) data[i];
        }
      } else {
        char buff[3];
        for(size_t i=0; i < info->len; i++) {
          sprintf(buff, "%02x ", (uint8_t) data[i]);
          msg += buff ;
        }
      }
      Serial.printf("%s\n",msg.c_str());

      if((info->index + len) == info->len){
        Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len);
        if(info->final){
          Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary");
          if(info->message_opcode == WS_TEXT)
            client->text("I got your text message");
          else
            client->binary("I got your binary message");
        }
      }
    }
  }
}





// process the command
void processCommand(String cmd) {  
  if (cmd.length() > 1) {
    byte cmdId = cmd.charAt(1);    
    switch (cmdId) {     
      //U1 Switch Relays On
      case 0x31:
           Serial.println("Relays On");
           digitalWrite(feeder_relay_pin, HIGH);
           digitalWrite(stoker_relay_pin, HIGH);               
        break;
      //U2  Switch Relays Off
      case 0x32:        
           Serial.println("Relays Off");
           digitalWrite(feeder_relay_pin, LOW);
           digitalWrite(stoker_relay_pin, LOW);                
        break;
       
    }
  }
}


@JacoFourie
Copy link
Author

This code also works 100%. Here I am using this lib https://github.com/bbx10/WebServer_tng

So something is not well on the ESP32 using this lib.


#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <WebSocketsServer.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <RunningMedian.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <WebServer.h>


#define COMMAND_START_CHAR  'U'
#define COMMAND_END_STRING  "\r\n"
int cmdEndStrLen = strlen(COMMAND_END_STRING);
String cmdBuf = "";

TaskHandle_t wifi_tasks;
SemaphoreHandle_t baton;

int feeder_relay_pin = 32;
int stoker_relay_pin = 33;

OneWire oneWire_1(18);
DallasTemperature sensor_t1(&oneWire_1);

RunningMedian s_temp = RunningMedian(11); //Smooth Stoker Temp probe 1
float temp_c = 0, old_temp = 0, temp_value = 0;
int sensor_loop = 0;
int wificounter = 0;
char desp_temp[6];
long rssi;
long wifi_quality;

const char* ssid     = "Pandora-studio";
const char* password = "xxx";
const char* mqtt_server = "10.64.9.34";

//String WebPage = "<!DOCTYPE html><html><style>input[type=\"text\"]{width: 90%; height: 3vh;}input[type=\"button\"]{width: 9%; height: 3.6vh;}.rxd{height: 90vh;} textarea{width: 99%; height: 100%; resize: none;}</style><script>var Socket;function start(){Socket=new WebSocket('ws://' + window.location.hostname + ':81/'); Socket.onmessage=function(evt){ document.getElementById(\"rxConsole\").value +=evt.data; }}function enterpressed(){Socket.send(document.getElementById(\"txbuff\").value); document.getElementById(\"txbuff\").value=\"\";}</script><body onload=\"javascript:start();\"> <div><input class=\"txd\" type=\"text\" id=\"txbuff\" onkeydown=\"if(event.keyCode==13) enterpressed();\"><input class=\"txd\" type=\"button\" onclick=\"enterpressed();\" value=\"Send\" > </div><br><div class=\"rxd\"> <textarea id=\"rxConsole\" readonly></textarea> </div></body></html>";
String WebPage = "<!DOCTYPE html><html><style>input[type=\"text\"]{width: 90%; height: 3vh;}input[type=\"button\"]{width: 9%; height: 3.6vh;}.rxd{height: 90vh;}textarea{width: 99%; height: 100%; resize: none;}</style><script>var Socket;function start(){Socket=new WebSocket('ws://' + window.location.hostname + ':81/'); Socket.onmessage=function(evt){ document.getElementById(\"rxConsole\").value +=evt.data; document.getElementById(\"temp_val\").value=evt.data; }}function enterpressed(){Socket.send(\"Hallo Jaco. You pressed the button !!\"); document.getElementById(\"txbuff\").value=\"\";} function relayon(){Socket.send(\"U1\");} function relayoff(){Socket.send(\"U2\");}   </script><body onload=\"javascript:start();\"> <div><input class=\"txd\" type=\"text\" id=\"txbuff\" onkeydown=\"if(event.keyCode==13) enterpressed();\"><input class=\"txd\" type=\"button\" onclick=\"enterpressed();\" value=\"Send\" ></div> <div><input type = \"text\" id = \"temp_val\" value = \"0.0\" /></div><br><div class=\"rxd\"> <input class=\"txd\" type=\"button\" onclick=\"relayon();\" value=\"Relay On\" > <input class=\"txd\" type=\"button\" onclick=\"relayoff();\" value=\"Relay Off\" >   <textarea id=\"rxConsole\" readonly></textarea> </div></body></html>";

WebSocketsServer webSocket = WebSocketsServer(81);
WebServer server(80);

// instance of MQTT client
WiFiClient espClient;
PubSubClient mqtt_client(espClient);
WiFiClientSecure sec_client;

// Initialize Telegram BOT
#define BOTtoken "xxx"  // your Bot Token (Get from Botfather)
UniversalTelegramBot bot(BOTtoken, sec_client);


void setup_wifi() {
     
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  if(WiFi.status() == WL_CONNECTED){
    WiFi.disconnect();
  }

 
   if(WiFi.status() != WL_CONNECTED){
     WiFi.persistent(false);
     WiFi.mode(WIFI_OFF); 
     WiFi.mode(WIFI_STA);     
     WiFi.begin(ssid, password);
   }
  

  wificounter = 0;
  while (WiFi.status() != WL_CONNECTED && wificounter < 10) {    
    for (int i = 0; i < 500; i++) {     
      delay(1);
    }
    Serial.print(".");       
    wificounter++;
  }


  if(wificounter >= 10){
     Serial.println("Restarting ...");
     ESP.restart();
  }

  delay(10);
  // We start by connecting to a WiFi network
  
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
}



void on_message(char* topic, byte* payload, unsigned int length) {

  char message[length];
  Serial.print("Message arrived [");
  Serial.print(topic);
  
  
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);    
    message[i] = (char)payload[i];
  }
  Serial.println();
  //message[length + 1] = '\0';
    
  mqtt_client.publish("Esp32", message , length );
  
  
 
}


void reconnect() {

  //Check if the wifi is connected
  if(WiFi.status() != WL_CONNECTED) {
    setup_wifi();
  }
  // Loop until we're reconnected
  while (!mqtt_client.connected()) {
    Serial.print("Attempting MQTT connection...");
    
    // Attempt to connect
    if (mqtt_client.connect("ESP32Client")) {
      Serial.println("connected");      
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqtt_client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
      
    }
  }
}


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

    // We start by connecting to a WiFi network
    setup_wifi();
   
    //Start the web serber
    server.on("/", handleRoot);
    server.on("/inline", [](){
    server.send(200, "text/plain", "this works as well");});
    server.onNotFound(handleNotFound);
    server.begin();
    
    //Start the web sockets    
    webSocket.begin();
    webSocket.onEvent(webSocketEvent);

    //Connect to the MQTT server
    Serial.println("Setting MQTT server");
    mqtt_client.setServer(mqtt_server, 1883);
    mqtt_client.setCallback(on_message);

    //Set relay mode
    pinMode(feeder_relay_pin, OUTPUT);
    pinMode(stoker_relay_pin, OUTPUT);

    ArduinoOTA
    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH)
        type = "sketch";
      else // U_SPIFFS
        type = "filesystem";

      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
    })
    .onEnd([]() {
      Serial.println("\nEnd");
    })
    .onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    })
    .onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
      else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
      else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
      else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
      else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });

  ArduinoOTA.begin();



    //Start the bot  
    bot.sendMessage("xxx", "Esp32 Booted");

    baton = xSemaphoreCreateMutex();
    xTaskCreatePinnedToCore(codeForWiFiTask,"WiFiTask",10000,NULL,1,&wifi_tasks,0);
    
}

void handleRoot() {  
  server.send(200, "text/html", WebPage);  
}

void handleNotFound(){  
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);  
}



//We want to run all WiFi on CPU 0
void codeForWiFiTask( void * parameter )
{
  //Endless for loop 
  for (;;) {

          //Handle Over the air updates
          ArduinoOTA.handle();
      
          //Handle the websoctes
          webSocket.loop();

          //Handle the web server
          server.handleClient();

          // as long as the mqtt client is not connected, reconnect.
          if (!mqtt_client.connected()) {
              reconnect();
          }
          // on each iteration of loop, mqtt client would check the bus for new messages
          mqtt_client.loop();  
                 
        if(old_temp != temp_c) {
         old_temp = temp_c;
         Serial.print("Temp :");
         Serial.println(temp_c , 2);
         //char desp_temp[];
         dtostrf(temp_c,0,2,desp_temp);         
         webSocket.broadcastTXT(desp_temp);

         // Prepare a JSON payload string
         String payload1 = "{";          
         payload1 += "\"temp\":"; payload1+= temp_c;
         payload1 += "}";

         // Send payload
         char attributes1[100];
         payload1.toCharArray( attributes1, 100 );      
         mqtt_client.publish( "TempLogger/AllValues", attributes1 );

       }
    
    if (Serial.available() > 0){
      char c[] = {(char)Serial.read()};
      webSocket.broadcastTXT(c, sizeof(c));
    }

  delay(10);
  //end of the for loop  
  }
}



//Loop run on CPU 1
//We do all the sensor stuff on CPU 1
void loop() {

  portDISABLE_INTERRUPTS();
  sensor_t1.requestTemperatures(); 
  temp_value = sensor_t1.getTempCByIndex(0);
  portENABLE_INTERRUPTS();
  
  
  //If the buffer has more than 5 values in
  if(s_temp.getCount() >= 5){

     //Check if the temp values is in range
     
     //If we have a spike
     if(abs(s_temp.getMedian() - temp_value)  > 5 ){

         Serial.println("We have a spike");
         sensor_loop = 0;
        //Read new values
        //Sit in a loop until we get a valid value or after 10 tries
        while( abs(s_temp.getMedian() - temp_value) > 5 && sensor_loop < 10) {
            portDISABLE_INTERRUPTS();
            sensor_t1.requestTemperatures(); 
            temp_value = sensor_t1.getTempCByIndex(0);
            portENABLE_INTERRUPTS();
            sensor_loop++;
            Serial.print("Loop count : ");
            Serial.println(sensor_loop);
            delay(500);
        }

        if(sensor_loop >= 10) {
           //If we did not get a valid value then do nothing
           //We have to alert that the sensor is faulty but for now we will have a flat line
           Serial.println("We did not get a new value");
        }else {
          Serial.println("We got a new value");
        }
                
     }else {

         //The value is in range                
          s_temp.add(temp_value);
       
     }


    
  }else {
             
    s_temp.add(temp_value); 
    
  }


 temp_c = s_temp.getMedian();

       
}

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length){   

   switch(type) {
        case WStype_DISCONNECTED:
            Serial.printf("[%u] Disconnected!\n", num);
            break;
        case WStype_CONNECTED:
            {
                IPAddress ip = webSocket.remoteIP(num);
                Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);

               // send message to client
               webSocket.sendTXT(num, "Connected");

               //Send the Temp value
               dtostrf(temp_c,0,2,desp_temp);         
               webSocket.sendTXT(num,desp_temp);
            }
            break;
        case WStype_TEXT:
            Serial.printf("[%u] get Text: %s\n", num, payload);            
            cmdBuf = "";                     
            for (int i = 0; i < length; i ++) {
                 cmdBuf += (char) payload[i];
                 }  
            processCommand(cmdBuf);
            // send message to client
            // webSocket.sendTXT(num, "message here");

            // send data to all connected clients
            // webSocket.broadcastTXT("message here");
            break;
        case WStype_BIN:
            Serial.printf("[%u] get binary length: %u\n", num, length);                       
            break;
    }

         
}



// process the command
void processCommand(String cmd) {     
  if (cmd.length() > 1) {
    byte cmdId = cmd.charAt(1);    
    switch (cmdId) {     
      //U1 Switch Relays On
      case 0x31:
           digitalWrite(feeder_relay_pin, HIGH);
           digitalWrite(stoker_relay_pin, HIGH);               
           Serial.println("Relay on");
        break;
      //U2  Switch Relays Off
      case 0x32:        
           digitalWrite(feeder_relay_pin, LOW);
           digitalWrite(stoker_relay_pin, LOW);   
           Serial.println("Relay off");             
        break;
           
    }
  }
}

@GracefulTabby
Copy link

I am also caught with a similar error.
For me, if you do not use WebSocket and display a website with many image files, the following random error will appear.

I also like this code, so I would like to use it if possible.

Error 1:

assertion "heap != NULL && "free() target pointer is outside heap areas"" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/./heap_caps.c", line 274, function: heap_caps_free
abort() was called at PC 0x400e34fb on core 1

Backtrace: 0x40087d6c:0x3ffe36f0 0x40087e6b:0x3ffe3710 0x400e34fb:0x3ffe3730 0x40083b6b:0x3ffe3760 0x400840f5:0x3ffe3780 0x4000bec7:0x3ffe37a0 0x40100da5:0x3ffe37c0 0x40100e67:0x3ffe37e0 0x400d4f4a:0x3ffe3800 0x400d5249:0x3ffe3840 0x400d52bb:0x3ffe3870

Error 2:

 CORRUPT` HEAP: Bad head at 0x3ffe83ec. Expected 0xabba1234 got 0x3ffe8418
assertion "head != NULL" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/./multi_heap_poisoning.c", line 199, function: multi_heap_free
abort() was called at PC 0x400e34fb on core 1

Backtrace: 0x40087d6c:0x3ffe3640 0x40087e6b:0x3ffe3660 0x400e34fb:0x3ffe3680 0x40087a7d:0x3ffe36b0 0x40083b72:0x3ffe36d0 0x400840f5:0x3ffe36f0 0x4000bec7:0x3ffe3710 0x400dd106:0x3ffe3730 0x400db055:0x3ffe3750 0x400db066:0x3ffe3770 0x400da5ce:0x3ffe3790 0x400dbe55:0x3ffe37b0 0x400d8ba3:0x3ffe37d0 0x400d8bb1:0x3ffe37f0 0x400d4f0e:0x3ffe3810 0x400d51a1:0x3ffe3840 0x400d52cf:0x3ffe3870

Error 3:

CORRUPT HEAP: Bad head at 0x3ffe436c. Expected 0xabba1234 got 0x3ffe44a0
assertion "head != NULL" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/./multi_heap_poisoning.c", line 199, function: multi_heap_free
abort() was called at PC 0x400e34fb on core 1

Backtrace: 0x40087d6c:0x3ffd5df0 0x40087e6b:0x3ffd5e10 0x400e34fb:0x3ffd5e30 0x40087a7d:0x3ffd5e60 0x40083b72:0x3ffd5e80 0x400840f5:0x3ffd5ea0 0x4000bec7:0x3ffd5ec0 0x40100da5:0x3ffd5ee0 0x40100e67:0x3ffd5f00 0x400d4ac9:0x3ffd5f20 0x400fd42d:0x3ffd5f40

Error 4:

assertion "tcp_input: active pcb->state != CLOSED" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/core/tcp_in.c", line 217, function: tcp_input
abort() was called at PC 0x400e34fb on core 1

Backtrace: 0x40087d6c:0x3ffd5e70 0x40087e6b:0x3ffd5e90 0x400e34fb:0x3ffd5eb0 0x40102cb5:0x3ffd5ee0 0x401073b2:0x3ffd5f00 0x4010c98e:0x3ffd5f20 0x400fd449:0x3ffd5f40

Error 5:

Guru Meditation Error: Core  1 panic'ed (InstrFetchProhibited)
. Exception was unhandled.
Register dump:
PC      : 0xadff1c7e  PS      : 0x00060130  A0      : 0x800d52d2  A1      : 0x3ffe3900  
A2      : 0x3ffe7e34  A3      : 0x000000f4  A4      : 0x3ffe192c  A5      : 0x00000000  
A6      : 0x3ffe195c  A7      : 0x00000001  A8      : 0x800d5195  A9      : 0x3ffe38e0  
A10     : 0x3ffe7e74  A11     : 0x3ffe3908  A12     : 0x3ffe390c  A13     : 0x3ffe3907  
A14     : 0x3ffe390c  A15     : 0x3ffe19e0  SAR     : 0x00000010  EXCCAUSE: 0x00000014  
EXCVADDR: 0xadff1c7c  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  

Backtrace: 0x6dff1c7e:0x3ffe3900 0x400d52cf:0x3ffe3930

@XYZVector
Copy link

XYZVector commented Feb 21, 2018

I am experiencing the same errors also. I'm trying to get my JTAG debugger setup but it is very touchy especially when in the core guts of the memory allocation functions. All you have to do to recreate the problem is just open up a web socket and start sending text. I was waiting until there was others that had the problem before posting. Thinking it was something in my code, I am confirming Error2 in the previous post. Now I did clear up the some errors, by making the onWS callback function simple and placing any memory it modifies in a critical section. I believed for awhile that the issue was sending large amounts of text with WebSocket->textAll function. I think that the callback function of the web socket is invoked from another thread. For those young players this means that you have to take thread synchronization into account. I have done that by placing my callback function of the received data so that the data it modifies it does so in a critical section. This helped with other errors but this one still remains. This is on a textAll function call, however it is in the task that handles the lwip functions. Below is the stack backtrace decoded.

0x40088274: invoke_abort at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/./panic.c line 578
0x40088373: abort at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/./panic.c line 578
0x400f8cff: __assert_func at /Users/ivan/e/newlib_xtensa-2.2.0-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/stdlib/../../../.././newlib/libc/stdlib/assert.c line 63 (discriminator 8)
0x40087f85: multi_heap_free at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/./multi_heap_poisoning.c line 284
0x4008409a: heap_caps_free at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/./heap_caps.c line 136
0x40084625: _free_r at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/newlib/./syscalls.c line 42
0x40134391: tcp_close_shutdown at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/core/tcp.c line 225
0x40134453: tcp_close at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/core/tcp.c line 305
0x400e95d1: _tcp_close_api(tcpip_api_call*) at C:\Users\Andre\Documents\Arduino\libraries\AsyncTCP-master\src/AsyncTCP.cpp line 704
0x40130acd: tcpip_thread at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/api/tcpip.c line 474

On the client side I usually get this error in the web browser.
WebSocket connection to 'ws://charmasterv9.local/ws' failed: Received unexpected continuation frame.
O @ (index):24

When that happens the processor throws

assertion "head != NULL" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/./multi_heap_poisoning.c", line 199, function: multi_heap_free

Any help would be greatly appreciated.

This might not be in this library also as I have seen a lot of issues with heap corruption detection code screwing up other items. It might be issues with one task allocates memory and another frees it, causing issues.

@kemaddux
Copy link

kemaddux commented Mar 8, 2018

My esp32 is having similar issues with random crashes, sometime within a few hours or maybe runs a day.
So far, if all references to the ArduinoOTA are removed, no crashes have happened during the couple of day of testing. Still working on configuring mDNS to work properly with hostnames without OTA. The same sketch running on a esp8266, using the proper headers and OTA runs for months at a time and never has had any crashes. Not that this is an esp32 OTA issue, so far it is a good workaround for me.

@xfdr0805
Copy link

I am also caught with a similar error.

Connecting to WiFi...
Connected to the WiFi network
192.168.5.3

ws[/ws][1] connect
ws[/ws][1] text-message[9]: reconcent
ws[/ws][1] pong[0]:
ws[/ws][1] text-message[41]: {"CMD":"START","AMP_ID":2,"AMP_SN":"123"}
ws[/ws][1] error(1002): Unexpected continuation螨?(
ws[/ws][1] disconnect: 1073607000
ws[/ws][2] connect
ws[/ws][2] text-message[9]: reconcent
ws[/ws][2] pong[0]:
ws[/ws][2] disconnect: 1073607000
ws[/ws][3] connect
ws[/ws][3] text-message[9]: reconcent
ws[/ws][3] pong[0]:
ws[/ws][3] error(1002): Unexpected continuation0,0,0]}锞x锞xV颀?★?酗?
ws[/ws][3] disconnect: 1073607000
ws[/ws][4] connect
ws[/ws][4] text-message[9]: reconcent
ws[/ws][4] pong[0]:
ws[/ws][4] text-message[44]: {"CMD":"START","AMP_ID":3,"AMP_SN":"123456"}
ws[/ws][4] error(1002): Unexpected continuation78,49.26,0,0锞xVx斤?l瘕?(
CORRUPT HEAP: Bad head at 0x3ffdf1cc. Expected 0xabba1234 got 0x3ffdf35c
assertion "head != NULL" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/./multi_heap_poisoning.c", line 199, function: multi_heap_free
abort() was called at PC 0x400dd277 on core 1

Backtrace: 0x400882ec:0x3ffd4210 0x400883eb:0x3ffd4230 0x400dd277:0x3ffd4250 0x40088015:0x3ffd4280 0x4008413a:0x3ffd42a0 0x400846c5:0x3ffd42c0 0x4000bec7:0x3ffd42e0 0x400f8f39:0x3ffd4300 0x400f8ffb:0x3ffd4320 0x4011b9d5:0x3ffd4340 0x400f6135:0x3ffd4360

Rebooting...
ets Jun 8 2016 00:22:57

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:2
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11404
entry 0x40078a28
Serial init OK!
Connecting to WiFi...

@JacoFourie
Copy link
Author

I have not had any issues using this lib https://github.com/bbx10/WebServer_tng . The ESP32 has been running for 3 weeks without any crash and I serve large html5 bootstrap files using web-sockets.

Here are the screens I am using and all is working fine using the other lib. Pity this one is so unstable.

dashb1
manual1

@me-no-dev
Copy link
Owner

Thanks @JacoFourie for sharing this... yes I know about the random crashes and I am looking into it... could not figure out why it happens yet but I have some TCP redesigns in mind that should help.

@JacoFourie I don't know if you realize this, but the server you liked is Sync server ;)

@JacoFourie
Copy link
Author

@me-no-dev sorry I don't understand what you mean by Sync server ?

@Pablo2048
Copy link

@JacoFourie if you have to call something like server.handleClient() in your loop() then its sync server (and supports probably only one connection @ time). Another disadvantage of sync server without native ws plugin is that you need two ports - one for www server and one for ws server. ESPAsyncWebServer IMHO handles more than one connection simultaneously and uses only one listening port for both www and ws part.

@JacoFourie
Copy link
Author

@Pablo2048 Aaa OK I get that. But the code I have can handle up to 20 connections at once. I tested it. I only need one connection as it will be a user interface to set the program values and view the telemetry. I would love to use this lib. But it crashes all the time. So even if the design is better, it does not work for my use with websockets. The other one does work 100% for my use, even if I do have to use another lib for the web sockets and define another port. I am willing to test this and port my code to this lib if they can sort out the crashes and reboots.

@GracefulTabby
Copy link

I monitored this bug while monitoring the heap.
Then, if you made two HTTP requests at the same time, you probably could confirm that this code exhausted the heap, though.
Although it depends on the page size, this seems to happen when reading a large page containing photos etc.
My web page is not using WS.
The page size is about 150 KB.

I do not know how to solve it, but it is good to use it.
Can not it be solved by not receiving simultaneous requests?

@GracefulTabby
Copy link

I gradually understood the structure, but I am pretty tough.
The current packet reception method is certainly necessary to use WebSocket.
However, it seems that HTTP request has also been received at the same time, and HEAP has been eliminated trying to respond to it at the same time.
We think that we can not solve it unless we make only one response to http request.
I am still looking for ways to improve, but now I am trying to improve on Async-TCP side.

@GracefulTabby
Copy link

GracefulTabby commented Mar 30, 2018

https://youtu.be/uN9DI5f46-w

I cited a video here.
This movie shows page loading and heap transition.
Here's what you want to see is how to press the F5 key with the keyboard capture in the bottom right.
The F5 key is updating the web page and you can destroy the heap by pressing it twice in a row.
The position is three places around 13 seconds, 29 seconds, and 39 seconds.
This seems to be due to double response to HTTP request.
The page size was 136 KB.
We look forward to helping you.

@vyruz1986
Copy link

I believe I've got the same problem, I put this on gitter last weekend and @me-no-dev confirmed it was reproducible:
I've been working on a version of my code which does as little as possible but still causes the crash to appear. What I've found out is that it only happens once I start using the ArduinoJson library. If I transmit a static JSON string the ESP never crashes.

When the ESP crashes this is always preceded by an error 1002 which has as data 'Unexpected continuation....' where the remainder of the string will have some combination of pieces from the JSON string and rubbish data. In some cases this error is shown but it's not followed by a crash.

The crash will only occur if the websocket client also sends a message, if you just leave it listening it keeps running for 10+ minutes without problems
As soon as you send some messages it will crash within the next minute.

I've uploaded the minimalist code which demonstrates the crash here.
Steps to reproduce:

  1. Compile and upload to ESP32 board (make sure you have ESP32-Arduino SDK, ESPAsyncWebServer and ArduinoJson libraries installed)
  2. Connect to the 'TestAP' access point which the ESP sets up (password TestAPPass)
  3. Use the chrome and the [Simple WEbsocket Client] to connect to the ESP on ws://192.168.20.1/ws
  4. When you're connected you should see a JSON string being sent every 200ms
  5. Enter a message (e.g. 'hello) into the Reqeust field of the websocket client, click send
  6. Repeat to send this message a couple of times, the crash should occur within the next minute

@valerivp
Copy link

Any news on the subject? This library is very good, but on ESP32 it can not be used.

@atanisoft
Copy link
Contributor

@valerivp I use websockets on an esp32 without issues. From the exceptions on the initial report it looks like a heap exhaustion issue which may not be related to this library.

@valerivp
Copy link

@atanisoft, Are you using this library or something? It is important for me to use HTTP and Websocket on the same port

@JacoFourie
Copy link
Author

I have not tested using another websockets lib with this web server lib. I have been using the other lib as stated and it is very stable. Been running for months now without any crashes. even if it is a sync server.

@valerivp
Copy link

valerivp commented Jun 18, 2018

@JacoFourie , which

the other lib

?

@JacoFourie
Copy link
Author

@JacoFourie
Copy link
Author

And I use this websocket server with the web server.

https://github.com/Links2004/arduinoWebSockets

@valerivp
Copy link

@JacoFourie , They work together on the same port (80)?

@JacoFourie
Copy link
Author

No. And that is why I would like to use this lib. But last time I check it was not stable at all. If the lib can be made stable on the ESP32 than I would move my code to this lib.

@RosCstr
Copy link

RosCstr commented Jun 18, 2018

The issues with ESPAsyncWebServer remain. Even with the most easy example of using this lib like (https://techtutorialsx.com/2017/12/01/esp32-arduino-asynchronous-http-webserver/) if you enter on page generated by esp32 <ip_adr>/hello from multiple computers and refresh the web-page it will result in the same errors and backtraces. Tested this last week multiple times.

Do not know if this is a espressif/esp-idf problem or if this results from the espressif/arduino_esp32

@BlackEdder
Copy link

If this is happening only on ESP32 (dual core) then this could well be a race issue. I had very similar problems using AsyncTCP in my code, because often onAck() would be called while the code was still dealing with the previous onAck().

I had (mistakenly) written the code assuming that events would never interrupt each other, which is fine on the ESP8266, but can lead to memory corruption on the ESP32.

@JacoFourie
Copy link
Author

@BlackEdder can you not have a look as it seems you have experience with this issue? It would be great if it can get fixed.

@atanisoft
Copy link
Contributor

@valerivp yes, I use this library and have extensive usage of websockets from an http page served by this library which makes callbacks to the esp32 via websockets. It is possible there is a race condition in the handlers in your code and you can add some guards for that using semaphores and delays etc. In all of my handlers I write them so they are simple and do a single task quickly and return control to the library/OS to avoid issues. I have plenty of other issues to handle (hardware interrupt tasks every 50-70ms as example).

@valerivp
Copy link

My project work correctly on ESP8266, but on ESP32 я have problem with webcocket

@atanisoft
Copy link
Contributor

There are major architecture differences between esp32 and esp8266. More than likely it is not a bug in this library but instead a race condition or other single threaded design pattern in your code or another library you are using that is at fault.

@JacoFourie
Copy link
Author

I get errors with the sample. So then how should one use it ?

@theZaX
Copy link

theZaX commented Aug 7, 2018

As far as making this work I was reading about many similar issues when using web sockets with AsyncTCP It is my intuition that it is not an issue with this library but something deeper as this mostly just builds upon AsyncTCP. I read about a workaround that adds a handler into the Async loop this would prevent any issues of both your code and the loop trying to send at the same time, but I can't remember where I saw that.

@JacoFourie
Copy link
Author

I see now I am using the Arduino Core web server. I installed my IDE using the new method and the IDE picked that lib. So all is working using the core webserver also.

@JacoFourie
Copy link
Author

Here is the system I am working on. Now porting it to the M5Stack,
https://www.youtube.com/watch?v=jYnhPLxoM1k

@me-no-dev
Copy link
Owner

Can you all with this issue (that you can reproduce) test it with different browsers? I get conflicting reports that maybe Chrome/Webkit is causing this to happen. The more I know, the easier it will be to pinpoint the problem.

@JacoFourie
Copy link
Author

My default browser is Fire Fox. I will test with some other browsers also.

@zhivko
Copy link

zhivko commented Aug 13, 2018

I can reproduce in Firefox and Chromium browsers.

@zhivko
Copy link

zhivko commented Aug 14, 2018

I can reproduce continuation error with this simple project:
https://github.com/zhivko/esp32_asyncws/blob/master/src/Server.ino
After browser connects to esp32 asyncwebserver client dies in 16 seconds with opcode=-1 in chromium/firefox browser
On esp32 I get:

 [W][AsyncTCP.cpp:539] _poll(): rx timeout 4
49743 ws[/ws][2] error(1002): Unexpected continuation
49744 ws[/ws][2] disconnect

@zhivko
Copy link

zhivko commented Aug 16, 2018

Just tried commit 4c621f3 and it works for me. 👍

@RosCstr
Copy link

RosCstr commented Aug 16, 2018

Hello again - updated comment,

I also tried the commit "4c621f3" and I see that the problem persists unfortunately... The code that I tested on is presented in the ESPAsyncWebServer in the examples, the simple_server.ino (https://github.com/me-no-dev/ESPAsyncWebServer/blob/master/examples/simple_server/simple_server.ino).

In order to reproduce the issue:

  • if I am refreshing the same page from the same pc (this happens only at way multiple refreshes)
  • if I am refreshing the same page from 2 pc's (it happens fast - only few successive refreshes are needed from both pc's)
  • if from the first pc I am refreshing as an example: 192.168.1.195/ and pc 2: 192.168.1.195/get
    => In all the above situations, at successive refresses I get one of the next two errors cases and the ESP reboots:

Case 1:

CORRUPT HEAP: Bad head at 0x3ffbdba4. Expected 0xabba1234 got 0x3ffbe034**
E (53501) boot: Assert failed in multi_heap_free, /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap_poisoning.c:205 (head != NULL)
Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC      : 0x400db4bd  PS      : 0x00060934  A0      : 0x8008f3c4  A1      : 0x3ffbbba0  
A2      : 0x3ffc3b38  A3      : 0x000000cd  A4      : 0x3ffc3bfc  A5      : 0x3ffc3b28  
A6      : 0x3ffbeaa9  A7      : 0x00000000  A8      : 0x800db4bd  A9      : 0x3ffbbb50  
A10     : 0x400ed2f0  A11     : 0x3ffc50c8  A12     : 0x3f4033f0  A13     : 0x00000008  
A14     : 0x00000002  A15     : 0x00000001  SAR     : 0x00000004  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffffc  
Backtrace: 0x400db4bd:0x3ffbbba0 0x4008f3c1:0x3ffbbbd0 0x40084782:0x3ffbbbf0 0x40086949:0x3ffbbc10 0x4000bec7:0x3ffbbc30 0x400d889a:0x3ffbbc50 0x400d6bb9:0x3ffbbc70 0x400d6bca:0x3ffbbc90 0x400d63aa:0x3ffbbcb0 0x400d71f5:0x3ffbbcd0 0x400d4153:0x3ffbbcf0 0x400d4161:0x3ffbbd10 0x400d7c8e:0x3ffbbd30 0x400d7f51:0x3ffbbd60 0x400d807f:0x3ffbbd90
PC: 0x400db4bd: __assert_func at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/bootloader_support/src/bootloader_init.c line 523
EXCVADDR: 0x00000000
Decoding stack results
0x400db4bd: __assert_func at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/bootloader_support/src/bootloader_init.c line 523
0x4008f3c1: multi_heap_free at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap_poisoning.c line 205
0x40084782: heap_caps_free at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/heap_caps.c line 262
0x40086949: _free_r at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/newlib/syscalls.c line 42
0x400d889a: String::~String() at C:\Users\v.florian\git\arduino-esp32\cores\esp32\WString.cpp line 129
0x400d6bb9: AsyncWebServerResponse::~AsyncWebServerResponse() at C:\Users\v.florian\Documents\3rdparty_lib_gits\ESPAsyncWebServer\src\WebResponses.cpp line 103
0x400d6bca: AsyncWebServerResponse::~AsyncWebServerResponse() at C:\Users\v.florian\Documents\3rdparty_lib_gits\ESPAsyncWebServer\src\WebResponses.cpp line 105
0x400d63aa: AsyncWebServerRequest::~AsyncWebServerRequest() at C:\Users\v.florian\Documents\3rdparty_lib_gits\ESPAsyncWebServer\src\WebRequest.cpp line 87
0x400d71f5: AsyncWebServer::_handleDisconnect(AsyncWebServerRequest*) at C:\Users\v.florian\Documents\3rdparty_lib_gits\ESPAsyncWebServer\src\WebServer.cpp line 97
0x400d4153: AsyncWebServerRequest::_onDisconnect() at C:\Users\v.florian\Documents\3rdparty_lib_gits\ESPAsyncWebServer\src\WebRequest.cpp line 226
0x400d4161: std::_Function_handler   >::_M_invoke(const std::_Any_data &,  ,  ) at C:\Users\v.florian\Documents\3rdparty_lib_gits\ESPAsyncWebServer\src\WebRequest.cpp line 73
0x400d7c8e: std::function ::operator()(void*, AsyncClient*) const at c:\users\v.florian\git\arduino-esp32\tools\xtensa-esp32-elf\xtensa-esp32-elf\include\c++\5.2.0/functional line 2271
0x400d7f51: AsyncClient::_error(signed char) at C:\Users\v.florian\Documents\3rdparty_lib_gits\AsyncTCP\src\AsyncTCP.cpp line 489
0x400d807f: _async_service_task(void*) at C:\Users\v.florian\Documents\3rdparty_lib_gits\AsyncTCP\src\AsyncTCP.cpp line 901

Core 0 register dump:
PC      : 0x4008cf7e  PS      : 0x00060034  A0      : 0x8008ecfe  A1      : 0x3ffb6f00  
A2      : 0x3ffae718  A3      : 0x0000cdcd  A4      : 0xb33fffff  A5      : 0x00000001  
A6      : 0x00060e20  A7      : 0x0000abab  A8      : 0x0000cdcd  A9      : 0x3ffb7020  
A10     : 0x3ffbe0d0  A11     : 0x00000036  A12     : 0x3ffbe040  A13     : 0x3ffbe070  
A14     : 0x3ffbe0b4  A15     : 0x3ffc8bb0  SAR     : 0x00000010  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x4000c349  LEND    : 0x4000c36b  LCOUNT  : 0xffffffff  
Backtrace: 0x4008cf7e:0x3ffb6f00 0x4008ecfb:0x3ffb6f30 0x4008f373:0x3ffb6f50 0x40084688:0x3ffb6f70 0x4008473e:0x3ffb6f90 0x400f88a9:0x3ffb6fe0 0x401077a0:0x3ffb7000 0x400df2be:0x3ffb7020 0x40120239:0x3ffb7040 0x40120e15:0x3ffb7110 0x4012c63d:0x3ffb7130 0x40088a72:0x3ffb7180
PC: 0x4008cf7e: vTaskEnterCritical at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/include/freertos/portmacro.h line 282
EXCVADDR: 0x00000000
Decoding stack results
0x4008cf7e: vTaskEnterCritical at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/include/freertos/portmacro.h line 282
0x4008ecfb: multi_heap_internal_lock at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap.c line 372
0x4008f373: multi_heap_malloc at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap_poisoning.c line 181
0x40084688: heap_caps_malloc at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/heap_caps.c line 103
0x4008473e: heap_caps_malloc_prefer at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/heap_caps.c line 181
0x400f88a9: pbuf_alloc at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/core/pbuf.c line 327
0x401077a0: wlanif_input at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/port/netif/wlanif.c line 165
0x400df2be: tcpip_adapter_sta_input at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/tcpip_adapter/tcpip_adapter_lwip.c line 1086

=========================================================

Case 2:

Guru Meditation Error: Core  1 panic'ed (LoadStoreError). Exception was unhandled.
Core 1 register dump:
PC      : 0x400f960c  PS      : 0x00060330  A0      : 0x800d7cc3  A1      : 0x3ffbbbe0  
A2      : 0x401411f0  A3      : 0x00000000  A4      : 0x00000000  A5      : 0x3ffbbc80  
A6      : 0x3ffbf670  A7      : 0x00000000  A8      : 0x04cd1522  A9      : 0x3ffbbbf0  
A10     : 0x3ffb0000  A11     : 0x3ffbf640  A12     : 0xc0400000  A13     : 0x3ffbd8ec  
A14     : 0x00000007  A15     : 0x00000001  SAR     : 0x0000000a  EXCCAUSE: 0x00000003  
EXCVADDR: 0x40141234  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  
Backtrace: 0x400f960c:0x3ffbbbe0 0x400d7cc0:0x3ffbbc00 0x400d7ff9:0x3ffbbc40 0x400d806b:0x3ffbbc70
PC: 0x400f960c: tcp_poll at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/core/tcp.c line 1732
EXCVADDR: 0x40141234: AsyncCallbackWebHandler::handleUpload(AsyncWebServerRequest*, String const&, unsigned int, unsigned char*, unsigned int, bool) at c:\users\v.florian\git\arduino-esp32\tools\xtensa-esp32-elf\xtensa-esp32-elf\include\c++\5.2.0/functional line 2271
Decoding stack results
0x400f960c: tcp_poll at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/core/tcp.c line 1732
0x400d7cc0: AsyncClient::_close() at C:\Users\v.florian\Documents\3rdparty_lib_gits\AsyncTCP\src\AsyncTCP.cpp line 461
0x400d7ff9: AsyncClient::_poll(tcp_pcb*) at C:\Users\v.florian\Documents\3rdparty_lib_gits\AsyncTCP\src\AsyncTCP.cpp line 550
0x400d806b: _async_service_task(void*) at C:\Users\v.florian\Documents\3rdparty_lib_gits\AsyncTCP\src\AsyncTCP.cpp line 886

.

Most of the time I get just the first error case, with the "CORRUPT HEAP: Bad head at 0x3ffbdba4. Expected 0xabba1234 got 0x3ffbe034". The second error case happens more rare.
Sorry for the long post

@me-no-dev
Copy link
Owner

please decode any backtrace exception you get. The message on it's own does not mean much

@me-no-dev
Copy link
Owner

Also it's important to separate WebSocket issues from other issues. They might or might not be related.
Overall I have the feeling that I need to account for FreeRTOS on ESP32 and that might result in splitting the libs if too much ifdefs are required... we will see.

In all cases! Please post minimal example sketches and instructions on how to reproduce the issues you have. If I can reproduce an issue, chances are that I will fix it :)

Also! Don't be shy and come to gitter :) I get hundreds of emails daily and going through them is not easy

@me-no-dev
Copy link
Owner

I have just pushed an update to the AsyncTCP lib. please give it a go (in combination with the latest code for the server)

@RosCstr
Copy link

RosCstr commented Aug 20, 2018

I updated the AsyncTCP and ESPAsyncWebServer to the commit heads from last Thursday and now to the latest commits.

I tested again with the code from: the simple_server.ino (https://github.com/me-no-dev/ESPAsyncWebServer/blob/master/examples/simple_server/simple_server.ino).

Tests were conducted on: Google Chrome/Mozila Firefox/internet Explorer Edge.

What I tested was refreshing the same page ex: 192.168.1.195/ on 2 different pc's in the same web browser and testing 2 different pages, ex: pc 1:192.168.1.195/ and pc 2: 192.168.1.195/get in the same web browser as explained bellow.

.

=> results using ESPAsyncWebServer commit: 4c621f3 and AsyncTCP commit: 34a0320 (the txt files have also the results from Exception decoder plugin)

Small facts: what I saw was that the Esp32 cracks with the above traces usually after multiple msgs like
[W][AsyncTCP.cpp:614] _poll(): rx timeout 4
are seen in the console. The only web browser that does not give the above warning msg and does not crash the ESP32 is Internet Explorer

.

=> results using ESPAsyncWebServer commit: bed4146 and AsyncTCP commit: 5453ec2 (the txt files have also the results from Exception decoder plugin):

Small facts: what I saw was that the Esp32 cracks with the above traces usually after multiple msgs like
[W][AsyncTCP.cpp:614] _poll(): rx timeout 4
are seen in the console. The only web browser that does not give the above warning msg and does not crash the ESP32 is Internet Explorer

.

I hope that the above documents can shine some light over the problem.

@Garito
Copy link

Garito commented Sep 30, 2018

Hi!
I'm having an issue that looks very similar to this one only that with server events
I have not investigated my issue enough (yet) but this will close the search if related
Can they be?

@JacoFourie
Copy link
Author

So this lib is still not working using websockets with the webserver ?

@zekageri
Copy link

This is still an open issue. There was a huge progress on it. With the latest Async TCP lib is very stable for me. However when i open my webpages from SOFTAP with an android phone, the restart and the heap poisoning is always coming back.
But most of the time i get that error message:

dhcps: send_offer>>udp_sendto result 0
[D][WiFiGeneric.cpp:336] _eventCallback(): Event: 17 - AP_STAIPASSIGNED
assertion "new_rcv_ann_wnd <= 0xffff" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/lwip/src/core/tcp.c", line 779, function: tcp_update_rcv_ann_wnd
abort() was called at PC 0x4010305f on core 0

Backtrace: 0x4008d894:0x3ffb4e70 0x4008dac5:0x3ffb4e90 0x4010305f:0x3ffb4eb0 0x40129c9a:0x3ffb4ee0 0x40129d29:0x3ffb4f00 0x40155da1:0x3ffb4f20 0x401266c8:0x3ffb4f40 0x400897b1:0x3ffb4f70

Decoded:

Decoding stack results
0x4008d894: invoke_abort at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/panic.c line 155
0x4008dac5: abort at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/panic.c line 170
0x4010305f: __assert_func at ../../../.././newlib/libc/stdlib/assert.c line 63
0x40129c9a: tcp_update_rcv_ann_wnd at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/lwip/src/core/tcp.c line 779
0x40129d29: tcp_recved at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/lwip/src/core/tcp.c line 820
0x401266c8: tcpip_thread at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/lwip/src/api/tcpip.c line 124
0x400897b1: vPortTaskWrapper at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/port.c line 143

I'am not doing anything else then opening a page on android phone in the softap. In that page there are 1-2 websocket calls when the server loaded. But the crash happens before the websocket calls.

@matt123p
Copy link
Contributor

matt123p commented Sep 7, 2019

I have submitted 3 Pull Requests, which seem together fix all of the instability I have had with websockets.

The 3 problems I identified are:

  1. Some browsers do not close the socket which can cause a memory leak if left unchecked.
  2. There is a race condition (threading issue) around the use of websocket buffers
  3. There is a race condition around the closing of websockets - this is particularly acute when you close the browser window.

With these three changes in place I have not seen the ESP32 reboot, although I am not doing any kind of serious testing at the moment.

It would be great if anyone who still has instability issues around the websockets to give the changes a go.

@WonderWhyWilli
Copy link

@matt123p Thank you, it runs much more stable now (no crashes especially on Chrome with normal site refreshes).

But I managed to crash it nonetheless with Chrome and Edge (extreme refreshes):

  • load any site from the ESP32
  • on Chrome: press F12 (developer mode)
  • hold F5
  • It will crash in a few seconds

Crashes are:

  • heap corruption (most of the time: ... got 0x00000000)
  • (Sometimes) Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.

But I don't know if this is websocket related or not...

@matt123p
Copy link
Contributor

matt123p commented Sep 8, 2019

Unfortunately I blew up my last ESP32, so I can't test at the moment, but if I had to guess, I would say you are hitting some kind of resource limit. If you want to debug the problem further, then you should check the number of open sockets at any one time and make sure it isn't spiralling upwards.

You can look at calling count() on the websockets object or if that isn't the problem then try checking the open of open AsyncTCP sockets (there is no functionality to do this - so you would have to add the code to do the counting).

I will be able to have a better look when I get a new ESP32.

@JacoFourie
Copy link
Author

Hi. Where do I find the latest version of this that you state is stable now? I would like to test it and I will give you feedback.

@matt123p
Copy link
Contributor

matt123p commented Sep 8, 2019

Hi. Where do I find the latest version of this that you state is stable now? I would like to test it and I will give you feedback.

Sorry forgot to mention that - you can download a copy from my fork: matt123p/ESPAsyncWebServer

There is a small code change required, you need to call "cleanupClients()" periodically from your main loop - in my test I do this around once per second.

@stale
Copy link

stale bot commented Nov 7, 2019

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Nov 7, 2019
@stale
Copy link

stale bot commented Nov 21, 2019

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.

@stale stale bot closed this as completed Nov 21, 2019
@XYZVector
Copy link

This issue seems to be resolved in the latest close this one out. Thanks me-no-dev for your library and time.

@un0038998
Copy link

I faced the similar issues with AsyncWebSocket when sending huge data continuously .
I was sending binary image from esp32 cam board and each image was 5Kb .
So when we keep sending messages , the queue gets full if connection is slow or receiver is slow.
Then It consumes whole heap memory available for esp32 board (max heap available around 180kb) .
So I changed the WS_MAX_QUEUED_MESSAGES parameter to 15 from 32. So the max messages queued will have the total size of 15*5kb = 75kb which is much less than total heap .
It resolved the issue for me and it never crashed again .
You can change this setting in AsyncWebSocket.H file in the library folder.

Check the size of the messages you are sending and set this parameter.
Hope this might help.

@VikingVoltage
Copy link

My post may be relevant.

@un0038998
Copy link

un0038998 commented Apr 18, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests