Reboot with ELF file SHA256: cc613ecae273b465 error code

I´ve been taking my time writing this code using an ESP32 taking some parts from the internet and some others on my own.
Its purpose is to make a WebServer with a few switches, dimmers, and lately the reading of a sensor, which is where this issue began.
This is the code I’ve used, and at the end of it, I’ll add the debugging with the error codes, backtrace, and everything.
Hope you can help me!
Thank you in advance.


// Import required libraries
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
//#include <Ticker.h>
//#include <ESP32PWM.h>
#include <ArduinoOTA.h>
#include <string> 
#include <iostream>
using namespace std;
//#include <espexceptiondecoder>


// Replace with your network credentials
const char* ssid = "MyWifi";
const char* password = "MyPass";

const char* PARAM_INPUT_1 = "output";
const char* PARAM_INPUT_2 = "state";
const char* PARAM_INPUT_3 = "value";
const char* PARAM_INPUT_4 = "measurement";


const int sensorPin = 34;
const int dimmerPin = 22;

//const int timerPin = 6;
//const int timerInterval = 5000;  // Intervalo de tiempo para activar/desactivar el interruptor con temporizador en milisegundos


// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

//bool switchState = false;
int dimmerValue = 0;
bool timerSwitchState = false;
//Ticker timer;

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<body>
  <h2>SERVIDOR WEB ESP32</h2>
  %BUTTONPLACEHOLDER%
<script>

function toggleCheckbox(element) {
  var xhr = new XMLHttpRequest();
  //Comprueba si el checkbox está marcado
  if(element.checked)
  // Si está marcado, envía una solicitud GET al servidor con el estado 1
  { xhr.open("GET", "/update?output="+element.id+"&state=1", true); }
  else 
  // Si no está marcado, envía una solicitud GET al servidor con el estado 0
  { xhr.open("GET", "/update?output="+element.id+"&state=0", true); }
  
  // Envía la solicitud al servidor
  xhr.send();
}

function setDimmerValue(element) {
  var xhr_dim = new XMLHttpRequest();
  var value = element.value;
  
  xhr_dim.open("GET", "/update?output=" + element.id + "&value=" + value, true);
  xhr_dim.send();
}

setInterval(function() {
      var xhr_sen = new XMLHttpRequest();
      xhr_sen.onreadystatechange = function() {

        if (xhr_sen.readyState === 4 && xhr_sen.status === 200) {
          document.getElementById('sensor').textContent = xhr_sen.responseText;
        }
      };
      xhr_sen.open('GET', '/sensor', true);
      xhr_sen.send();
    }, 3000);


</script>

//ventana del sensor
<h4>Sensor Measurement:</h4>
<p>Valor: <span id="sensor"></span></p>

</body>
</html>
)rawliteral";

String outputState(int output){
  if(digitalRead(output)){
    return "checked";
  }
  else {
    return "";
  }
}

String DimmerOutputState(int dimoutput){
  dimmerValue=dimoutput;
  analogWrite(dimmerPin,dimmerValue);
  return "dimmerValue";
}

// Replaces placeholder with button section in your web page
String processor(const String& var){
  //Serial.println(var);
  if(var == "BUTTONPLACEHOLDER"){
    String buttons = "";
    buttons += "<h4>Switch Output - GPIO 2</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"2\" " + outputState(2) + "><span class=\"slider\"></span></label>";

    buttons += "<h4>Switch Output - GPIO 4</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"4\" " + outputState(4) + "><span class=\"slider\"></span></label>";

    buttons += "<h4>Switch Output - GPIO 33</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"33\" " + outputState(33) + "><span class=\"slider\"></span></label>";

    buttons += "<h4>Switch Output - GPIO 15</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"15\" " + outputState(15) + "><span class=\"slider\"></span></label>";

    // Dimmer
    buttons += "<h4>Dimmer</h4><input type=\"range\" min=\"0\" max=\"4095\" value=\"" + DimmerOutputState(dimmerValue) + "\" onchange=\"setDimmerValue(this)\" id=\"22\"><span class=\"slider\"></span>";

    return buttons;
  }
  return String();
}

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

