ESP32 LoRa two way radio communication

Anelito
Posts: 2
Joined: Mon Feb 01, 2021 1:00 am

ESP32 LoRa two way radio communication

Postby Anelito » Mon Feb 01, 2021 1:07 am

Hello everyone,
I have recently been exploring LoRa communication system and, inspired by the Meshtastic project to which I contributed in the early days, I decided to create a very basic two-way radio using a commercial LoRa module based on the ESP32.
Leveraging the two cores of the ESP32, I separated the logic into two threads, one responsible for sending messages and another for receiving. The TX thread also takes care of displaying the user interface via WiFi.

Now, going to the debug part, messages are correctly sent, I can see their spectral trace using a SDR dongle at 433MHz. However, somehow the receiving logic doesn't work. The RX thread is correctly working, there are no errors. I tried to replace with callbacks without success.

What can I do to find out the cause?

Here's the project files: https://github.com/grcasanova/Talker

Thank you

Here is the RX task code

Code: Select all

[Codebox=c file=Untitled.c]  
  while(true) {
    // try to parse packet
    int packetSize = LoRa.parsePacket();
    if (packetSize) {
      // received a packet
      Serial.print("Received packet");

      // 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 = "";

      while (LoRa.available()) {
        incoming += (char)LoRa.read();
      }

      if (incomingLength != incoming.length()) { // check length for error
        Serial.println("error: message length does not match length");
        continue;  // skip rest of the cycle
      }

      // if the recipient isn't this device or broadcast,
      if (recipient != FROM_ADDR && recipient != ALL) {
        Serial.println("This message is not for me.");
        continue;  // skip rest of the cycle
      }

      // Save msg
      String temp = "<li class='you'>"+incoming+"</li>";
      appendFile(SPIFFS, FILENAME, temp.c_str());

      // if message is for this device, or broadcast, print details:
      Serial.println("Message: " + incoming);
      Serial.println("RSSI: " + String(LoRa.packetRssi()));
      Serial.println("SNR: " + String(LoRa.packetSnr()));
      Serial.println();

      screen.clear();
      screen.setTextAlignment(TEXT_ALIGN_LEFT);
      screen.setFont(ArialMT_Plain_10);
      screen.drawString(0, 0, "Received Message:");
      screen.drawString(0, 15, incoming);
      screen.display();
    }
    
    vTaskDelay(10);
  }
}[/Codebox]
Last edited by Anelito on Mon Feb 01, 2021 10:34 am, edited 1 time in total.

chegewara
Posts: 2505
Joined: Wed Jun 14, 2017 9:00 pm

Re: ESP32 LoRa two way radio communication

Postby chegewara » Mon Feb 01, 2021 7:21 am

After quick pick on your code i have question, because i might miss it, where is LoRa switching to RX with lora.setRX(n) or lora.receive() which internally calls setRX()?
https://github.com/StuartsProjects/SX12 ... 7XLT.h#L57

Also you have to remember that you cant RX and TX at the same time, so you may miss some packets sometimes. In addition you have to call stRX() always after transmitting.

Anelito
Posts: 2
Joined: Mon Feb 01, 2021 1:00 am

Re: ESP32 LoRa two way radio communication

Postby Anelito » Mon Feb 01, 2021 10:39 am

I just followed Arduino LoRa library duplex example, where they don't use any switching between transmission and reception of data frames. Unless the "onReceive" callback already sets the radio in the receiving mode.

Regarding loss of packets, that's inherently connected to LoRa being half duplex, I haven't seen any special solution rather than basic buffering implemented in other projects like Meshtastic.

Code: Untitled.c Select all

#include <SPI.h>              // include libraries
#include <LoRa.h>

const int csPin = 7; // LoRa radio chip select
const int resetPin = 6; // LoRa radio reset
const int irqPin = 1; // change for your board; must be a hardware interrupt pin

String outgoing; // outgoing message

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

void setup() {
Serial.begin(9600); // initialize serial
while (!Serial);

Serial.println("LoRa Duplex");

// override the default CS, reset, and IRQ pins (optional)
LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin

if (!LoRa.begin(915E6)) { // initialize ratio at 915 MHz
Serial.println("LoRa init failed. Check your connections.");
while (true); // if failed, do nothing
}

Serial.println("LoRa init succeeded.");
}

void loop() {
if (millis() - lastSendTime > interval) {
String message = "HeLoRa World!"; // send a message
sendMessage(message);
Serial.println("Sending " + message);
lastSendTime = millis(); // timestamp the message
interval = random(2000) + 1000; // 2-3 seconds
}

// parse for a packet, and call onReceive with the result:
onReceive(LoRa.parsePacket());
}

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
}

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 = "";

while (LoRa.available()) {
incoming += (char)LoRa.read();
}

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

// if the recipient isn't this device or broadcast,
if (recipient != localAddress && recipient != 0xFF) {
Serial.println("This message is not for me.");
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();
}

chegewara
Posts: 2505
Joined: Wed Jun 14, 2017 9:00 pm

Re: ESP32 LoRa two way radio communication

Postby chegewara » Thu Feb 04, 2021 1:21 pm

Sorry, my bad. I assumed you are using different library, and i dont know that one, so i cant help.

Who is online

Users browsing this forum: No registered users and 1 guest