Guru Meditation Error... while accessing the address 0x42d00020 (invalid mmu entry)

Hi,
I’ve finally managed to make my system work with an ESP32 WROOM and 2 Heltec LoRa 32 (v3). Briefly, I have a weather station with the ESP32 WROOM sending data via ESP-NOW to a repeater based on the Heltec LoRa 32 (v3), which retransmits the data via LoRa, and it is then received at home with another Heltec LoRa 32 (v3). Everything works, except that I ran the code for the receiver, I receive the data correctly, but is quickly followed by a “Guru Meditation Error” followed instantly by a reboot. Ultimately, I don’t care if it reboots every minute (except that it’s an ugly solution), but the problem is that it clobbers the output which I try to send to a spreadsheet or database.
The complete error that I get is the following:

Guru Meditation Error: Core / panic’ed (Cache disabled but cached memory region accessed).
MMU entry fault error occurred while accessing the address 0x42b80020 (invalid mmu entry)

Core 0 register dump:
PC : 0x40379e76 PS : 0x00060334 A0 : 0x82013688 A1 : 0x3fca0290
A2 : 0x00000000 A3 : 0x00000000 A4 : 0x00060020 A5 : 0x3fc9fb70
A6 : 0x00000001 A7 : 0x00000160 A8 : 0x8201289e A9 : 0x3fca0250
A10 : 0x00000000 A11 : 0x00000000 A12 : 0x3fc955b0 A13 : 0x00000000
A14 : 0x00060020 A15 : 0x3fca026f SAR : 0x00000019 EXCCAUSE: 0x00000007
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000

Backtrace: 0x40379e73:0x3fca0290 0x42013685:0x3fca02b0 0x4037e1a3:0x3fca02d0 0x4037d39a:0x3fca02f0

Core 1 register dump:
PC : 0x4203396f PS : 0x00060e34 A0 : 0x8200288a A1 : 0x3fca30a0
A2 : 0x3fc97fa4 A3 : 0x000003e8 A4 : 0x8037dba3 A5 : 0x3fc96bb0
A6 : 0x00000000 A7 : 0x3fc97f80 A8 : 0x42b80000 A9 : 0x3fca3080
A10 : 0x3fc97fa4 A11 : 0x00000005 A12 : 0x00000000 A13 : 0x00000000
A14 : 0x3fc94e20 A15 : 0xffffffff SAR : 0x0000000a EXCCAUSE: 0x00000007
EXCVADDR: 0x00000000 LBEG : 0x400556d5 LEND : 0x400556e5 LCOUNT : 0xffffffff

Backtrace: 0x4203396c:0x3fca30a0 0x42002887:0x3fca30c0 0x42002ddd:0x3fca30e0 0x4200e978:0x3fca3120 0x4037d39a:0x3fca3140

ELF file SHA256: e2f591cf0

Rebooting…

Could one of you tell me what this is all about and what can be done to fix it?
Here is the code that receives the data. Don’t judge my code style, I’m not a software engineer, far from it :smile:

 /**
  • Send and receive LoRa-modulation packets with a sequence number, showing RSSI
  • and SNR for received packets on the little display.
  • Note that while this send and received using LoRa modulation, it does not do
  • LoRaWAN. For that, see the LoRaWAN_TTN example.
  • This works on the stick, but the output on the screen gets cut off.
    */

// Turns the ‘PRG’ button into the power button, long press is off
#define HELTEC_POWER_BUTTON // must be before “#include <heltec_unofficial.h>”
#include <heltec_unofficial.h>

// Pause between transmited packets in seconds.
// Set to zero to only transmit a packet when pressing the user button
// Will not exceed 1% duty cycle, even if you set a lower value.
#define PAUSE 300

// Frequency in MHz. Keep the decimal point to designate float.
// Check your own rules and regulations to see what is legal where you are.
#define FREQUENCY 866.3 // for Europe
// #define FREQUENCY 905.2 // for US