//Switches

  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  pinMode(33, OUTPUT);
  digitalWrite(33, LOW);
  pinMode(15, OUTPUT);
  digitalWrite(15, LOW);

  //Dimmer
  pinMode(dimmerPin, OUTPUT);
  digitalWrite(dimmerPin, LOW);  

  //Sensor. La configuracion de este pin se incorpora en Loop()
  pinMode(sensorPin, INPUT);
  
  // 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());

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

  // Route for sensor value (aqui estoy tratando de recargar el valor como si fuera en void loop)
  server.on("/sensor", HTTP_GET, [](AsyncWebServerRequest *request){
  // Read the sensor value
    while (true){
    int sensorValue = analogRead(sensorPin);
    //Convert the sensor value to a string, o en este caso en una variable tipo "char"
    char sensorValueStr[1000]; 
    sprintf(sensorValueStr, "%d", sensorValue);
    // Send the sensor value as the response
    request->send(200, "text/plain", sensorValueStr);
    //delay (1000);
    };
  });


  // Send a GET request to <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
  server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage1;
    String inputMessage2;
    String inputMessage3;
    String inputMessage4;

    // GET input1 value on <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
    if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_2)) {
      inputMessage1 = request->getParam(PARAM_INPUT_1)->value();
      inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
      digitalWrite(inputMessage1.toInt(), inputMessage2.toInt());
    }

    else if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_3)) {
      inputMessage1 = request->getParam(PARAM_INPUT_1)->value();
      inputMessage3 = request->getParam(PARAM_INPUT_3)->value();
      digitalWrite(inputMessage1.toInt(), inputMessage3.toInt());
    }

    else if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_4)) {
      inputMessage1 = request->getParam(PARAM_INPUT_1)->value();
      inputMessage3 = request->getParam(PARAM_INPUT_4)->value();
      digitalWrite(inputMessage1.toInt(), inputMessage4.toInt());
    }    

    else {
      inputMessage1 = "No message sent";
      inputMessage2 = "No message sent";
    }
    Serial.print("GPIO: ");
    Serial.print(inputMessage1);
    Serial.print(" - Set to: ");
    Serial.print(inputMessage2);
    Serial.print("ADC value: ");
    Serial.println(inputMessage3);
    //Serial.print("Sensor Measurement ");
    //Serial.println(inputMessage4);
    request->send(200, "text/plain", "OK");
  });

  // Start server
  server.begin();
}
void loop() {
}

Now, this code compiles and is able to be uploaded and even run, but when the time comes to go into the local IP (around 30 or 40 secs) it crashes, and the console gives the next message:

