Watchdog reset with websocket and SPIFFS

Hello,

I'm experiencing some troubles with my webserver for an automatic bartender. I'm currently experimenting with the idea of having a page 2 for settings. Everything works great when using windows PC but when trying to navigate forth and back between settings page and main page i get a watch dog reset.

The project is using websocket and SPIFFS. There is index.html and settings.html in the .data folder. It crashed as soon as i press the setting button using my iphone.

Here is my arduino code:

// Import required libraries
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>

// Replace with your network credentials
const char *ssid = "ASUS_B0";
const char *password = "essay_5457";

bool ledState = 0;
const int ledPin = 2;

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

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

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

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP Local IP Address
  Serial.println(WiFi.localIP());

  initSPIFFS();
  initWebSocket();


  // Route for root / web page
  initWebServer();




  // Start server
}


void loop() {



  ws.cleanupClients();
  digitalWrite(ledPin, ledState);
}






void notifyClients() {
  ws.textAll(String(ledState));
}

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;
      notifyClients();
    } else if (strcmp((char *)data, "settings") == 0) {
      Serial.println("settings");



    } else if (strcmp((char *)data, "tillbaka") == 0) {
      Serial.println("tillbaka");

      server.on("/", HTTP_ANY, [](AsyncWebServerRequest *request) {
        request->send(SPIFFS, "/index.html");
      });


    }

    else {
      Serial.println((char *)data);
      Serial.println("ovan");
    }
  }
}

void onEvent(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);
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
  }
}

void initWebSocket() {
  ws.onEvent(onEvent);
  server.addHandler(&ws);
}

String processor(const String &var) {
  Serial.println(var);
  if (var == "STATE") {
    if (ledState) {
      return "ON";
    } else {
      return "OFF";
    }
  }
  return String();
}

void onRootRequest(AsyncWebServerRequest *request) {
  request->send(SPIFFS, "/index.html", "text/html", false, processor);
}

void initWebServer() {
  server.on("/", onRootRequest)
  server.on("/settings", HTTP_ANY, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/settings.html");
  });

  server.serveStatic("/", SPIFFS, "/");
  server.begin();
}

void initSPIFFS() {
  if (!SPIFFS.begin()) {
    Serial.println("Cannot mount SPIFFS volume...");
    while (1) {
      //onboard_led.on = millis() % 200 < 50;
      //onboard_led.update();
    }
  }
}

Here is index.HTML:

<!DOCTYPE HTML><html>
<head>
  <title>ESP Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
  html {
    font-family: Arial, Helvetica, sans-serif;
    text-align: center;
  }
  h1 {
    font-size: 1.8rem;
    color: white;
  }
  h2{
    font-size: 1.5rem;
    font-weight: bold;
    color: #143642;
  }
  .topnav {
    overflow: hidden;
    background-color: #143642;
  }
  body {
    margin: 0;
  }
  .content {
    padding: 30px;
    max-width: 600px;
    margin: 0 auto;
  }
  .card {
    background-color: #F8F7F9;;
    box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
    padding-top:10px;
    padding-bottom:20px;
  }
  .button {
    padding: 15px 50px;
    font-size: 24px;
    text-align: center;
    outline: none;
    color: #fff;
    background-color: #0f8b8d;
    border: none;
    border-radius: 5px;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
   }
   /*.button:hover {background-color: #0f8b8d}*/
   .button:active {
     background-color: #0f8b8d;
     box-shadow: 2 2px #CDCDCD;
     transform: translateY(2px);
   }
   .state {
     font-size: 1.5rem;
     color:#8c8c8c;
     font-weight: bold;
   }
  </style>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
</head>
<body>
  <div class="topnav">
    <h1>ESP WebSocket Server</h1>
  </div>
  <div class="content">
    <div class="card">
      <h2>Bartender</h2>

     	<p><button id="drink1" class="button">Drink 1</button></p>
	<p><button id="drink2" class="button">Drink 2</button></p>
	<p><button id="drink3" class="button">Drink 3</button></p>
	<p><a href=\settings><button id="settings" class="button">settings</button></p>
    
	</div>
  </div>
<script>
  var gateway = `ws://${window.location.hostname}/ws`;
  var websocket;
  window.addEventListener('load', onLoad);
  function initWebSocket() {
    console.log('Trying to open a WebSocket connection...');
    websocket = new WebSocket(gateway);
    websocket.onopen    = onOpen;
    websocket.onclose   = onClose;
    websocket.onmessage = onMessage; // <-- add this line
  }
  function onOpen(event) {
    console.log('Connection opened');
  }
  function onClose(event) {
    console.log('Connection closed');
    setTimeout(initWebSocket, 2000);
  }
  function onMessage(event) {
    var state;
    if (event.data == "1"){
      state = "ON";
    }
    else{
      state = "OFF";
    }
    document.getElementById('state').innerHTML = state;
  }
  function onLoad(event) {
    initWebSocket();
    initButton();
  }
  function initButton() {
    	document.getElementById('drink1').addEventListener('click', drink1);
	document.getElementById('drink2').addEventListener('click',drink2);
	document.getElementById('drink3').addEventListener('click', drink3);
	document.getElementById('settings').addEventListener('click', settings);
  }
  