// LoRa bandwidth. Keep the decimal point to designate float.
// Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125.0, 250.0 and 500.0 kHz.
#define BANDWIDTH 250.0

// Number from 5 to 12. Higher means slower but higher “processor gain”,
// meaning (in nutshell) longer range and more robust against interference.
#define SPREADING_FACTOR 9

// Transmit power in dBm. 0 dBm = 1 mW, enough for tabletop-testing. This value can be
// set anywhere between -9 dBm (0.125 mW) to 22 dBm (158 mW). Note that the maximum ERP
// (which is what your antenna maximally radiates) on the EU ISM band is 25 mW, and that
// transmissting without an antenna can damage your hardware.
#define TRANSMIT_POWER 0

double_t rxdata = 0.0;
volatile bool rxFlag = true;
long counter = 0;
uint64_t last_tx = 0;
uint64_t tx_time;
uint64_t minimum_pause;
uint8_t len;
uint8_t size;

typedef struct struct_message {
float temp;
float temp_gnd;
float humid;
float humid_gnd;
float SL_press;
float radValue;
float rain;
float kph;
float kphGust;
float rainCumul;
float solP1;
float solP2;
float battShI1;
float battShI2;
float battV1;
float battV2;
float loadP1;
float loadP2;
float rssiWifi;
} struct_message;

// Create a struct_message called wx_data
struct_message wx_data;

void setup() {
heltec_setup();
// both.println(“Radio init”);
RADIOLIB_OR_HALT(radio.begin());
// Set the callback function for received packets
radio.setDio1Action(rx);
// Set radio parameters
// both.printf(“Frequency: %.2f MHz\n”, FREQUENCY);
RADIOLIB_OR_HALT(radio.setFrequency(FREQUENCY));
// both.printf(“Bandwidth: %.1f kHz\n”, BANDWIDTH);
RADIOLIB_OR_HALT(radio.setBandwidth(BANDWIDTH));
// both.printf(“Spreading Factor: %i\n”, SPREADING_FACTOR);
RADIOLIB_OR_HALT(radio.setSpreadingFactor(SPREADING_FACTOR));
// both.printf(“TX power: %i dBm\n”, TRANSMIT_POWER);
RADIOLIB_OR_HALT(radio.setOutputPower(TRANSMIT_POWER));
// Start receiving
RADIOLIB_OR_HALT(radio.startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF));
}

