Skip to content

AsyncWebServer with other Port constantly generates restarts receiving the IP #108

@mikrocoder

Description

@mikrocoder

Platform

ESP32 (XIAO ESP32S3)

IDE / Tooling

Arduino (IDE/CLI), Arduino IDE 2.3.4, Windows 11, Espressif Core 3.1.1 & C++20 (23)

What happened?

If you change the port for the Async WebServer, the ESP32 restarts immediately as soon as it has received the IP.

Stack Trace

23:23:23.942 -> Rebooting...
23:23:23.942 -> ESP-ROM:esp32s3-20210327
23:23:23.942 -> Build:Mar 27 2021
23:23:23.978 -> rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
23:23:23.978 -> Saved PC:0x4037a8e6
23:23:23.978 -> SPIWP:0xee
23:23:23.978 -> mode:DIO, clock div:1
23:23:23.978 -> load:0x3fce2820,len:0x1188
23:23:23.978 -> load:0x403c8700,len:0x4
23:23:23.978 -> load:0x403c8704,len:0xbf0
23:23:23.978 -> load:0x403cb700,len:0x30e4
23:23:23.978 -> entry 0x403c88ac
23:23:24.168 -> Connecting to ...............
23:23:39.213 -> Verbindung zum AP fehlgeschlagen
23:23:39.213 -> 
23:23:39.213 -> 
23:23:39.249 -> ESP-ROM:esp32s3-20210327
23:23:39.286 -> Build:Mar 27 2021
23:23:39.286 -> rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
23:23:39.286 -> Saved PC:0x4037a8e6
23:23:39.286 -> SPIWP:0xee
23:23:39.286 -> mode:DIO, clock div:1
23:23:39.286 -> load:0x3fce2820,len:0x1188
23:23:39.286 -> load:0x403c8700,len:0x4
23:23:39.286 -> load:0x403c8704,len:0xbf0
23:23:39.286 -> load:0x403cb700,len:0x30e4
23:23:39.286 -> entry 0x403c88ac
23:23:39.504 -> Connecting to .
23:23:40.561 -> Verbunden mit: FritziBoxi
23:23:40.561 -> Esp32 IP: 192.168.178.31
23:23:40.561 -> 
23:23:40.881 -> Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
23:23:40.881 -> 
23:23:40.881 -> Core  1 register dump:
23:23:40.881 -> PC      : 0x42099717  PS      : 0x00060030  A0      : 0x8200cc30  A1      : 0x3fca99b0  
23:23:40.881 -> A2      : 0x3fcb5ad4  A3      : 0x00000054  A4      : 0x00000003  A5      : 0x00000000  
23:23:40.881 -> A6      : 0x3c0c1d48  A7      : 0x0000000c  A8      : 0x8207f948  A9      : 0x3fca9990  
23:23:40.881 -> A10     : 0x3fcb5ad4  A11     : 0x3fca99a0  A12     : 0x00000001  A13     : 0x0000ff00  
23:23:40.881 -> A14     : 0x3fcb5128  A15     : 0x00000019  SAR     : 0x0000001a  EXCCAUSE: 0x0000001c  
23:23:40.881 -> EXCVADDR: 0x00000058  LBEG    : 0x40056fc5  LEND    : 0x40056fe7  LCOUNT  : 0xffffffff  
23:23:40.881 -> 
23:23:40.881 -> 
23:23:40.881 -> Backtrace: 0x42099714:0x3fca99b0 0x4200cc2d:0x3fca99d0 0x42002f3a:0x3fca99f0 0x42011897:0x3fca9a50 0x4037d902:0x3fca9a70

Minimal Reproductible Example (MRE)

// Import required libraries
#include <credentials.h> // ssid, password
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

bool ledState = true;
const int ledPin = LED_BUILTIN;

// Create AsyncWebServer object on port 80
// AsyncWebServer server(80); // original
AsyncWebServer *server; // siehe Zeile 164 - Port 81
AsyncWebSocket ws("/ws");

#define USED_ARDUINO_IDE_VERSION 20304// IDE 2.3.4

Stream &cout {Serial}; // Serial1.begin(115200, SERIAL_8N1, D11, D12) - Rx /Tx
constexpr bool DEBUG {false};

//#define WEBDEBUG        // Einkommentieren für die Webseite Ausgabe
#define SERIALDEBUG   // Einkommentieren für die Serielle Ausgabe

#if defined(SERIALDEBUG) && !defined(WEBDEBUG)
  #define DEBUG_B(...) Serial.begin(__VA_ARGS__)
  #define DEBUG_T(...) cout.print(__VA_ARGS__)
  #define DEBUG_P(...) cout.println(__VA_ARGS__)
  #define DEBUG_F(...) cout.printf(__VA_ARGS__)
