How to Transmit/Receive Multiple Data with RA-02 LoRa SOLVED

Hi all!
I am trying to send/receive 4 integers with ra-02 and Arduino or ESP8266. The integers are latitude, longitude, speed, and course. I was thinking I need to parse the incoming stream somehow, but don't know how to. Answers would be great!
Thanks!

Pack them together as a struct or an array and send all at once.

Hi
Thanks for your response. How would I parse that on the receiver side? Like, distinguish between the different data?

That's the benefit of using a struct / array on both sides and transmitting the raw binary ... you don't have to "parse" anything.

You send bytes from the struct's memory address on the TX side and store them in the corresponding struct's memory address on the RX side.

Just send and receive an array of binary values. No need to parse anything.

That was my first thought, to do a struct, but using the LoRa library, I don’t think that is possible. When I try to transmit the data that way, this is the response:
“no matching function for call to ‘LoRaClass::print(Data_Package&)’”

Here is the code:

#include <SPI.h>
#include <LoRa.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

#define ss 5
#define rst 0
#define dio0 4

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 4800;
int counter = 0;

TinyGPSPlus gps;
SoftwareSerial gpsSerial(RXPin, TXPin);

struct Data_Package {
  byte Latitude;
  byte Longitude;
  byte Speed;
  byte Course;
};
Data_Package data;

