Closed PepeProf closed 2 years ago
Hi,
First I took the liberty to clean up your code to make it more legible. Note that it's better to read the full packet first, and then deal with its contents. You want to flush the buffer anyway.
#include <SPI.h>
#include <LoRa.h>
//====== Defining Pins =============
#define RF_RST 22
#define RF_CS 15
#define RF_SCK 18
#define RF_MOSI 23
#define RF_MISO 19
#define RF_IRQ 11
//==================================
SPIClass hspi = NULL;
byte localAddress = 0x00;
void setup() {
Serial.begin(115200);
Serial.println("Starting...");
//========================== Initalizing Radio SPI ==================================
hspi = SPIClass(HSPI);
LoRa.setSPI(hspi);
LoRa.setPins(RF_CS, RF_RST, RF_IRQ);// set CS, reset, IRQ pin
if (!LoRa.begin(868E6)) Serial.println("LoRa init failed. Check your connections.");
//============================== MY ADDRESS =========================================
localAddress = 0x02;
//===================================================================================
LoRa.setTxPower(5);
Serial.println("LoRa init succeeded.");
LoRa.onReceive(onPackageReceive);
LoRa.receive();
//===================================================================================
}
void loop() {
delay(100);
}
void onPackageReceive(int packetSize) {
if (packetSize) {
Serial.println("Received packet");
char buff[16];
memset(buff, 0, 16);
int ix = 0;
while (LoRa.available()) {
char c = (char)LoRa.read();
buff[ix++] = c;
}
byte to = buff[0];
if (to == localAddress || to == 0xff) {
byte type = buff[1];
byte from = buff[2];
Serial.println("============== Package Received ==============");
Serial.print(" To: "); Serial.println(to, HEX);
Serial.print(" From: "); Serial.println(from, HEX);
Serial.print(" Type: "); Serial.println(type, HEX);
Serial.print(" RSSI: "); Serial.println(LoRa.packetRssi());
Serial.println("=============================================");
if (type == 0x02) {
sendPackage(from, 0x03);
Serial.println("Sent!");
}
}
}
}
void sendPackage(byte destination, byte type) {
LoRa.beginPacket();
LoRa.write(destination);
LoRa.write(type);
LoRa.write(localAddress);
LoRa.endPacket();
LoRa.receive();
Serial.println("=============# Package Sent #=============");
Serial.print(" To: "); Serial.println(destination, HEX);
Serial.print(" From: "); Serial.println(localAddress, HEX);
Serial.print(" Package Type: "); Serial.println(type, HEX);
Serial.println("==========================================");
}
Now the error points to Serial.println("Sent!");
, which is weird at best... "Sent!" does indeed get printed, as we can see in the Serial Monitor output...
0x400d20a9: Print::println(char const*) at C:\Users\Pepe\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32\Print.cpp line 196
0x400d20a9: Print::println(char const*) at C:\Users\Pepe\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32\Print.cpp line 196
0x400d0ead: onPackageReceive(int) at D:\Users\pepe\Desktop\arduino\sketch_nov06a/sketch_nov06a.ino line 70
So the crash happens on line 196 of Print.cpp
:
193 size_t Print::println(const char c[])
194 {
195 size_t n = print(c);
196 n += println(); // <-------- Say whu'?
197 return n;
198 }
There's nothing there that warrants throwing a fit. What happens if you remove altogether Serial.println("Sent!");
, or move it to the sendPackage()
routine? Does it still break?
First of all, thank you for replying!
It is kinda strange, if I remove every Serial.print then it throws:
Decoding stack results
0x400d1265: LoRaClass::receive(int) at C:\Users\Pepe\Documents\Arduino\libraries\LoRa\src\LoRa.cpp line 418
0x400d0d77: sendPackage(unsigned char, unsigned char) at D:\Users\pepe\Desktop\arduino\sketch_nov06a/sketch_nov06a.ino line 75
0x400d0ded: onPackageReceive(int) at D:\Users\pepe\Desktop\arduino\sketch_nov06a/sketch_nov06a.ino line 61
0x400d145f: LoRaClass::handleDio0Rise() at C:\Users\Pepe\Documents\Arduino\libraries\LoRa\src\LoRa.cpp line 721
0x400d1419: LoRaClass::handleDio0Rise() at C:\Users\Pepe\Documents\Arduino\libraries\LoRa\src\LoRa.cpp line 704
0x40080eba: LoRaClass::onDio0Rise() at C:\Users\Pepe\Documents\Arduino\libraries\LoRa\src\LoRa.cpp line 760
0x40080f05: __onPinInterrupt at C:\Users\Pepe\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32\esp32-hal-gpio.c line 220
But if I also remove LoRa.receive()
from sendPackage(byte destination, byte type)
, then it works which cannot believe because I am sure that I've tried that before.... 🤔 I think that little modification in the code did the trick! But I need to put it in receive mode after the onPackageReceive
function runs.
Is it possible to put LoRa.receive()
in the function without crashing the whole ESP? Or how would you do that?
I suspect that the LoRa.receive()
happens too quickly after LoRa.endPacket()
. Maybe try to do LoRa.endPacket(false);
first (instead of LoRa.endPacket();
, to see if that helps: looking at the source code, it seems the code doesn't necessarily wait for the Tx process to be done before closing up.
int LoRaClass::endPacket(bool async) {
if ((async) && (_onTxDone))
writeRegister(REG_DIO_MAPPING_1, 0x40); // DIO0 => TXDONE
// put in TX mode
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX);
if (!async) {
// wait for TX done
while ((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0) {
yield();
}
// clear IRQs
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
}
return 1;
}
So asking endPacket()
to wait could be a good idea. And possibly even adding a delay before LoRa.receive()
too.
Hello,
Unfortunately I was unable to put LoRa.receive()
in the function, no matter how big delays I added, or add false to the function.
So what I did, that I modified the LoRa.cpp file a little:
ICACHE_RAM_ATTR int LoRaClass::endPacket(bool async)
{
if ((async) && (_onTxDone))
writeRegister(REG_DIO_MAPPING_1, 0x40); // DIO0 => TXDONE
// put in TX mode
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX);
if (!async) {
// wait for TX done
while ((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0) {}
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
//Modified part:
delay(1);
writeRegister(REG_DIO_MAPPING_1, 0x00); // DIO0 => RXDONE
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS);
}
return 1;
}
And now, I don't have to care about adding LoRa.receive()
anywhere in the code, because it will automatically go back to receive mode after a packet is sent.
So thank you for helping me!
Hacking the library is always iffy, as the next update will wipe it out. But that looks like it's worth a PR. Great job.
Hello,
Currently I am having problems sending back a package from the receive function called by onReceive(). Everything is working correctly, all the pins are connected correctly and sending/receiving is working just fine.
First I send a package to the ESP32 with type 0x02 and the ESP answers back with package type 0x03. And in my case the package is sent back (type 0x03), but the ESP32 crashes, after it tries to leave the onPackageReceive() function.
Problematic ESP code:
Serial monitor:
Decoded backtrace:
I would really appreciate if someone could help me.