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(){
  
}

This is crashing because you can't call yield or delay in an asynchronous callback, and the DHT library from Adafruit is doing that. You need to periodically update the DHT data in your main loop and reference the results in the async callback.

Of note, you also can't update it in a Timer/interrupt, or anything outside of loop() for the same reason. Its a very poorly written library.

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