sandeepmistry / arduino-LoRa

An Arduino library for sending and receiving data using LoRa radios.
MIT License
1.61k stars 621 forks source link

LoRaDuplexCallback.ino fails when a callback occurs on ESP32-WROOM-DA Module. #592

Closed janczeresnia closed 1 year ago

janczeresnia commented 1 year ago

Hello, a very nice library. I have a problem with running the LoRaDuplexCallback.ino example on the ESP32 microcontroller. Every time an interrupt occurs, ESP32 restarts with an error:

Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1). 

Core  1 register dump:
PC      : 0x4008a634  PS      : 0x00060b35  A0      : 0x8008988a  A1      : 0x3ffbec7c  
A2      : 0x3ffb8a00  A3      : 0x3ffb8890  A4      : 0x00000004  A5      : 0x00060b23  
A6      : 0x00060b23  A7      : 0x00000001  A8      : 0x3ffb8890  A9      : 0x00000018  
A10     : 0x3ffb8890  A11     : 0x00000018  A12     : 0x3ffc187c  A13     : 0x00060b23  
A14     : 0x007beeb8  A15     : 0x003fffff  SAR     : 0x0000000e  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x40085cdc  LEND    : 0x40085ce6  LCOUNT  : 0x00000000  
Core  1 was running in ISR context:
EPC1    : 0x400dbdf7  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x00000000

When I removed all Serial.print calls from onReceive(int packetSize) function I get another error:

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x400845e0  PS      : 0x00050131  A0      : 0x800d1dfa  A1      : 0x3ffbee9c  
A2      : 0x00000040  A3      : 0x00018040  A4      : 0x000637ff  A5      : 0x3ffbee6c  
A6      : 0x00000000  A7      : 0x3ffbdbc4  A8      : 0x00000001  A9      : 0x40087e1a  
A10     : 0x00060623  A11     : 0x3ffc18ac  A12     : 0x00000001  A13     : 0x3ffbee4c  
A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x00000009  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x800d1e06  LBEG    : 0x40085e98  LEND    : 0x40085ea3  LCOUNT  : 0x00000000  

Backtrace:0x400845dd:0x3ffbee9c |<-CORRUPTED

When I disable hardware interrupts everything works but in my project I need interrupts. I checked the power supply, connections are ok.

A sketch which I am using with some changes to the original example:

/*
 * ESP32-Wroom-da module and LoRa SX127x Duplex Communication with callback
 */

#include <LoRa.h> // https://github.com/sandeepmistry/arduino-LoRa

#define SW_PIN                    13    // Switch GPIO13
#define LORA_ENABLE_IRQ_CALLBACK        // Enable/Disable Callback
/**************************************************************
  ESP32 hardware SPI
  MOSI: 23
  MISO: 19
  SCK:  18
  SS:   5
**************************************************************/
#define SPI_CS                    2     // GPIO2  --> SX127x's NSS
#define RST                       17    // GPIO17 --> SX127x's RESET
#ifdef LORA_ENABLE_IRQ_CALLBACK
  #define DI0                     16    // GPIO16 --> SX127x's DI0 IRQ (Interrupt Request)
#endif

// https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md
#define LORA_FREQUENCY            433E6 // frequency in Hz (433E6, 868E6, 915E6)
#define LORA_TX_POWER             2     // Supported values are 2 to 20 default 17
#define LORA_LNA_GAIN             3     // disable AGC and set LNA gain values between 1 - 6 are supported
#define LORA_SPREADING_FACTOR     9     // Supported values are between 6 and 12. If a spreading factor of 6 is set, implicit header mode must be used to transmit and receive packets.
#define LORA_SIGNAL_BANDWIDTH     125E3 // Supported values are 7.8E3, 10.4E3, 15.6E3, 20.8E3, 31.25E3, 41.7E3, 62.5E3, 125E3, 250E3, and 500E3
#define LORA_CONING_RATE          7     // Supported values are between 5 and 8, these correspond to coding rates of 4/5 and 4/8. The coding rate numerator is fixed at 4
#define LORA_PREAMBLE_LENGTH      6     // Supported values are between 6 and 65535 defaults to 8
#define LORA_SYNC_WORD            0x12  // byte value to use as the sync word, defaults to 0x12
#define LORA_ENABLE_CRC           true

String outgoing;               // outgoing message
byte msgCount = 0;             // count of outgoing messages
byte localAddress = 0xAA;      // address of this device
byte destination = 0xFF;       // destination to send to
long lastSendTime = 0;         // last send time
int interval = 2000;           // interval between sends

// Global variable for receive data
bool showMsg = false;
int recipientG;
byte senderG;            // sender address
byte incomingMsgIdG;     // incoming msg ID
byte incomingLengthG;    // incoming msg length
String incomingG;        // payload of packet
int rssiG;
int snrG;