void loop() {
heltec_loop();

// If a packet was received, display it and the RSSI and SNR
if (rxFlag) {
rxFlag = false;
RADIOLIB(radio.readData((uint8_t *) &rxdata, sizeof(wx_data)));

Serial.printf("_radiolib_status: %d \n", _radiolib_status);

if (_radiolib_status == RADIOLIB_ERR_NONE && rxdata > 1.0) {
  memcpy(&wx_data, &rxdata, sizeof(wx_data));

  heltec_led(50); // 50% brightness is plenty for this LED

/*
Serial.printf(" Size: %d bytes, “, sizeof(wx_data));
Serial.printf(” RSSI: %.2f dBm, “, radio.getRSSI());
Serial.printf(” SNR: %.2f dB\n", radio.getSNR());

  Serial.printf("  Temp: %.1f C\n", wx_data.temp);
  Serial.printf("  Temp_Gnd: %.1f C\n", wx_data.temp_gnd);
  Serial.printf("  Humid: %.0f \%\n", wx_data.humid);
  Serial.printf("  Humid Gnd: %.0f \%\n", wx_data.humid_gnd);
  Serial.printf("  SL_press: %.1f hPa\n", wx_data.SL_press);
  Serial.printf("  Rad Value: %.0f W/m2\n", wx_data.radValue);
  Serial.printf("  Rain: %.2f mm\n", wx_data.rain);
  Serial.printf("  Wind: %.0f kph\n", wx_data.kph);
  Serial.printf("  Wind Gust: %.0f kph\n", wx_data.kphGust);
  Serial.printf("  Rain Cumul: %.2f mm\n", wx_data.rainCumul);
  Serial.printf("  Solar1 Power: %.0f mW\n", wx_data.solP1);
  Serial.printf("  Solar2 Power: %.0f mW\n", wx_data.solP2);
  Serial.printf("  Batt1 Current: %.0f mA\n", wx_data.battShI1);
  Serial.printf("  Batt2 Current: %.0f mA\n", wx_data.battShI2);
  Serial.printf("  Batt1 Volt: %.2f V\n", wx_data.battV1);
  Serial.printf("  Batt2 Volt: %.2f V\n", wx_data.battV2);
  Serial.printf("  Load1 Power: %.0f mW\n", wx_data.loadP1);
  Serial.printf("  Load2 Power: %.0f mW\n", wx_data.loadP2);
  Serial.printf("  WiFi RSSI: %.1f dBm\n", wx_data.rssiWifi);

*/
Serial.print(wx_data.temp);
Serial.print(", “);
Serial.print(wx_data.temp_gnd);
Serial.print(”, “);
Serial.print(wx_data.humid);
Serial.print(”, “);
Serial.print(wx_data.humid_gnd);
Serial.print(”, “);
Serial.print(wx_data.SL_press);
Serial.print(”, “);
Serial.print(wx_data.radValue);
Serial.print(”, “);
Serial.print(wx_data.rain);
Serial.print(”, “);
Serial.print(wx_data.kph);
Serial.print(”, “);
Serial.print(wx_data.kphGust);
Serial.print(”, “);
Serial.print(wx_data.rainCumul);
Serial.print(”, “);
Serial.print(wx_data.solP1);
Serial.print(”, “);
Serial.print(wx_data.solP2);
Serial.print(”, “);
Serial.print(wx_data.battShI1);
Serial.print(”, “);
Serial.print(wx_data.battShI2);
Serial.print(”, “);
Serial.print(wx_data.battV1);
Serial.print(”, “);
Serial.print(wx_data.battV2);
Serial.print(”, “);
Serial.print(wx_data.loadP1);
Serial.print(”, ");
Serial.println(wx_data.loadP2);

  delay(100);  heltec_led(0);
  rxdata = 0.0;
}

}

}

// Can’t do Serial or display things here, takes too much time for the interrupt
void rx() {
rxFlag = true;
}

Thank you!

What ever this is, maybe this?

Er, no, longer transmission time so more likely to have other signals cut in.

This defines the variable as floating point. And then:

Which reads as “put the 19 floats we received in to a variable that is defined as one single float, please”. Which it will do, but you are overwriting 18 x 4 bytes of memory with the received data that overflows. The rxdata needs to be defined as a pointer and 19 x sizeof(float) allocated. Or defined as an array. But overall, don’t send floats, see below.

First rule of fighting with embedded code club debugging is cut out stuff until it works then add stuff back in. Send just one byte and move on from there.

You can optimise your 76 byte payload and bypass all sorts of issues with using structs by converting the floats at the send end in to fixed bytes - you can fit quite a lot in to one or two bytes, I’d suspect it could be half the size. And if you only send power data less often in a different payload you can get it right down.

And so the legal authorities don’t get interested in your activities, make sure you are keeping to the 1% duty cycle.

Hi. Thanks for your reply and useful information.

This is the library that Heltec is suggesting to use with the Heltec LoRa 32 (v3).

These comments were on the original code from a Heltec example that I used to create this code, so not my comment. Given my lack of knowledge about the subject, I can only assume that the comment is correct.

Ok, good to know, but could you help me by giving an example of what declaration should look like as my knowledge of C++ is beginner’s level.

Don’t know how to do that. Also, I would rather not send different payload as it would make the parsing of payload complicated on the receiving end.

So far, the longest transmit time for a payload has been 307ms, but I only transmit every 60s, so I am well below the 1% limit.

Not linked from the product page - where did you read this?

It’s wrong due to the reason I provided.

uint16_t nameOfArray[100]; will create an array of 100 unsigned integers.