void setup() {
  Serial.begin(9600);
  gpsSerial.begin(GPSBaud);
  Serial.println("LoRa Sender");
  LoRa.setPins(ss, rst, dio0);  
  if (!LoRa.begin(915E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  LoRa.setSyncWord(0xF3);
  Serial.println("LoRa Initializing OK!");
}

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(counter);

  data.Latitude = gps.location.lat();
  data.Longitude = gps.location.lng();
  data.Course = gps.course.deg();
  data.Speed = gps.speed.mph();
  
  // send packet
  LoRa.beginPacket();
  LoRa.print(data);
  LoRa.endPacket();

  counter++;

  delay(5000);
}

kgray9:
That was my first thought, to do a struct, but using the LoRa library, I don't think that is possible.

You need to be more specific about "the LoRa library". There's more than one. Which one are you using? Post the GitHub link.

https://www.arduino.cc/reference/en/libraries/lora/

First, note the maximum packet size of 255 byte which should be more than enough for your struct.

You need to reference LoRa.h for the available methods. The LoRaClass class inherits from Stream. So, you have:

virtual size_t write(const uint8_t *buffer, size_t size);

for sending your packet.

On the RX side, use parsePacket() and make sure the length is correct. The, read() each byte and copy it into successive locations of the receiving struct. Or, read() it all into a separate buffer the memcpy it into the struct.

Note that RadioHead is a more capable library. See the Reliable Datagram examples.

kgray9:
Hi all!
I am trying to send/receive 4 integers with ra-02 and Arduino or ESP8266.

Be careful using structures.
If your Arduino is one such as an Arduino UNO, Pro Mini or Mega, then 32 bit microcontrollers such as ESP32 and DUE, wont decode the structure correctly.
I can point you at a library that allows you to build the LoRa packet to send like this;

LoRa.startWriteSXBuffer(0);
LoRa.writeUint16(voltage);  
LoRa.writeUint16(temperature);  
LoRa.endWriteSXBuffer();

The receiver then uses this to decode the received buffer;

LoRa.startReadSXBuffer(0);
voltage = LoRa.readUint16(); 
temperature = LoRa.readUint16();
LoRa.endReadSXBuffer();

If you want to send a strucrure then the library allows you to send an array\buffer directly like this;

LoRa.transmit(array, sizeof(array), ...............

The array can be a structure, character array or and array that you fill yourself with integers, floats etc.

srnet:
Be careful using structures.
If your Arduino is one such as an Arduino UNO, Pro Mini or Mega, then 32 bit microcontrollers such as ESP32 and DUE, wont decode the structure correctly.

I usually first look to see how each side allocates the struct then adjust data types and packing accordingly.

Sorry. Any short code examples @gfvalvo? I'm still kind of new to C++.

gfvalvo: virtual size_t write(const uint8_t *buffer, size_t size);

for sending your packet.

How would I use this in my code? Is that instead of LoRa.print();? Would I use it almost like I do with the Radiohead library? Like:

radio.write(&data, sizeof(Data_Package));

But instead:

LoRa.write(&data, sizeof(Data_Package));

:confused: ?

I just found the LoRaDuplex LoRa library example. :slight_smile: It is exactly what I need. Thanks for all the responses everyone!

SOLVED

kgray9:
I just found the LoRaDuplex LoRa library example.

Which if I recall correctly uses Strings ?

Its generally considered not to be a good idea to uses Strings with Arduinos.

It sends multiple integers for msg ID, message length, local address, and recipient address, as well as a message that is a string. I sent my 4 pieces of data without even using the message payload (which is a string).

Here is my working sender code for for anyone who might find it useful:

#include <SPI.h>
#include <LoRa.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

#define ss 5
#define rst 0
#define dio0 4

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 4800;
int counter = 0;

TinyGPSPlus gps;
SoftwareSerial gpsSerial(RXPin, TXPin);

byte msgCount = 0;
byte Latitude;
byte Longitude;
byte Speed;
byte Course;
byte localAddress = 0xBB;
byte destination = 0xFF;

void setup() {
  Serial.begin(9600);
  gpsSerial.begin(GPSBaud);
  Serial.println("LoRa Sender");
  LoRa.setPins(ss, rst, dio0);  
  if (!LoRa.begin(915E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  Serial.println("LoRa Initializing OK!");
}

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(msgCount);

  Latitude = gps.location.lat();
  Longitude = gps.location.lng();
  Course = gps.course.deg();
  Speed = gps.speed.mph();
  String outgoing = String(Latitude) + String(Longitude) + String(Course) + String(Speed);
  // send packet
  LoRa.beginPacket();
  LoRa.write(destination);
  LoRa.write(localAddress);
  LoRa.write(msgCount);
  LoRa.write(outgoing.length());
  LoRa.write(Latitude);
  LoRa.write(Longitude);
  LoRa.write(Course);
  LoRa.write(Speed);
  LoRa.endPacket();
  msgCount++;
  delay(4000);
}

Here is the receiver code:

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

#define ss 5
#define rst 0
#define dio0 4

byte localAddress = 0xFF;
int recipient;
String incoming;
byte sender;
byte incomingMsgId;
byte incomingLength;
byte Latitude;
byte Longitude;
byte Course;
byte Speed;

void setup() {
  Serial.begin(9600);
  Serial.println("LoRa Receiver");
  LoRa.setPins(ss, rst, dio0);  
  if (!LoRa.begin(915E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  int packetSize = LoRa.parsePacket();
  if (packetSize == 0) return;
  recipient = LoRa.read();
  sender = LoRa.read();
  incomingMsgId = LoRa.read();
  incomingLength = LoRa.read();
  Latitude = LoRa.read();
  Longitude = LoRa.read();
  Course = LoRa.read();
  Speed = LoRa.read();
  incoming = String(Latitude) + String(Longitude) + String(Course) + String(Speed);
  if (incomingLength != incoming.length()) {
    Serial.println("error: message length does not match length");
    return;
  }
  if (recipient != localAddress) {
    Serial.println("This message is not for me.");
    return;
  }
  Serial.println("********************************************");
  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("Latitude: " + String(Latitude));
  Serial.println("Longitude: " + String(Longitude));
  Serial.println("Course: " + String(Course));
  Serial.println("Speed: " + String(Speed));
  Serial.println("RSSI: " + String(LoRa.packetRssi()));
  Serial.println("Snr: " + String(LoRa.packetSnr()));
  Serial.println("");
}

Here is the serial monitor output of the receiver:

********************************************
Received from: 0xbb
Sent to: 0xff
Message ID: 48
Message length: 4
Latitude: 0
Longitude: 0
Course: 0
Speed: 0
RSSI: -120
Snr: -3.50

I don’t have the GPS hooked up yet so all its data is showing up as 0.
My new tutorial: https://www.hackster.io/k-gray/ra-02-lora-with-esp8266-ecd71b

Hope this helps!

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.