function drink1(){
    websocket.send('drink1');
  }

function drink2(){
    websocket.send('drink2');
  }

function drink3(){
    websocket.send('drink3');
  }
 

 function settings(){
    websocket.send('settings');
}


</script>
</body>
</html>

And here is settings.html:

<!DOCTYPE HTML><html>
<head>
  <title>ESP Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
  html {
    font-family: Arial, Helvetica, sans-serif;
    text-align: center;
  }
  h1 {
    font-size: 1.8rem;
    color: white;
  }
  h2{
    font-size: 1.5rem;
    font-weight: bold;
    color: #143642;
  }
  .topnav {
    overflow: hidden;
    background-color: #143642;
  }
  body {
    margin: 0;
  }
  .content {
    padding: 30px;
    max-width: 600px;
    margin: 0 auto;
  }
  .card {
    background-color: #F8F7F9;;
    box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
    padding-top:10px;
    padding-bottom:20px;
  }
  .button {
    padding: 15px 50px;
    font-size: 24px;
    text-align: center;
    outline: none;
    color: #fff;
    background-color: #0f8b8d;
    border: none;
    border-radius: 5px;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
   }
   /*.button:hover {background-color: #0f8b8d}*/
   .button:active {
     background-color: #0f8b8d;
     box-shadow: 2 2px #CDCDCD;
     transform: translateY(2px);
   }
   .state {
     font-size: 1.5rem;
     color:#8c8c8c;
     font-weight: bold;
   }
  </style>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
</head>
<body>
  <div class="topnav">
    <h1>ESP WebSocket Server</h1>
  </div>
  <div class="content">
    <div class="card">
      <h2>Settings</h2>
      <p><button id="Glasstorlek" class="button">Glasstorlek</button></p>
	<p><button id="Recept" class="button">Recept</button></p>
	<p><button id="Rensning" class="button">Rensning</button></p>
	<p><a href=\><button id="Rensning" class="button">Tillbaka</button></p>
    
	</div>
  </div>
<script>
  var gateway = `ws://${window.location.hostname}/ws`;
  var websocket;
  window.addEventListener('load', onLoad);
  function initWebSocket() {
    console.log('Trying to open a WebSocket connection...');
    websocket = new WebSocket(gateway);
    websocket.onopen    = onOpen;
    websocket.onclose   = onClose;
    websocket.onmessage = onMessage; // <-- add this line
  }
  function onOpen(event) {
    console.log('Connection opened');
  }
  function onClose(event) {
    console.log('Connection closed');
    setTimeout(initWebSocket, 2000);
  }
  function onMessage(event) {
    var state;
    if (event.data == "1"){
      state = "ON";
    }
    else{
      state = "OFF";
    }
    document.getElementById('state').innerHTML = state;
  }
  function onLoad(event) {
    initWebSocket();
    initButton();
  }
  function initButton() {
    	document.getElementById('Glasstorlek').addEventListener('click', glasstorlek);
	document.getElementById('Recept').addEventListener('click', recept);
	document.getElementById('Rensning').addEventListener('click', rensning);	
	document.getElementById('Rensning').addEventListener('click', tillbaka);
  }
  function toggle(){
    websocket.send('toggle');
  }
 
  function printa(){
    websocket.send('printa');
}

   function tillbaka(){
    websocket.send('tillbaka');
}


</script>
</body>
</html>

Last but not least, the watchdog reset:

23:35:31.339 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
23:35:31.370 -> 
23:35:31.370 ->  ets Jan  8 2013,rst cause:2, boot mode:(3,6)
23:35:31.370 -> 
23:35:31.370 -> load 0x4010f000, len 3460, room 16 
23:35:31.370 -> tail 4
23:35:31.409 -> chksum 0xcc
23:35:31.409 -> load 0x3fff20b8, len 40, room 4 
23:35:31.409 -> tail 4
23:35:31.409 -> chksum 0xc9
23:35:31.409 -> csum 0xc9
23:35:31.409 -> v00055aa0
23:35:31.409 -> ~ld

Does anyone of you guys have any idea why it responds differently to using an iphone compared to windows PC? And if so, if there is any fix for this.

BR
Joel

Because you probably use Chrome (or a derivative) on the PC but on the iPhone you're forced to Apple's view of how the web should work. I have to guess about the reason for the failure but an ESP32 isn't a full-fledged webserver. The ESP32 can handle up to 8 tcp connections. If they are closed correctly if the page is left that number is enough for your application. But if the browser doesn't close the connection but just don't serve the connection any longer it may stay open for a longer time.
I would would rewrite your application so it stays on the index.html but may display the settings inside that page. That holds open just one websocket and your probably fine.

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