#endif

#if defined(WEBDEBUG) &&  !defined(SERIALDEBUG)
  #define DEBUG_B(...) 
  #define DEBUG_T(...) WebSerial.print(__VA_ARGS__)
  #define DEBUG_P(...) WebSerial.println(__VA_ARGS__)
  #define DEBUG_F(...) WebSerial.printf(__VA_ARGS__)
#endif

#if (!defined(SERIALDEBUG) && !defined(WEBDEBUG)) || (defined(SERIALDEBUG) && defined(WEBDEBUG))
  #define DEBUG_B(...)
  #define DEBUG_T(...)
  #define DEBUG_P(...)
  #define DEBUG_F(...)
#endif

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>ESP32 WebSocket Server</title>
    <style>
    html{font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
    body{margin-top: 50px;}
    h1{color: #444444;margin: 50px auto;}
    p{font-size: 19px;color: #888;}
    #state{font-weight: bold;color: #444;}
    .switch{margin:25px auto;width:80px}
    .toggle{display:none}
    .toggle+label{display:block;position:relative;cursor:pointer;outline:0;user-select:none;padding:2px;width:80px;height:40px;background-color:#ddd;border-radius:40px}
    .toggle+label:before,.toggle+label:after{display:block;position:absolute;top:1px;left:1px;bottom:1px;content:""}
    .toggle+label:before{right:1px;background-color:#f1f1f1;border-radius:40px;transition:background .4s}
    .toggle+label:after{width:40px;background-color:#fff;border-radius:20px;box-shadow:0 2px 5px rgba(0,0,0,.3);transition:margin .4s}
    .toggle:checked+label:before{background-color:#4285f4}
    .toggle:checked+label:after{margin-left:42px}
    </style>
  </head>
  <body>
    <h1>ESP32 WebSocket Server</h1>
    <div class="switch">
      <input id="toggle-btn" class="toggle" type="checkbox" %CHECK%>
      <label for="toggle-btn"></label>
    </div>
    <p>On-board LED: <span id="state">%STATE%</span></p>

    <script>
	  window.addEventListener('load', function() {
		var websocket = new WebSocket(`ws://${window.location.hostname}/ws`);
		websocket.onopen = function(event) {
		  console.log('Connection established');
		}
		websocket.onclose = function(event) {
		  console.log('Connection died');
		}
		websocket.onerror = function(error) {
		  console.log('error');
		};
		websocket.onmessage = function(event) {
		  if (event.data == "1") {
			document.getElementById('state').innerHTML = "OFF";
			document.getElementById('toggle-btn').checked = false;
		  }
		  else {
			document.getElementById('state').innerHTML = "ON";
			document.getElementById('toggle-btn').checked = true;
		  }
		};
		
		document.getElementById('toggle-btn').addEventListener('change', function() { websocket.send('toggle'); });
	  });
	</script>
  </body>
</html>
)rawliteral";

void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
  AwsFrameInfo *info = (AwsFrameInfo*)arg;
  if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;
    if (strcmp((char*)data, "toggle") == 0) {
      ledState = !ledState;
      ws.textAll(String(ledState));
    }
  }
}

void eventHandler(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("WebSocket client #%u disconnected\n", client->id());
      break;
    case WS_EVT_DATA:
      handleWebSocketMessage(arg, data, len);
      digitalWrite(ledPin, ledState);
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
  }
}

String processor(const String& var){
  if(var == "STATE"){
      return ledState ? "OFF" : "ON";
  }
  if(var == "CHECK"){
    return ledState ? "checked" : "";
  }
  return String();
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);

  Serial.print("Connecting to ");
  // Connect to Wi-Fi
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    DEBUG_F(".");
    if (millis() > 15000) {
      DEBUG_P("\nVerbindung zum AP fehlgeschlagen\n\n");
      ESP.restart();
    }
  }
  DEBUG_P("\nVerbunden mit: " + WiFi.SSID());
  DEBUG_P("Esp32 IP: " + WiFi.localIP().toString() + "\n");

  ws.onEvent(eventHandler);
  server->addHandler(&ws); // orignal . statt ->

  // Route for root / web page
  server->on("/", HTTP_GET, [](AsyncWebServerRequest *request) { // orignal . statt ->
    request->send_P(200, "text/html", index_html, processor);
  });

  // Start server
  //server.begin(); // original
  server = new AsyncWebServer(81);
  server -> begin();
}

void loop() {
  ws.cleanupClients();
}

I confirm that:

  • I have read the documentation.
  • I have searched for similar discussions.
  • I have searched for similar issues.
  • I have looked at the examples.
  • I have upgraded to the lasted version of ESPAsyncWebServer (and AsyncTCP for ESP32).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions