ESP8266 Client connection causing restart?

Hi there,

Newbie but not completely… have been playing around with electronic projects for a year or two now, some were simple enough and were done and dusted. Now I have tried to up my game a bit and run into more than a few problems. Have managed to over come most leading me to now asking you guys who have helped no end already… thanks in advance.

So, I have managed to piece together and worked out kinks from other examples of code that I have come across. The aim is to have the ESP8266 reading multiple sensors and then posting them to its own page. I have got that far (barring adding in the extra sensors) but I am now encountering random crashes. I thought initially it was due to client page already being connected, managed to seemingly rule that out while typing this.

Initially it looked like it was crashing when initialising a server… then it seemed to be when the client connected, leading me to (don’t slap me) adding a few delays, which seemed to clear up the problem. However, after it running for 3-5 minutes I can get a reset, sometimes it’s shorter sometimes longer.

Problems that seem to be the case (so correct me if im wrong):

  • If client (my computer) is looking at the ESP’s IP address, with the page open I get, wifi connecting, connected, dump and reset which repeats until i close down the webpage.

-After random amounts of time the device will restart, and might continue its program but invariably gets stuck.

Below is the code (with embedded HTML). I know its probably messy and looks like a hack job, any pointers or notes would be appreciated.

//Includes
#include <ESP8266WiFi.h>
#include "ESPAsyncWebServer.h"
#include <Adafruit_Sensor.h>
#include <DHT.h>

//Definitions
const char* ssid = "******";
const char* password = "******";

#define DHTPIN 5     // Digital pin connected to the DHT sensor


#define DHTTYPE    DHT11     // DHT 11


DHT dht(DHTPIN, DHTTYPE);


AsyncWebServer server(80);

String readDHTTemperature() {
  
  float t = dht.readTemperature();
    if (isnan(t)) {    
    Serial.println("Failed to read from DHT sensor!");
    return "--";
  }
  else {
    Serial.println(t);
    return String(t);
  }
}

String readDHTHumidity() {
  float h = dht.readHumidity();
  if (isnan(h)) {
    Serial.println("Failed to read from DHT sensor!");
    return "--";
  }
  else {
    Serial.println(h);
    return String(h);
  }
}

const char index_html[] PROGMEM = R"rawliteral(





String processor(const String& var){
  //Serial.println(var);
  if(var == "TEMPERATURE"){
    return readDHTTemperature();
  }
  else if(var == "HUMIDITY"){
    return readDHTHumidity();
  }
  return String();
}

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

    dht.begin();
  
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  
  Serial.println(WiFi.localIP());

  delay(1000);

  
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });
  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHTTemperature().c_str());
  });
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHTHumidity().c_str());
  });

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

  delay(2000);
  Serial.println(dht.readTemperature());
  Serial.println(dht.readHumidity());
  
}
<!DOCTYPE HTML>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://code.highcharts.com/highcharts.js"></script>
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .dht-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 15px;
    }
  </style>
</head>
<body>
  <h2>ESP32 DHT Server</h2>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="dht-labels">Temperature</span> 
    <span id="temperature">%TEMPERATURE%</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <i class="fas fa-tint" style="color:#00add6;"></i> 
    <span class="dht-labels">Humidity</span>
    <span id="humidity">%HUMIDITY%</span>
    <sup class="units">%</sup>
  </p>
  <h2>ESP Weather Station</h2>
  <div id="chart-temperature" class="container"></div>
  <div id="chart-humidity" class="container"></div>
</body>
<script>
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperature").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperature", true);
  xhttp.send();
}, 10000 ) ;

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("humidity").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/humidity", true);
  xhttp.send();
}, 10000 ) ;
</script>

<script>
var chartT = new Highcharts.Chart({
  chart:{ renderTo : 'chart-temperature' },
  title: { text: 'DHT Temperature' },
  series: [{
    showInLegend: false,
    data: []
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    },
    series: { color: '#059e8a' }
  },
  xAxis: { type: 'datetime',
    dateTimeLabelFormats: { second: '%H:%M:%S' }
  },
  yAxis: {
    title: { text: 'Temperature (Celsius)' }
    //title: { text: 'Temperature (Fahrenheit)' }
  },
  credits: { enabled: false }
});
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var x = (new Date()).getTime(),
          y = parseFloat(this.responseText);
      //console.log(this.responseText);
      if(chartT.series[0].data.length > 40) {
        chartT.series[0].addPoint([x, y], true, true, true);
      } else {
        chartT.series[0].addPoint([x, y], true, false, true);
      }
    }
  };
  xhttp.open("GET", "/temperature", true);
  xhttp.send();
}, 30000 ) ;