void setup() {
  Serial.begin(115200);
  while (!Serial && (millis() < 1000)) delay(2000);
  Serial.println(F("ESP32 LoRa SX127x Duplex Callback"));
  // Configure LoRa module
  // override the default CS, reset, and IRQ pins (optional)
  LoRa.setSPI(SPI);
  #ifdef LORA_ENABLE_IRQ_CALLBACK
    Serial.println("LoRa IRQ Enable");// Callback enable code
    LoRa.setPins(SPI_CS, RST, DI0); // set CS, reset, IRQ pin
  #else
    Serial.println("LoRa IRQ Disable");// Callback disable code
    LoRa.setPins(SPI_CS, RST);      // set CS, reset
  #endif
  if (!LoRa.begin(LORA_FREQUENCY)) {
    while (true) {
      Serial.println("LoRa init failed !!!");
      delay(1000);
    }
  }
  LoRa.setGain(LORA_LNA_GAIN);
  LoRa.setTxPower(LORA_TX_POWER);
  LoRa.setSpreadingFactor(LORA_SPREADING_FACTOR);
  LoRa.setSignalBandwidth(LORA_SIGNAL_BANDWIDTH);
  LoRa.setCodingRate4(LORA_CONING_RATE);
  LoRa.setPreambleLength(LORA_PREAMBLE_LENGTH);
  LoRa.setSyncWord(LORA_SYNC_WORD);
  if (LORA_ENABLE_CRC == true) {
    LoRa.enableCrc();
  } else {
    LoRa.disableCrc();
  }
  #ifdef LORA_ENABLE_IRQ_CALLBACK
    // Callback enable code
    LoRa.onReceive(onReceive);
    LoRa.receive();
  #endif
  Serial.println("LoRa init OK");
}

void loop() {
  if (millis() - lastSendTime > interval) {
    String message = "ESP32 Co pan panie?";// send a message
    sendMessage(message);
    Serial.println("\nSend count: " + String(msgCount) + " message: " + message);
    lastSendTime = millis();            // timestamp the message
    interval = random(2000) + 1000;     // 2-3 seconds
    #ifdef LORA_ENABLE_IRQ_CALLBACK
      // Callback enable code
      LoRa.receive();                   // go back into receive mode
    #endif
  }
  #ifndef LORA_ENABLE_IRQ_CALLBACK
    // Callback disable code
    onReceive(LoRa.parsePacket());      // parse for a packet, and call onReceive with the result:
  #endif
  if (showMsg) {                        // Print on Serial receive data
    printReciveMsg();
  }
}

void sendMessage(String outgoing) {
  LoRa.beginPacket();                   // start packet
  LoRa.write(destination);              // add destination address
  LoRa.write(localAddress);             // add sender address
  LoRa.write(msgCount);                 // add message ID
  LoRa.write(outgoing.length());        // add payload length
  LoRa.print(outgoing);                 // add payload
  LoRa.endPacket();                     // finish packet and send it
  msgCount++;                           // increment message ID
}

// Print global variable on Serial in main loop
void printReciveMsg(void) {
  Serial.print("\nRcv from: 0x");
  Serial.println(senderG, HEX);

  Serial.print("Sent to: 0x");
  Serial.println(recipientG, HEX);

  Serial.print("Msg ID: ");
  Serial.println(incomingMsgIdG);

  Serial.print("Msg length: ");
  Serial.println(incomingLengthG);

  Serial.print("Msg: ");
  Serial.println(incomingG);

  Serial.print("RSSI: ");
  Serial.println(rssiG);

  Serial.print("Snr: ");
  Serial.println(snrG);

  Serial.flush();
  showMsg = false;
}

// Copy receive data do global variable
void CopyRcvData(int recipient,byte sender,byte incomingMsgId,byte incomingLength,String incoming,int rssi,int snr) {
  recipientG = recipient;
  senderG = sender;
  incomingMsgIdG = incomingMsgId;
  incomingLengthG = incomingLength;
  incomingG = incoming;
  rssiG = rssi;
  snrG = snr;
  showMsg = true;
}

void onReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return

  // read packet header bytes:
  int recipient = LoRa.read();          // recipient address
  byte sender = LoRa.read();            // sender address
  byte incomingMsgId = LoRa.read();     // incoming msg ID
  byte incomingLength = LoRa.read();    // incoming msg length
  String incoming = "";                 // payload of packet

  while (LoRa.available()) {            // can't use readString() in callback, so
    incoming += (char)LoRa.read();      // add bytes one by one
  }

  if (incomingLength != incoming.length()) {// check length for error
    Serial.println("error: msg not match length\n");
    return;                             // skip rest of function
  }

  // if the recipient isn't this device or broadcast,
  if (recipient != localAddress && recipient != 0xFF) {
    Serial.println("This msg is not for me.\n");
    return;                             // skip rest of function
  }

  // if message is for this device, or broadcast, print details:
//  Serial.println("Received from: 0x" + String(sender, HEX));
//  Serial.println("Sent to: 0x" + String(recipient, HEX));
//  Serial.println("Message ID: " + String(incomingMsgId));
//  Serial.println("Message length: " + String(incomingLength));
//  Serial.println("Message: " + incoming);
//  Serial.println("RSSI: " + String(LoRa.packetRssi()));
//  Serial.println("Snr: " + String(LoRa.packetSnr()));
//  Serial.println();

  int rssi = LoRa.packetRssi();
  int snr = LoRa.packetSnr();
  CopyRcvData(recipient,sender,incomingMsgId,incomingLength,incoming,rssi,snr);
}

I am using the latest of Arduino ESP32 Version 2.0.4 MCU: ESP32-WROOM-DA LoRa: module Ra-01

What to do to make the interrupts work properly?