ESP8266 reading DHT22 interrupt

While trying to setup a web server which tracks the sensor data from a DHT22 temperature and humidity sensor, my NodeMCU ESP8266 keeps getting these panic interrupts:

User exception (panic/abort/assert)
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Panic core_esp8266_main.cpp:137 __yield

>>>stack>>>
*cut for clarity*
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

Decoding the stack gives:

*Decoding stack results* 0x402069ce: **DHT::read(bool)** at C:\Users\Robert\Documents\Arduino\libraries\DHT_sensor_library-1.4.2\**DHT.cpp** line **252** 0x401002c8: **ets_post(uint8, ETSSignal, ETSParam)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **181** 0x40100b50: **malloc(size_t)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\umm_malloc\**umm_malloc.cpp** line **821** 0x40100b88: **realloc(void*, size_t)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\umm_malloc\**umm_malloc.cpp** line **853** 0x40100b50: **malloc(size_t)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\umm_malloc\**umm_malloc.cpp** line **821** 0x40100b88: **realloc(void*, size_t)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\umm_malloc\**umm_malloc.cpp** line **853** 0x40100b88: **realloc(void*, size_t)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\umm_malloc\**umm_malloc.cpp** line **853** 0x402074a1: **String::changeBuffer(unsigned int)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**WString.cpp** line **202** 0x40206b24: **DHT::readHumidity(bool)** at C:\Users\Robert\Documents\Arduino\libraries\DHT_sensor_library-1.4.2\**DHT.cpp** line **150** 0x40207588: **String::copy(char const*, unsigned int)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**WString.cpp** line **225** 0x401001ce: **readDHT22Humidity()** at C:\Users\Robert\Documents\Arduino\nodemcu_kas_v3/**nodemcu_kas_v3.ino** line **19** 0x40201086: **operator()(AsyncWebServerRequest*)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/**WString.h** line **277** 0x4020319a: **AsyncWebServerRequest::addInterestingHeader(String const&)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/**WString.h** line **79** 0x402075c1: **String::String(char const*)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**WString.cpp** line **41** 0x40206452: **AsyncCallbackWebHandler::canHandle(AsyncWebServerRequest*)** at C:\Users\Robert\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/**WebHandlerImpl.h** line **125** 0x402010dc: **std::_Function_handler >::_M_invoke(const std::_Any_data &, AsyncWebServerRequest *&&)** at c:\users\robert\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.4-gcc10.3-1757bed\xtensa-lx106-elf\include\c++\10.3.0\bits/**invoke.h** line **103** 0x4020621c: **AsyncCallbackWebHandler::handleRequest(AsyncWebServerRequest*)** at c:\users\robert\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.4-gcc10.3-1757bed\xtensa-lx106-elf\include\c++\10.3.0\bits/**std_function.h** line **617** 0x4020455d: **AsyncWebServerRequest::_removeNotInterestingHeaders()** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/**WString.h** line **79** 0x402066c0: **AsyncWebServer::_attachHandler(AsyncWebServerRequest*)** at c:\users\robert\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.4-gcc10.3-1757bed\xtensa-lx106-elf\include\c++\10.3.0\bits/**std_function.h** line **680** 0x40204680: **AsyncWebServerRequest::_parseLine()** at C:\Users\Robert\Documents\Arduino\libraries\ESPAsyncWebServer-master\src\**WebRequest.cpp** line **581** 0x40208124: **String::trim()** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/**WString.h** line **277** 0x4020784c: **String::concat(char const*)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**WString.cpp** line **317** 0x4020474a: **AsyncWebServerRequest::_onData(void*, unsigned int)** at C:\Users\Robert\Documents\Arduino\libraries\ESPAsyncWebServer-master\src\**WebRequest.cpp** line **124** 0x401003dd: **millis()** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_wiring.cpp** line **193** 0x4020492c: **std::_Function_handler >::_M_invoke(const std::_Any_data &, void *&&, AsyncClient *&&, void *&&, unsigned int &&)** at C:\Users\Robert\Documents\Arduino\libraries\ESPAsyncWebServer-master\src\**WebRequest.cpp** line **76** 0x40201f7c: **AsyncClient::_recv(std::shared_ptr&, tcp_pcb*, pbuf*, long)** at C:\Users\Robert\Documents\Arduino\libraries\ESPAsyncTCP-master\src/**ESPAsyncTCP.h** line **103** 0x40201fdc: **AsyncClient::_s_recv(void*, tcp_pcb*, pbuf*, long)** at c:\users\robert\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.4-gcc10.3-1757bed\xtensa-lx106-elf\include\c++\10.3.0\bits/**shared_ptr_base.h** line **1324** 0x4021c825: **tcp_input** at core/**tcp_in.c** line **501** 0x40219fad: **ip4_input** at core/ipv4/**ip4.c** line **1467** 0x40100947: **umm_free_core(umm_heap_context_t*, void*)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\umm_malloc\**umm_malloc.cpp** line **549** 0x40212cb1: **ethernet_input_LWIP2** at netif/**ethernet.c** line **188** 0x40212ab0: **esp2glue_ethernet_input** at glue-lwip/**lwip-git.c** line **116** 0x4023ae1d: **ethernet_input** at glue-esp/**lwip-esp.c** line **365** 0x4023ae2f: **ethernet_input** at glue-esp/**lwip-esp.c** line **373** 0x40100b00: **umm_init()** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\umm_malloc\**umm_malloc.cpp** line **476** 0x401000ac: **app_entry_redefinable()** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **325** 0x40212b08: **esp2glue_netif_set_up1down0** at glue-lwip/**lwip-git.c** line **493** 0x40212c00: **esp2glue_netif_update** at glue-lwip/**lwip-git.c** line **418** 0x4023ad14: **netif_set_addr** at glue-esp/**lwip-esp.c** line **588** 0x401002c8: **ets_post(uint8, ETSSignal, ETSParam)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **181** 0x401002c8: **ets_post(uint8, ETSSignal, ETSParam)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **181** 0x401002c8: **ets_post(uint8, ETSSignal, ETSParam)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **181** 0x401002c8: **ets_post(uint8, ETSSignal, ETSParam)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **181** 0x401002c8: **ets_post(uint8, ETSSignal, ETSParam)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **181** 0x401002c8: **ets_post(uint8, ETSSignal, ETSParam)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **181** 0x401002c8: **ets_post(uint8, ETSSignal, ETSParam)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **181** 0x40212de1: **memp_free** at core/**memp.c** line **383** 0x402065e1: **AsyncWebServer::addHandler(AsyncWebHandler*)** at C:\Users\Robert\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/**StringArray.h** line **32** 0x402138ec: **tcp_free** at core/**tcp.c** line **216** 0x40213b06: **tcp_listen_with_backlog_and_err** at core/**tcp.c** line **915** 0x40213b37: **tcp_listen_with_backlog** at core/**tcp.c** line **828** 0x40201a1d: **AsyncServer::begin()** at C:\Users\Robert\Documents\Arduino\libraries\ESPAsyncTCP-master\src\**ESPAsyncTCP.cpp** line **1131** 0x4020710c: **Print::println()** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/**Print.h** line **57** 0x4020661d: **AsyncWebServer::begin()** at C:\Users\Robert\Documents\Arduino\libraries\ESPAsyncWebServer-master\src\**WebServer.cpp** line **84** 0x401002c8: **ets_post(uint8, ETSSignal, ETSParam)** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **181** 0x401002e9: **esp_schedule()** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **128** 0x4020845e: **loop_wrapper()** at C:\Users\Robert\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266\**core_esp8266_main.cpp** line **205**

The piece of code where it seems to go wrong is in the request for the sensor data:

String readDHT22Humidity() {
  float h = dht.readHumidity();
  //float h = 20.0;
  if (isnan(h)) {
    Serial.println("Failed to read from DHT22 sensor!");
    return "";
  }
  else {
    Serial.println(h);
    return String(h);
  }
}

Using float h = 20 makes the code run fine, but dht.readHumidity() results in the exception. I have looked at the references and it seems that the memory allocation is off. Adding ICACHE_RAM_ATTR to the String function doesn't help (neither does IRAM_ATTR) .

Can anyone help me out with this?

Not very likely, it's only a clue. Post all your code.

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <FS.h>
#include <DHT.h>
const int dataPin = D4; 
#define DHTTYPE DHT22
DHT dht(dataPin, DHTTYPE);

const char* ssid = "x";
const char* password = "x";

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

IRAM_ATTR String readDHT22Humidity() {
  float h = dht.readHumidity();
  //float h = 20.0;
  if (isnan(h)) {
    Serial.println("Failed to read from DHT22 sensor!");
    return "";
  }
  else {
    Serial.println(h);
    return String(h);
  }
}

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<!-- Rui Santos - Complete project details at https://RandomNerdTutorials.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. -->
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://code.highcharts.com/highcharts.js"></script>
  <style>
    body {
      min-width: 310px;
      max-width: 800px;
      height: 400px;
      margin: 0 auto;
    }
    h2 {
      font-family: Arial;
      font-size: 2.5rem;
      text-align: center;
    }
  </style>
</head>
<body>
  <h2>ESP Weather Station</h2>
  <div id="chart-temperature" class="container"></div>
  <div id="chart-humidity" class="container"></div>
</body>
<script>
var chartT = new Highcharts.Chart({
  chart:{ renderTo : 'chart-temperature' },
  title: { text: '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();
}, 2000 ) ;

var chartH = new Highcharts.Chart({
  chart:{ renderTo:'chart-humidity' },
  title: { text: 'BME280 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();
}, 2000 ) ;
</script>
</html>)rawliteral";

void setup(){
  dht.begin(); 
  delay(5000);
  // Serial port for debugging purposes
  Serial.begin(115200);
  Serial.println(readDHT22Humidity());

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

  // Print ESP32 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);
  });
  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHT22Humidity().c_str());
  });
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHT22Humidity().c_str());
  });
  // Start server
  server.begin();
}
 
void loop(){
  
}