var chartH = new Highcharts.Chart({
  chart:{ renderTo:'chart-humidity' },
  title: { text: 'DHT Humidity' },
  series: [{
    showInLegend: false,
    data: []
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    }
  },
  xAxis: {
    type: 'datetime',
    dateTimeLabelFormats: { second: '%H:%M:%S' }
  },
  yAxis: {
    title: { text: 'Humidity (%)' }
  },
  credits: { enabled: false }
});
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var x = (new Date()).getTime(),
          y = parseFloat(this.responseText);
      //console.log(this.responseText);
      if(chartH.series[0].data.length > 40) {
        chartH.series[0].addPoint([x, y], true, true, true);
      } else {
        chartH.series[0].addPoint([x, y], true, false, true);
      }
    }
  };
  xhttp.open("GET", "/humidity", true);
  xhttp.send();
}, 30000 ) ;

</script>

</html>)rawliteral";

I edited the code box and removed the html and stored it seperately.

I assume my most recent stack might be useful, so have attached it here. (at time of posting this the device has been up for 23minutes without reset.

Decoding stack results
0x40100300: millis() at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\core_esp8266_wiring.cpp line 188
0x4020825d: __yield() at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\core_esp8266_main.cpp line 135
0x402067b6: DHT::read(bool) at C:\Users\jrand\Documents\Arduino\libraries\DHT_sensor_library\DHT.cpp line 252
0x40100aa4: malloc(size_t) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x40100aa4: malloc(size_t) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x40100aa4: malloc(size_t) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x40100aed: realloc(void*, size_t) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 586
0x402073d6: String::changeBuffer(unsigned int) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\WString.cpp line 187
0x40100aed: realloc(void*, size_t) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 586
0x402073d6: String::changeBuffer(unsigned int) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\WString.cpp line 187
0x402073d6: String::changeBuffer(unsigned int) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\WString.cpp line 187
0x401007eb: umm_free_core(void*) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 351
0x40206944: DHT::readTemperature(bool, bool) at C:\Users\jrand\Documents\Arduino\libraries\DHT_sensor_library\DHT.cpp line 86
0x40207684: String::operator=(String const&) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\WString.cpp line 262
0x40201148: readDHTTemperature() at C:\Users\jrand\Documents\Arduino\DHTPage/DHTPage.ino line 25
0x402011bd: std::_Function_handler ::_M_invoke(const std::_Any_data &, AsyncWebServerRequest *) at C:\Users\jrand\Documents\Arduino\DHTPage/DHTPage.ino line 235
0x40207329: String::invalidate() at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\WString.cpp line 140
0x40203ab0: AsyncWebServerRequest::_removeNotInterestingHeaders() (C:\Program Files at x86)\Arduino\libraries\ESPAsyncWebServer\src\WebRequest.cpp line 182
0x4020104c: std::_Function_base::_Base_manager ::_M_manager(std::_Any_data &, const std::_Any_data &, std::_Manager_operation) at c:\users\jrand\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-4-b40a506\xtensa-lx106-elf\include\c++\4.8.2/functional line 1931
0x4020552d: AsyncCallbackWebHandler::handleRequest(AsyncWebServerRequest*) at c:\users\jrand\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-4-b40a506\xtensa-lx106-elf\include\c++\4.8.2/functional line 2464
0x4020596c: AsyncWebServer::_attachHandler(AsyncWebServerRequest*) (C:\Program Files at x86)\Arduino\libraries\ESPAsyncWebServer\src\WebServer.cpp line 116
0x40203bd5: AsyncWebServerRequest::_parseLine() (C:\Program Files at x86)\Arduino\libraries\ESPAsyncWebServer\src\WebRequest.cpp line 581
0x40208048: String::trim() at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\WString.cpp line 828
0x40203e20: AsyncWebServerRequest::_onData(void*, unsigned int) (C:\Program Files at x86)\Arduino\libraries\ESPAsyncWebServer\src\WebRequest.cpp line 124
0x40100300: millis() at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\core_esp8266_wiring.cpp line 188
0x4021ad64: mem_free at core/mem.c line 237
0x40203e79: std::_Function_handler ::_M_invoke(const std::_Any_data &, void *, AsyncClient *, void *, unsigned int) at c:\users\jrand\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-4-b40a506\xtensa-lx106-elf\include\c++\4.8.2/functional line 2073
0x40206072: AsyncClient::_recv(std::shared_ptr &, tcp_pcb*, pbuf*, long) (C:\Program Files at x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp line 649
0x4020621a: AsyncClient::_s_recv(void*, tcp_pcb*, pbuf*, long) (C:\Program Files at x86)\Arduino\libraries\ESPAsyncTCP\src\ESPAsyncTCP.cpp line 738
0x40214564: tcp_input at core/tcp_in.c line 501
0x40100aa4: malloc(size_t) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x40219fea: ip4_input at core/ipv4/ip4.c line 1467
0x40100a6f: free(void*) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 398
0x4021114d: ethernet_input_LWIP2 at netif/ethernet.c line 188
0x40210f6c: esp2glue_ethernet_input at glue-lwip/lwip-git.c line 469
0x40230f2e: ethernet_input at glue-esp/lwip-esp.c line 365
0x40230f3f: ethernet_input at glue-esp/lwip-esp.c line 373
0x40100208: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\core_esp8266_main.cpp line 177
0x40100208: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\core_esp8266_main.cpp line 177
0x40100aa4: malloc(size_t) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x40100aed: realloc(void*, size_t) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 586
0x40100aa4: malloc(size_t) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x4020939d: uart_write(uart_t*, char const*, size_t) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\uart.cpp line 509
0x402073d6: String::changeBuffer(unsigned int) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\WString.cpp line 187
0x40206cc4: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266/HardwareSerial.h line 165
0x401007eb: umm_free_core(void*) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 351
0x40100a6f: free(void*) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 398
0x4021ad44: mem_malloc at core/mem.c line 210
0x4021ad64: mem_free at core/mem.c line 237
0x40205859: AsyncWebServer::addHandler(AsyncWebHandler*) (C:\Program Files at x86)\Arduino\libraries\ESPAsyncWebServer\src/StringArray.h line 32
0x40211291: memp_free at core/memp.c line 447
0x40211330: tcp_free at core/tcp.c line 217
0x4021152d: tcp_listen_with_backlog_and_err at core/tcp.c line 915
0x4021156f: tcp_listen_with_backlog at core/tcp.c line 829
0x40208208: __esp_yield() at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266/core_esp8266_features.h line 92
0x40208a8e: __delay(unsigned long) at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\core_esp8266_wiring.cpp line 54
0x40201433: loop() at C:\Users\jrand\Documents\Arduino\DHTPage/DHTPage.ino line 248
0x40208330: loop_wrapper() at C:\Users\jrand\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\core_esp8266_main.cpp line 197

You are probably running out of memory with all those Strings. I'd start by making your temperature and humidity functions return const char * rather than String. Same for your processor() function

const char * readDHTTemperature() {
  static char value[10];
  float t = dht.readTemperature();
  if (isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    //return "--";
    strpy(value, "---");
  }
  else {
    Serial.println(t);
    //return String(t);
    dtostrf(t, 7, 2, value);
  }
  return value;
}

const char * readDHTHumidity() {
  static char value[10];
  float h = dht.readHumidity();
  if (isnan(h)) {
    Serial.println("Failed to read from DHT sensor!");
    //return "--";
    strpy(value, "---");
  }
  else {
    Serial.println(h);
    dtostrf(h, 7, 2, value);
    //return String(h);
  }
  return value;
}

global defined variables of type String (the one beginning with BIG "S" ) eat up all memory over time.

There are two alternatives for variable type String

a library .called PString or SafeString

PString gives a bit more comfort than array of char.
or

Safe, Robust, Debuggable String class for Arduino
It can be installed through the library-manager of the Arduino-IDE

best regards Stefan

You are probably running out of memory with all those Strings.

On an ESP, not that quickly, mind you, this is doubling up on the buffer size.

request->send_P(200, "text/plain", readDHTHumidity().c_str());

And then to think you put the page in PROGMEM first.

global defined variables of type String (the one beginning with BIG "S" ) eat up all memory over time.

If they exceed their initial reserved space, yes they can, but i looked twice and can't find any in this sketch.
eh Honestly i think this variable should be called something else

String processor(const String& var){

and you are returning what exactly here ?

return String();

is that the same as

return "";

? Anyway, yes you do use 'String' and nesting may not be needed, but as far as i see all 'String' s get destroyed, and there isn't anything else hogging the heap. Consider using the normal (rather than the Async) webserver, but also i doubt if that is the issue.

Hey, thanks for all your comments and suggestions. I shall give the code a try thanks BLH. I opened the link (Thanks Stefan always appreciate a link to something to read) and have started reading so will go through that over this evening.

Deva, the Strings part of this sketch is all new to me, everything I have done previously hasn't used such complicated code. I shall attempt the standard Webserver idea also (did start with that at one point not sure why i ended up changing - probably found it in a sketch example and thought id try it.

Regarding the name of the string are you referring to "processor" specifically?

Thanks again in advance.

Regarding the name of the string are you referring to "processor" specifically?

No i meant 'var' is not a very descriptive name. Anyway many of the EspWebserver functions return 'Strings' as a type without issue. There may be some other cause to your problem.
I suspect it is here :

String processor(const String& var){
  //Serial.println(var);
  if(var == "TEMPERATURE"){
    return readDHTTemperature();
  }
  else if(var == "HUMIDITY"){
    return readDHTHumidity();
  }
  return String();
}

and when you call this function

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

First of all you are not actually sending html code here. It is just text/plain. With the whole page included in your sketch i assumed you would be sending that but now i can't find it being used at all. If you are saying you send html but only send plain text your browser may get confused and may keep sending rquests. And unlike with the other 2 callback functions you do not convert the returned String to .c_str() It must be either one of the 2 options that is going wrong. (i'm not sure which one, or maybe even both are correct) There are known issues in the ESP-core, and it is possible that the send function here is looking for a terminator that does not exists and then just keeps copying memory. Try both adding the .c_str() in the one function and removing it in all of them. Please clean up your sketch so it shows without the raw webpage or show us where it is used.

Actually thinking about it some more i am confident that the cause is this line

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

I see now that here you call that whole html section, but processor may return an empty String, and it is still a mystery to me what 'var' is being referenced within that function.

Hey thanks for your interest. Im sitting down this evening after a long read last night about strings and other alternatives. Looking across other situations that other people have encountered, I’m leaning towards something more to do with the connected client. I shall give a few things a try and report back…

Thanks again :slight_smile:

Okay so, a bit about the “var”.

From my understanding of how it all works, the var in the processor String refers to the “var” outlined in the html section. in the

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperature").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperature", true);
  xhttp.send();
}, 10000 ) ;

