### Hardware:
Board: ESP32 Dev Module node32
IDE name: Platform.io …on Visual Studio Code
Computer OS: Ubuntu?
### Description:
Decoding Guru Meditation does not provide a place of the issue.
> Exception Cause: Not found
>
> 0x400d1d90: loop() at /home/peter/Documents/PlatformIO/Projects/monitorv1/src/main.cpp:150 (discriminator 10)
> 0x40084774: _xt_coproc_exc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/xtensa_vectors.S:1091
> 0x40086a21: spi_flash_restore_cache at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/spi_flash/cache_utils.c:283
> 0x400d1d90: loop() at /home/peter/Documents/PlatformIO/Projects/monitorv1/src/main.cpp:150 (discriminator 10)
> 0x400d1d90: loop() at /home/peter/Documents/PlatformIO/Projects/monitorv1/src/main.cpp:150 (discriminator 10)
> 0x40084771: _xt_coproc_exc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/xtensa_vectors.S:1090
> 0x40086a1e: spi_flash_phys2cache at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/spi_flash/flash_mmap.c:466
> 0x40082b8b: esp_reset_reason_get_hint at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/reset_reason.c:117
> 0x40088b7d: vQueueDelete at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c:1796 (discriminator 1)
>
The system reads sensor data over simple 433Mhz ASK routine ( [RFReceiver](https://github.com/zeitgeist87/RFReceiver) or [RadioHead](https://github.com/PaulStoffregen/RadioHead) ) and updates a web page on ESPAsyncWebServer. There is also a routine to read the time from NTP server.
If I don't initialize 433Mhz radio objects, failure of the WiFi does not influence the system. If WiFi will be available again the system recovers the WiFI connection and works as design.
With an active radio object and failure of the WiFi after few seconds system reboots with guru meditation:
> Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed)
> Core 1 register dump:
> PC : 0x400d1d90 PS : 0x00060034 A0 : 0x40084774 A1 : 0x3ffbe7b0
> A2 : 0x00000004 A3 : 0x3ffc192c A4 : 0x00000000 A5 : 0x00000010
> A6 : 0x00000000 A7 : 0x1300005c A8 : 0x80080f80 A9 : 0x00000001
> A10 : 0x00000000 A11 : 0x00000000 A12 : 0x3ffc1c7c A13 : 0x00000000
> A14 : 0x3ffc1c78 A15 : 0xffffffff SAR : 0x00000018 EXCCAUSE: 0x00000007
> EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
> Core 1 was running in ISR context:
> EPC1 : 0x40086a21 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x400d1d90
>
> Backtrace: 0x400d1d90:0x3ffbe7b0 0x40084771:0x3ffbe7d0 0x40086a1e:0x3ffba1f0 0x40082b8b:0x3ffba210 0x40088b7d:0x3ffba230
The reboots happen also even if the transmitter is switched off and actually there is no reason to call any radio method.
I read [here1](https://www.esp32.com/viewtopic.php?t=7684) and [here2](https://github.com/espressif/arduino-esp32/issues/855) that a part of the code within interrupt routine must always be in the ESP32's IRAM - is that correct?
I tried to add IRAM_ATTR to few function handling radio parts without any success.
### Question1:
Can i somehow disable (taking into consideration a slowdown of the performance) the caching? Is there something similar in Arduino / Platformio config to disable SPI_MASTER_ISR_IN_IRAM in ESP32 config settings?
### Question2:
Or how can I identify a function, which requires to stay in IRAM (if it is the solution of my problem)?
### Sketch:
```cpp
#include <Arduino.h>
#include "main.h"
#include "index.h"
#include "credentials.h"
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <TimeLib.h>
#include <Timezone.h>
#include "WiFi.h"
#include <ESPmDNS.h>
#include "ESPAsyncWebServer.h"
#include <PinChangeInterruptHandler.h>
#include <RFReceiver.h>
void updateJson();
void blink();
void printData(Tdata&);
void printDateTime(Timezone, time_t, const char *);
// Central European Time (Frankfurt, Paris)
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 0); /// get UTC
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; // Central European Standard Time
Timezone CE(CEST, CET);
TimeChangeRule *tcr;
time_t syncNTP();
getExternalTime NtpTime = &syncNTP;
AsyncWebServer server(80);
AsyncEventSource events("/events");
Tdata sensorsData[sensorNumber];
char jsonData[370];
RFReceiver receiver(4);
void setup()
{
for (int i=0; i<sensorNumber; i++) {
sensorsData[0].timeStamp = 0;
sensorsData[0].temperature = 0.0;
sensorsData[0].humidity = 0.0;
sensorsData[0].pressure = 0.0;
sensorsData[0].battery = 0.0;
}
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
delay(1000);
WiFi.begin(ssid, password);
Serial.setDebugOutput(true);
PRINTS("Connecting to WiFi ");
while (WiFi.status() != WL_CONNECTED) {
PRINTS(".");
blink();
}
PRINTS(" connected\n");
PRINTS(WiFi.localIP());
if (!MDNS.begin(localDomain)) {
PRINTS("Error setting up MDNS responder! Program Stoped\n");
while(1) {
blink();
}
}
PRINTS("mDNS responder started\n");
timeClient.begin();
if (!timeClient.update()) {
PRINTS("1st NTP Update Failed. Program Stoped\n");
while(1) {
blink();
}
};
setSyncInterval(_setSyncInterval);
setSyncProvider(NtpTime);
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/html", index_html);
});
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(404);
});
events.onConnect([](AsyncEventSourceClient *client){
syncNTP();
updateJson();
client->send(jsonData,"data",millis());
});
server.addHandler(&events);
server.begin();
MDNS.addService("http", "tcp", 80);
receiver.begin();
PRINT("Max Buf: ", MAX_PACKAGE_SIZE);
}
time_t last_utc=0;
void loop()
{
uint8_t buf[MAX_PACKAGE_SIZE];
uint8_t buflen = sizeof(buf);
uint8_t sensorID;
byte senderId = 0;
byte packageId = 0;
//PP2
if (receiver.ready())
{ // (driver.recv(buf, &buflen)) // Non-blocking
buflen = receiver.recvPackage(buf, &senderId, &packageId);
// Message with a good checksum received, dump it.
#if DEBUG_ON
//driver.printBuffer("Got:", buf, buflen);
PRINT("Buf Len:", buflen); PRINTLN;
PRINT("Size of TData:", sizeof(Tdata)); PRINTLN;
#endif
if (buflen==dataSize) {
//data = *(Tdata *) buf;
sensorID=(*reinterpret_cast<Tdata *> (buf)).sensorID;
memcpy(&sensorsData[sensorID],&buf, sizeof(Tdata));
PRINT("Sensor ID: ", sensorID); PRINTLN;
sensorsData[sensorID].timeStamp = now();
updateJson();
events.send(jsonData,"data",millis());
printData(sensorsData[sensorID]);
}
}
if (now()-last_utc >= 1) {
last_utc = now();
updateJson();
events.send(jsonData,"data",millis());
//printDateTime(CE, last_utc,(timeStatus()==timeSet)? " OK":(timeStatus()==timeNeedsSync)? " Need Sync":" Not Set");
}
}
void updateJson() {
time_t t = CE.toLocal(now(), &tcr);
time_t t0 = CE.toLocal(sensorsData[0].timeStamp, &tcr);
time_t t1 = CE.toLocal(sensorsData[1].timeStamp, &tcr);
time_t t2 = CE.toLocal(sensorsData[2].timeStamp, &tcr);
sprintf(jsonData,jsonStruc,
(timeStatus()==timeSet)? "white":(timeStatus()==timeNeedsSync)? "red":"yellow",
hour(t), minute(t), second(t), day(t), month(t), year(t),
hour(t0), minute(t0), second(t0), day(t0), month(t0), year(t0)%100U,
sensorsData[0].temperature,
sensorsData[0].humidity,
sensorsData[0].pressure,
sensorsData[0].battery,
hour(t1), minute(t1), second(t1), day(t1), month(t1), year(t1)%100U,
sensorsData[1].temperature,
sensorsData[1].humidity,
sensorsData[1].pressure,
sensorsData[1].battery,
hour(t2), minute(t2), second(t2), day(t2), month(t2), year(t2)%100U,
sensorsData[2].temperature,
sensorsData[2].humidity,
(float)sensorsData[0].counter);
}
time_t syncNTP() {
bool NTPSyncOK=true;
PRINTS("\nNTP Syncing ... ");
// WiFi.printDiag(Serial);
if (WiFi.isConnected()) {
NTPSyncOK = timeClient.forceUpdate();
} else {
PRINTS("\nRecovering WiFi connection\n");
//WiFi.mode(WIFI_STA);
WiFi.begin();
if (WiFi.isConnected()) {
NTPSyncOK = timeClient.forceUpdate();
//WiFi.mode(WIFI_OFF);
} else {
PRINTS("\nWIFI failed ...\n");
NTPSyncOK = false;
}
}
if (NTPSyncOK) {
PRINTS("NTP Sync OK\n");
return timeClient.getEpochTime();
}
else {
PRINTS("NTP Sync Failed\n");
return 0;
}
}
void blink() {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}
// --------------------------------
void printData(Tdata& data)
{
PRINT ("Sensor = ", data.sensorID); PRINTLN;
PRINT ("Temperature = ", data.temperature); PRINTS(" *C\n");
PRINT ("Pressure = ", data.pressure); PRINTS(" hPa\n");
PRINT ("Humidity = ", data.humidity); PRINTS(" %\n");
PRINT ("Battery = ", data.battery); PRINTS(" V\n");
PRINTS("Time = "); printDateTime(CE, data.timeStamp,(timeStatus()==timeSet)? " OK":(timeStatus()==timeNeedsSync)? " Need Sync":" Not Set");
PRINT ("Counter = ", data.counter); PRINTLN;
}
void printDateTime(Timezone tz, time_t utc, const char *descr)
{
char buf[40];
char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer)
TimeChangeRule *tcr; // pointer to the time change rule, use to get the TZ abbrev
time_t t = tz.toLocal(utc, &tcr);
strcpy(m, monthShortStr(month(t)));
sprintf(buf, "%.2d:%.2d:%.2d %s %.2d %s %d %s",
hour(t), minute(t), second(t), dayShortStr(weekday(t)), day(t), m, year(t), tcr -> abbrev);
PRINTS(buf); PRINTS(descr); PRINTLN;
}
```
### Sketch main.h:
```cpp
#include <Arduino.h>
#define DEBUG_ON 1
#define localDomain "pogoda"
#define _setSyncInterval 15
typedef struct
{
float temperature;
float humidity;
float pressure;
float battery;
long counter;
uint8_t sensorID;
long dummy;
time_t timeStamp;
} Tdata;
const char jsonStruc[] PROGMEM = R"rawliteral(
{"XC1":"%s",
"clock":"%02d:%02d:%02d %02d:%02d:%02d",
"time0":"%02d:%02d:%02d %02d:%02d:%02d",
"temp0":"%.2f",
"hum0" :"%.0f",
"pres0":"%.0f",
"bat0" :"%.2f",
"time1":"%02d:%02d:%02d %02d:%02d:%02d",
"temp1":"%.2f",
"hum1" :"%.0f",
"pres1":"%.0f",
"bat1" :"%.2f",
"time2":"%02d:%02d:%02d %02d:%02d:%02d",
"temp2":"%.2f",
"hum2" :"%.0f",
"pres2":"%.0f"}
)rawliteral";
const uint8_t sensorNumber = 3;
const uint8_t dataSize = 21; // data frame size
#if DEBUG_ON
#define PRINT(s, v) { Serial.print(s); Serial.print(v); }
#define PRINTX(s, v) { Serial.print(s); Serial.print(v, HEX); }
#define PRINTS(s) Serial.print(s)
#define PRINTLN Serial.println()
#else
#define PRINT(s, v)
#define PRINTX(s, v)
#define PRINTS(s)
#define PRINTLN
#endif
```
### Sketch index.h:
```cpp
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang=pl>
<head>
....
</body>
</html>
)rawliteral";
```