rst:0x1 (POWERON_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:0x3fff0030,len:1184
load:0x40078000,len:13192
load:0x40080400,len:3028
entry 0x400805e4
Connecting to WiFi..
Connecting to WiFi..
Connecting to WiFi..
192.168.1.34

abort() was called at PC 0x40144ef7 on core 1


Backtrace: 0x40083815:0x3ffd2960 0x4008d1bd:0x3ffd2980 0x40092cad:0x3ffd29a0 0x40144ef7:0x3ffd2a20 0x40144f3e:0x3ffd2a40 0x4014513d:0x3ffd2a60 0x401451f4:0x3ffd2a80 0x400d7e8d:0x3ffd2aa0 0x400d8996:0x3ffd2ac0 0x400d2f09:0x3ffd2ae0 0x400d2fa3:0x3ffd2f10 0x400dbcdf:0x3ffd2f30 0x400dbd1a:0x3ffd2f60 0x400d948d:0x3ffd2fb0 0x400d954b:0x3ffd3000 0x400d9801:0x3ffd3060 0x40162c0b:0x3ffd3080 0x40162c5a:0x3ffd30b0 0x40162c9d:0x3ffd30d0 0x40162de6:0x3ffd30f0 0x40162e63:0x3ffd3110

  #0  0x40083815:0x3ffd2960 in panic_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/panic.c:408
  #1  0x4008d1bd:0x3ffd2980 in esp_system_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/esp_system.c:137
  #2  0x40092cad:0x3ffd29a0 in abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/abort.c:46
  #3  0x40144ef7:0x3ffd2a20 in __cxxabiv1::__terminate(void (*)()) at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:47
  #4  0x40144f3e:0x3ffd2a40 in std::terminate() at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:57
  #5  0x4014513d:0x3ffd2a60 in __cxa_allocate_exception at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/gcc/libstdc++-v3/libsupc++/eh_alloc.cc:300
  #6  0x401451f4:0x3ffd2a80 in operator new(unsigned int) at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/gcc/libstdc++-v3/libsupc++/new_op.cc:54
  #7  0x400d7e8d:0x3ffd2aa0 in AsyncWebServerRequest::beginResponse(int, String const&, String const&) at .pio/libdeps/fm-devkit/ESPAsyncWebServer-esphome/src/WebRequest.cpp:730
  #8  0x400d8996:0x3ffd2ac0 in AsyncWebServerRequest::send(int, String const&, String const&) at .pio/libdeps/fm-devkit/ESPAsyncWebServer-esphome/src/WebRequest.cpp:772
  #9  0x400d2f09:0x3ffd2ae0 in setup()::{lambda(AsyncWebServerRequest*)#2}::operator()(AsyncWebServerRequest*) const at src/main.cpp:179 (discriminator 
3)
  #10 0x400d2fa3:0x3ffd2f10 in std::_Function_handler<void (AsyncWebServerRequest*), setup()::{lambda(AsyncWebServerRequest*)#2}>::_M_invoke(std::_Any_data const&, AsyncWebServerRequest*&&) at c:\users\thinkpad t470\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\bits/std_function.h:297
  #11 0x400dbcdf:0x3ffd2f30 in std::function<void (AsyncWebServerRequest*)>::operator()(AsyncWebServerRequest*) const at c:\users\thinkpad t470\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\bits/std_function.h:687
  #12 0x400dbd1a:0x3ffd2f60 in AsyncCallbackWebHandler::handleRequest(AsyncWebServerRequest*) at .pio/libdeps/fm-devkit/ESPAsyncWebServer-esphome/src/WebHandlerImpl.h:132
  #13 0x400d948d:0x3ffd2fb0 in AsyncWebServerRequest::_parseLine() at .pio/libdeps/fm-devkit/ESPAsyncWebServer-esphome/src/WebRequest.cpp:581 (discriminator 1)
  #14 0x400d954b:0x3ffd3000 in AsyncWebServerRequest::_onData(void*, unsigned int) at .pio/libdeps/fm-devkit/ESPAsyncWebServer-esphome/src/WebRequest.cpp:123
  #15 0x400d9801:0x3ffd3060 in std::_Function_handler<void (void*, AsyncClient*, void*, unsigned int), AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer*, AsyncClient*)::{lambda(void*, AsyncClient*, void*, unsigned int)#8}>::_M_invoke(std::_Any_data const&, void*&&, AsyncClient*&&, std::_Any_data const&, unsigned int&&) at .pio/libdeps/fm-devkit/ESPAsyncWebServer-esphome/src/WebRequest.cpp:76
      (inlined by) _M_invoke at c:\users\thinkpad t470\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\bits/std_function.h:297
  #16 0x40162c0b:0x3ffd3080 in std::function<void (void*, AsyncClient*, void*, unsigned int)>::operator()(void*, AsyncClient*, void*, unsigned int) const at c:\users\thinkpad t470\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\bits/std_function.h:687
  #17 0x40162c5a:0x3ffd30b0 in AsyncClient::_recv(tcp_pcb*, pbuf*, signed char) at .pio/libdeps/fm-devkit/AsyncTCP-esphome/src/AsyncTCP.cpp:961
  #18 0x40162c9d:0x3ffd30d0 in AsyncClient::_s_recv(void*, tcp_pcb*, pbuf*, signed char) at .pio/libdeps/fm-devkit/AsyncTCP-esphome/src/AsyncTCP.cpp:1253
  #19 0x40162de6:0x3ffd30f0 in _handle_async_event(lwip_event_packet_t*) at .pio/libdeps/fm-devkit/AsyncTCP-esphome/src/AsyncTCP.cpp:164
  #20 0x40162e63:0x3ffd3110 in _async_service_task(void*) at .pio/libdeps/fm-devkit/AsyncTCP-esphome/src/AsyncTCP.cpp:199




ELF file SHA256: cc613ecae273b465

Rebooting...

I know its a lot to process but i’m out of ideas.
Thank you!

It’s very clear from the exception backtraces that an out-of-memory exception occurs during the request->send(). And… with that code being in a while(true) loop, that’s also not very surprising. You’re exhausting the memory extremely quickly. You should only send one response to the request, not loop forever. The “loop forever” or “get new values continuously” logic can e.g. be implement in the JavaScript on the client side, or, by using the WebSockets technology instead with a thread running on the server side.

And looking at your client side with

setInterval(function() {
      var xhr_sen = new XMLHttpRequest();
      xhr_sen.onreadystatechange = function() {

        if (xhr_sen.readyState === 4 && xhr_sen.status === 200) {
          document.getElementById('sensor').textContent = xhr_sen.responseText;
        }
      };
      xhr_sen.open('GET', '/sensor', true);
      xhr_sen.send();
    }, 3000);

you already seem to have that, so the while(true) loop on the esp32 shouldn’t be necessary at all.

2 Likes

Also this buffer size of 1000 chars is absurd. analogRead can only return 0 to 4095 on an ESP32, that needs 4 characters + 1 null character at maximum. Since you delcared the variable type to be of int however, the compiler will complain since it assumes the int can take any value from -2^31 to 2^31-1 (= -2147483648 to 2147483647), so you’ll need a buffer size to hold that (plus \0), i.e.,

char sensorValueStr[12]; 
1 Like

That was very helpful. Thanks