While writing this it occured to me that I have “var” defined in two seperate scripts on the webpage section of it? is that likely to cause issue?

Im going to disable one of the scripts and give that a go first, im just thinking if they both call for data and delays simulateneously it could cause a bit of an lag maybe?

UPDATE: Rolling with the idea of its “whats connected or being requested by the connection/whats being sent”. I played with the server on function that you suggested Deva. I tried labelling processor as a c_str and IDE wasnt happy, then saw your other point regarding “text/html” vs “text/plain” so changed to the plain version. I was about to say that it hasnt crashed yet (with client connected but as I typed it, its done it again, however it rolls straight back into program whether page is connected or not, where it used to get stuck for a while resetting.

Edit: I didnt refresh the page on the browser, so although it was the old source code still requesting the data. Text/plain just sends a readable html document.

  • I am wondering if i need some sort of client handling or something? like a connection flush every so often?

Edit: Doing some investigation I have added

Serial.println(ESP.getFreeHeap(), DEC);

and the result returned on startup is 49720>49216>48328>48992… then seems to hold.
When i open the browser window 48136>48800>48992>49208 and doesnt change from there while posting data to the page. Page holds 40 points of data on two seperate charts.

One thing I did notice in the serial monitor:

21.80
72.00
48992
21.80
72.00         <<Between this humidity reading and this
21.80         <<Temperature reading should be a freeheap value, and this occurs when it posts 
72.00              data to the page.
48992
21.80
72.00
48992

Thanks in advance.

From my understanding of how it all works, the var in the processor String refers to the "var" outlined in the html section.

And what makes you think that the html section can be referenced by the function ? This is not supported on the ESP, no Java Script. What is in the html section is considered to be a "const char array " by the compiler and the processor. Maybe your browser can add data in between that (don't know how to though) but the compiler can not re-direct data from inside of it to some other function. This is not the way i make a dynamic webpage, and i doubt if it is a way that should be encouraged. How about for now just remove the reference to 'processor' from the callback function

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

and leave the rest the way it is. (it is html what you're sending anyway)
If you do want to create a dynamic webpage, the easiest method is to create a 'String' fill it with html parts and dynamic values as you go along and then send the whole thing in one go.

Hey there,

Thanks again for the interest.

Over night testing revealed that the device runs flawlessly when not connected to the page.

Right… The reason I “think” the HTML can be referenced by the function.

“var” is outlined in the HTML as to what it is as in either /temperature or /humidity as shown below.

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var x = (new Date()).getTime(),
          y = parseFloat(this.responseText);
      //console.log(this.responseText);
      if(chartH.series[0].data.length > 40) {
        chartH.series[0].addPoint([x, y], true, true, true);
      } else {
        chartH.series[0].addPoint([x, y], true, false, true);
      }
    }
  };
  xhttp.open("GET", "/humidity", true);
  xhttp.send();

In this it “creates the variable” on the page on page generation. It matters not to the ESP as it is only sending when it receives a request. So var “contains nothing” until a request is made for it. So within the code, it is looking for /temperature or /humidity and it will return the corresponding information.

Thanks Deva I shall give that a go removing the “processor”.

Thanks again in advance