Some help with lora please :-)

Hi folks,

I've only recently become of aware of lora and to learn i thought I would make a little project. However, (for me) it's not as straight forward as it appeared on the surface.
I wanted to set up two as transmitters, and simply push a button and then from that, trigger them to send a string to a receiver and i can read it out on the serial monitor. That's it! Should be simple right... Pffffff...

I suppose, right now, I'd just be happy with getting one transmitter set up, sending out a hellow world type of msg and have it received by another module. I have a couple of uno's for this, and I am using the following

LAMBDA68 LoRa Transceiver (8D, 868MHz DIL version)

I also dl'd the library made by chandrawi

And I was also referencing the project by Renzo Mischianti

But... I think the combination of all of these just served to blow my mind...

What I'm looking for is, somebody to kindly push me in the right direction... I feel a tad lost at the moment.

For a start, my module seems to be pinned at be differently than in the aforementioned project - here it is:

image

What i think i need to do is, and this is probably way off the mark, but it's all I've got so far

Connect the loRa to uno
I believe i'll have to take account of the 3.3v LoRa and 5V arduino (i'll use a voltage divider for now)

nselect > CSS
sck > sck
sdo > mosi
sdi > miso (no level shifting required)

The TX_switch and RX_switch.
I'm thinking these are just for changing the mode of the transceiver. And i think i can output from the Dio pin to switch this. However, if I just want to set one as a transmitter and one as a receiver, can I just hard wire these?

Not sure what the busy pin does or if i need it.
I guess I also need to set the reset pin
I obviously need the VCC and GND set and my antenna connected.

Assuming the above is correct (which is doubtful)

I then need to write a sketch that configures these modules. Is the library I chose OK for this?

Apologies for just being a bit clueless here. I've been searching for quite some time now to find answers but, tbh, I'm struggling a little.

Any help is greatly appreciated :slight_smile:

I would recommend you dont use LoRa modules that have TX and RX enable pins, unless there is a hugely compelling reason to do so.

Basic LoRa modules, RFM9X, DRF127X, RAOx etc are supported by most libraries and there is heaps of tutorials on the Internet for using them.

Why did you decide to use the LAMBDA68 ?

Does the library you want to use support the TX\RX switcing of the LAMBDA68 ?

I would also recommend that if you have a 'project' that you use 3.3V Arduinos so have none of the logic level translation issues.

Thx for the speedy reply!

Simple answer, didn't know what I was doing. Had a brief conversation with somebody about LoRa, it sounded interesting and useful. Ignorantly thought all things were made equal. Then hit a wall with these modules so to speak.

Pfff, I 'think' so... but I don't really understand the whole switching thing anyway if i'm honest. I was assuming that as they are transceivers, then this function was just governing when one module listens or speaks. I thought in my case I could then just set those pins high and low for one module and the other way around for the other...

But, I obviously don't know what I'm doing, and you're probably right. This is probably a bad place to start out learning about LoRa, with these modules.

A good tip indeed.

Thank you so much for the help!

there are a number of modules which have a microcontroller and LoRa device on the same PCB which removes the problems of interconnecting the device using dupont wires with the associated problems of poor connections and intermittent failures
e.g. TTGO LoRa32 SX1276 OLED which has ESP32 (with onboard WiFi, Bluetooth Classic and BLE), a LoRa module and an OLED - gives you a wide range of communication options

Thx for the info, looks interesting. I do not know anything about these boards.

I've just bought several RFM96W to play with, on the advice of srnet. They have level shifting built in, which will save me a lot of hassle. I'm eventually planning on attaching a 3 inch display to an arduino nero and then also adding a LoRa module for comms. I've bought a few now just to see how it all goes together and whether or not it is feasible. Down the line i'd like about 15 of these in a huge open plan office, all going back to one arduino which would be set as a receiver. Each sender module would simply be used to tap a couple of icons on the resistive display every now and again. Not sure if this is doable, not sure if LoRa is the right way to go. It just seemed easier than hard wiring ethernet or using wifi for that matter... At the end of the day, it's fun though, which is what counts.

Quick question. I looked at the link you sent, and then I came across the, Arduino Nano ESP32 with Headers...

What would be the reason for buying one of these over a standard Arduino Nano?

Thx!

it has a ESP32-S3 more power, more memory etc and onboard WiFi and BLE
if you require LoRa you have to add an external module with all the interconnection problems
unless I particularly required a nano footprint I would tend to purchase as ESP32 NoneMCU module - cheaper and has an ESP32

if you are planning multiple LoRa device have a look at post decimals-strings-and-lora which discusses the problems of multiple devices communicating different data sets etc

Do you have a link to the module ?

The Nano ESP32 is OK if your LoRa node needs a lot of processing power, or Wifi\Bluetooth, and can be connected to the mains for power. But then the TTGO modules would be just as good, includes the LoRa module and are not expensive.

For applications that just collect remote switch presses or sensor readings you dont need a lot of processing power so you would go for low power nodes that have a low deep sleep current to give ad a long battery life.

Thx for the info and the link to that post. I've only just briefly skimmed it and by the looks of the content it's going to be of great help.

Also thx for the info. I've just taken delivery of 3 of these this morning. I need to solder the headers and aerial - hopefully I'll get chance over the weekend.

What I would say is - this is a project where I'm going to have to do a lot of learning. Part of the reason was to challenge and better myself.

The open space inside the building, although fairly large, the furthest transmitter would still be probably less than 100M from the receiver.

My programming is OK'ish, but I enjoy it and it's getting better.
My knowledge of LoRa is nothing really.

The project in itself is a 3.5 inch resistive touchscreen, this model

I've tried it out and I've been pretty impressed.

So, one of these strapped to an Arduino and a LoRa module used as the transmitter. Each separate display will show a menu of 4 icons, e.g. A, B, C, D.
You select A (for example) and it takes you to the next menu - the whole program will be roughly about 4 menus deep (and the same) on each transmitter.
The plan is to output these selections to the central receiver arduino.
From that, I'm thinking this reciever will be connected to a windows PC where I will have to make and run a program that displays this selections onto a large monitor which in real time changes as the selections from different modules is pressed.
So if you select 'A', then on the central monitor, the A might change colour (or something along those lines).
Actual data though, touches/selections on the various transmitters will be sporadic and not that frequent.

My problems. There's so much out there, hardware wise. And it's hard to know the best fit. I think what i have seems OK so far.
My skill level. I'm pushing myself. I've set about a 6 month time frame, so it should be good enough.
However, my skill and experience in some of this is limited, which makes choosing the best plan of attack difficult.
I've gone with LoRa as it looks interesting and it's something I want to know more about. Hard wiring would be a pain, so it's got to be remote.
Wifi is still an option.
I'm worried about LoRa not being able to handle multiple nodes.
The big obstacle for me though will be making the program that collects the data and displays it on the monitor.
Down the line, I don't really want to just display the data. I'll want to analyse it too. in the sense of times between each selection on a display. And I've no idea how to get to that point as of yet. I'm learning on the job so to speak.

Anyway, thx for the previous advice/help. If my plan seems like I'm on the wrong track, please let me know.

If you're British and you know who Cilla Black is... then it's pretty obvious I've got a LoRa Lora reading to do...

Sorry, couldn't resist.

:slight_smile:

the Adafruit RFM96W modules should communicate over 100M depending on environment, e.g. walls in the way
try a web search for uno spi for examples of SPI connections etc
the Adafruit RFM96W module documentation states they a 5V tolerant so should interface with a UNO OK
depending on the complexity of your program you may require a more powerful microcontroller than the UNO R3 with more memory etc

Depends on software, the LoRa is used on networks such as this;

it depends on how many nodes, how often information is communicated and the size of the data packets
clearly if multiple nodes transmit concurrently the information will be corrupted (also other transmitters in the area at the same frequency can corrupt transmissions)
I find the simplest approach is for the central server to poll each client node in turn
how many nodes?
how often the nodes communicate/second?
size of data packet?
e.g. LoRa is not designed to communicate real time video

Thank you both for the further info

Really... Oh... I thought if the transmitters were addressed differently this would eradicate this issue.

Not sure I'm understanding this correctly.

Just so I'm sure. Do you mean rather than the central server just receiving the data from the transmitters. It actively asks for it?

yes
if transmitters using the same communications channel can transmit at any time depending on traffic levels you may get collisions which corrupt the packets - for more details try a web serach for collisions in communication systems
having the central server polling the clients is one way to help eliminate the problem
the link in post 7 shows example code for polling in a LoRa perr-to-peer system

This makes sense...

I'm looking forward to having a bash over the weekend.

Thank you so much for the help!

So...

With everyone's help so far. I've managed to connect a resistive touchscreen and a LoRa RFM96W to an Arduino Uno. When I press the screen, it sends a string that another Uno and RFM96W receives.

I would however like to connect lots of these to one receiver.

I've read through the link kindly provided in post 7.
I thought I understood it... But I don't.

Rather than show all my code for the display etc, for simplicity sake, I've made a little project where I just connect a momentary push button to the sender, and a string is sent to the receiver when it is pressed.

Here is the code, for sender and then receiver:

#include <SPI.h>
#include <LoRa.h>
int butPin{5};
int butVal{};


void setup() {
Serial.begin(9600);
Serial.println("LoRa Sender");
LoRa.begin(433E6);
pinMode(butPin,INPUT);
pinMode(butPin,INPUT_PULLUP);
}

void loop() {

butVal = digitalRead(butPin);

if(butVal==0){
  LoRa.beginPacket();
  LoRa.println("Hi there");
  LoRa.endPacket();}

else{}

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

void setup() {
  
Serial.begin(9600);
Serial.print("LoRa Receiver");
LoRa.begin(433E6);

}

void loop() {
 
if(LoRa.parsePacket()){
  while(LoRa.available()){
    Serial.print((char)LoRa.read());}
}

}

So, if I wanted to now alter this, so that I instead poll the sender. And also give the sender it's own ID, so I can eventually add multiple senders. How do I do it?

Looking through the linked example I could see that a nodeID has been defined but I couldn't figure out where this had come from, what library.

Also, from a hardware set-up perspective, i'm assuming that I'd now have to connect a pin for interrupt?

Thx!

the example referenced in post 7 is complicated in that there are multiple slave nodes which transmit different structures

the following example is simpler in that only a single structure is used by all nodes
LoRa slave transmitter node 1
EDIT: edited structure and added more comments

// Lora transmit structure Node using Feather 32u4

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

#define nodeID 1  //  <<< set up required node ID

// test packet - must match receiver
struct __attribute__((packed)) Struct1 {
  byte NodeID;  // ID of transmitting node
  int16_t seq;  // sequence number
  int16_t distance;
  float voltage;
  char text[20];
};
Struct1 struct1 = { nodeID, 0, 1, 4.5, "hello" };  // test data

void setup() {
  Serial.begin(115200);
  while (!Serial)
    ;
  Serial.print("\nLoRa slave transmitter Node ID ");
  Serial.println(nodeID);
  // void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN);
  LoRa.setPins(8, 4, 7);  // for Lora 32u4
  if (!LoRa.begin(866E6)) {
    Serial.println("Starting LoRa failed!");
    while (1)
      ;
  }
  LoRa.onTxDone(onTxDone);    // setup transmit callback
  LoRa.onReceive(onReceive);  // setup receive callback
  LoRa_rxMode();
}

// poll for packets - check if packet received
void loop() {
  checkIfPacketReceived();        // if packet received process it
  checkIfPacketTransmitted();     // check if packet has been transmitted
 }

// set transmit mode
void LoRa_txMode() {
  LoRa.idle();             // set standby mode
  LoRa.disableInvertIQ();  // normal mode
}

// set receive mode
void LoRa_rxMode() {
  LoRa.disableInvertIQ();  // normal mode
  LoRa.receive();          // set receive mode
}

// ***************** code called when message transmitted  ********************
volatile bool transmittedPacketOK = false;  // set true when packet has been transmitted
// transmit finished -set flag
void onTxDone() {
  transmittedPacketOK = true;  // indicate Tx done
  LoRa_rxMode();               // set receive mode
}

// poll for packets - check if packet received
void checkIfPacketTransmitted(void) {
  if (!transmittedPacketOK) return;    // check if packet has been transmitted
  transmittedPacketOK = false;         // clear ready for next transmission
  Serial.print(" Node ");              // packet recived display data
  Serial.print(nodeID);
  Serial.print(" TxDone seq number ");
  Serial.print(" seq number ");
  Serial.print(struct1.seq);
  Serial.print(" distance = ");
  Serial.print(struct1.distance);
  Serial.print(" voltage = ");
  Serial.print(struct1.voltage);
  Serial.print(" text = ");
  Serial.println(struct1.text);
}

// ***************** code to receive a message ********************

volatile int packetReceived = 0;  // set when packet received
// receive packet - check it is a poll size 1 byte if not ignore
void onReceive(int packetSize) {
  if (packetSize != 1) return;  // if not a poll packet return
  packetReceived = packetSize;
}

// called to check if packet has been received - if so process it
void checkIfPacketReceived(void) {
  if (!packetReceived) return;  // if no packet has been received return
  Serial.print("Lora receive RSSI ");
  Serial.print(LoRa.packetRssi());
  Serial.print(" packet size ");
  Serial.print(packetReceived);
  byte nodeIDreceived = LoRa.read();  // read first byte
  Serial.print(" nodeID polled ");
  Serial.print(nodeIDreceived);
  if (nodeID == nodeIDreceived) {  // polled for this structID?
    Serial.println(" sending packet!");
    sendMessage();  // send a message
  } else Serial.println();
  packetReceived = 0;  // clear reday for next poll
}

// transmit a message packet
void sendMessage() {
  LoRa_txMode();          // set transmit mode
  struct1.seq++;          // increment packet sequence number
  struct1.distance += 1;  // setup next test values
  struct1.voltage += 1;
  struct1.text[4]++;
  //struct1.z[0] += 1;
  LoRa_txMode();                                  // set tx mode
  LoRa.beginPacket();                             // start packet
  LoRa.write((byte *)&struct1, sizeof(struct1));  // transmit packet
  // display packet contents
  //for (unsigned int i = 0; i < sizeof(struct);i++) {
  // Serial.print(' ');
  // Serial.print(((byte *) &struct1)[i]);
  //}
  LoRa.endPacket(true);  // finish packet and send it
}

LoRa Master receiver

// Lora master receiver using using Feather 32u4 - polled version

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

// test packet - must match transmitter
struct __attribute__((packed)) Struct1 {
  byte NodeID;  // ID of transmitting node
  int16_t seq;  // sequence number
  int16_t distance;
  float voltage;
  char text[20];
} struct1;

// used for polling
byte nodeIDs[] = { 1, 2, 3 };   // list of nodeIDs to poll
byte polledOK[] = { 2, 2, 2 };  // indicate polling sucess/failure
int nodeIndex = 0;              // index into above arrays

void setup() {
  Serial.begin(115200);
  while (!Serial)
    ;
  Serial.println("LoRa Receiver");
  // void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN);
  //LoRa.setPins(10, 9, 2);  // 10 for UNO, 53 for Mega
  LoRa.setPins(8, 4, 7);  // for Lora 32u4
  if (!LoRa.begin(866E6)) {
    Serial.println("Starting LoRa failed!");
    while (1)
      ;
  }
  Serial.println("\nLora Master Receiver started");
  LoRa.onReceive(onReceive);  // set receive callback
  LoRa_rxMode();              // set receive mode
}

void loop() {
  checkIfPacketReceived();  // if packet received process it
  pollNextSlave();          // check if time to poll next node
}

// set receive mode
void LoRa_rxMode() {
  LoRa.disableInvertIQ();  // normal mode
  LoRa.receive();          // set receive mode
}

// set transmit mode
void LoRa_txMode() {
  LoRa.idle();             // set standby mode
  LoRa.disableInvertIQ();  // normal mode
}

// ************* poll next slave node for data  ? ****************
void pollNextSlave(void) {
  static unsigned long timer = 0;       // used to time polling
  if (millis() - timer < 5000) return;  // check if time to poll next node
  timer = millis();                     // poll next slave - reset timer for next poll
  if (--polledOK[nodeIndex] == 0) {     // did last receive response?
    Serial.print("Node failed to respond to polling ID = ");
    Serial.println(nodeIDs[nodeIndex]);
    polledOK[nodeIndex] = 1;
  }
  Serial.print("polling ID = ");  // poll next node
  Serial.println(nodeIDs[nodeIndex]);
  //Serial.println(nodeIndex);
  LoRa_txMode();                   // set to transmit
  LoRa.beginPacket();              // start packet
  LoRa.write(nodeIDs[nodeIndex]);  // transmit packet
  LoRa.endPacket(true);            // finish packet and send it
  if (++nodeIndex >= sizeof(nodeIDs)) nodeIndex = 0;
  LoRa_rxMode();  // set receive mode
}

//***************code when packet is received ****************

volatile int packetReceived = 0;  // set when packet received
// receive packet
void onReceive(int packetSize) {
  packetReceived = packetSize;  // indicat packet received
}

// called to check if packet has been received - if so process it
void checkIfPacketReceived(void) {
  if (!packetReceived) return;  // if no packet has been received return
  Serial.print("Lora receive RSSI ");
  Serial.print(LoRa.packetRssi());
  Serial.print(" packet size ");
  Serial.print(packetReceived);
  LoRa.readBytes((byte *)&struct1, packetReceived);  // receive struct1 packet
  // display packet
  //for (int i = 0; i < packetSize; i++) {
  // Serial.print(' ');
  // Serial.print(((byte *) &struct1)[i]);
  // }
  Serial.print(" from Node ");  // display packet contents
  Serial.print(struct1.NodeID);
  Serial.print(" seq number ");
  Serial.print(struct1.seq);
  Serial.print(" distance 1 = ");
  Serial.print(struct1.distance);
  Serial.print(" voltage 1 = ");
  Serial.print(struct1.voltage);
  Serial.print(" text = ");
  Serial.println(struct1.text);
  checkSeqNumber(struct1.NodeID, struct1.seq);
  packetReceived = 0;  // clear for next time
}

// check received sequence number
void checkSeqNumber(int NodeID, int seq) {
  static int seqNumbers[] = { 0, 0, 0, 0 }, seqErrors = 0;
  if (NodeID >= sizeof(seqNumbers) / sizeof(int)) return;
  if (seq != seqNumbers[NodeID]) {  // check for sequence error!
    Serial.print("  seq number error expected ");
    Serial.print(seqNumbers[NodeID]);
    Serial.print(" received ");
    Serial.print(seq);
    Serial.print("  seq  errors ");
    Serial.println(++seqErrors);
    seqNumbers[NodeID] = seq;
  }
  seqNumbers[NodeID]++;      // next sequence nunber expected
  polledOK[NodeID - 1] = 2;  // indicate polling sucess
}

a test run using two slave nodeID 1 and nodeID 2
LoRa slave transmitter Node ID 1 serial monitor output

LoRa slave transmitter Node ID 1
Lora receive RSSI -83 packet size 1 nodeID polled 2
Lora receive RSSI -79 packet size 1 nodeID polled 3
Lora receive RSSI -83 packet size 1 nodeID polled 1 sending packet!
 Node 1 TxDone seq number  seq number 1 distance = 2 voltage = 5.50 text = hellp
Lora receive RSSI -86 packet size 1 nodeID polled 2
Lora receive RSSI -83 packet size 1 nodeID polled 3
Lora receive RSSI -83 packet size 1 nodeID polled 1 sending packet!
 Node 1 TxDone seq number  seq number 2 distance = 3 voltage = 6.50 text = hellq
Lora receive RSSI -86 packet size 1 nodeID polled 2
Lora receive RSSI -79 packet size 1 nodeID polled 1 sending packet!
 Node 1 TxDone seq number  seq number 3 distance = 4 voltage = 7.50 text = hellr
Lora receive RSSI -79 packet size 1 nodeID polled 2
Lora receive RSSI -83 packet size 1 nodeID polled 3
Lora receive RSSI -83 packet size 1 nodeID polled 1 sending packet!
 Node 1 TxDone seq number  seq number 4 distance = 5 voltage = 8.50 text = hells
Lora receive RSSI -83 packet size 1 nodeID polled 2
Lora receive RSSI -83 packet size 1 nodeID polled 3
Lora receive RSSI -83 packet size 1 nodeID polled 1 sending packet!
 Node 1 TxDone seq number  seq number 5 distance = 6 voltage = 9.50 text = hellt

LoRa slave transmitter Node ID 2 serial monitor output

LoRa slave transmitter Node ID 2
Lora receive RSSI -117 packet size 1 nodeID polled 3
Lora receive RSSI -117 packet size 1 nodeID polled 1
Lora receive RSSI -117 packet size 1 nodeID polled 2 sending packet!
 Node 2 TxDone seq number  seq number 1 distance = 2 voltage = 5.50 text = hellp
Lora receive RSSI -117 packet size 1 nodeID polled 3
Lora receive RSSI -117 packet size 1 nodeID polled 1
Lora receive RSSI -116 packet size 1 nodeID polled 2 sending packet!
 Node 2 TxDone seq number  seq number 2 distance = 3 voltage = 6.50 text = hellq
Lora receive RSSI -116 packet size 1 nodeID polled 3
Lora receive RSSI -112 packet size 1 nodeID polled 1
Lora receive RSSI -117 packet size 1 nodeID polled 2 sending packet!
 Node 2 TxDone seq number  seq number 3 distance = 4 voltage = 7.50 text = hellr
Lora receive RSSI -112 packet size 1 nodeID polled 3
Lora receive RSSI -114 packet size 1 nodeID polled 1
Lora receive RSSI -117 packet size 1 nodeID polled 2 sending packet!
 Node 2 TxDone seq number  seq number 4 distance = 5 voltage = 8.50 text = hells
Lora receive RSSI -114 packet size 1 nodeID polled 3
Lora receive RSSI -113 packet size 1 nodeID polled 1
Lora receive RSSI -117 packet size 1 nodeID polled 2 sending packet!
 Node 2 TxDone seq number  seq number 5 distance = 6 voltage = 9.50 text = hellt
Lora receive RSSI -117 packet size 1 nodeID polled 3

LoRa master node serial monitor output

Lora Receiver started
polling ID = 1
Lora receive RSSI -65 packet size 29 from Node 1 seq number 3 distance 1 = 4 voltage 1 = 7.50 text = hellr
  seq number error expected 0 received 3  seq  errors 1
polling ID = 2
polling ID = 3
polling ID = 1
Lora receive RSSI -66 packet size 29 from Node 1 seq number 4 distance 1 = 5 voltage 1 = 8.50 text = hells
Node failed to respond to polling ID = 2
polling ID = 2
Lora receive RSSI -111 packet size 29 from Node 2 seq number 1 distance 1 = 2 voltage 1 = 5.50 text = hellp
  seq number error expected 0 received 1  seq  errors 2
Node failed to respond to polling ID = 3
polling ID = 3
polling ID = 1
Lora receive RSSI -65 packet size 29 from Node 1 seq number 5 distance 1 = 6 voltage 1 = 9.50 text = hellt
polling ID = 2
Lora receive RSSI -111 packet size 29 from Node 2 seq number 2 distance 1 = 3 voltage 1 = 6.50 text = hellq
Node failed to respond to polling ID = 3
polling ID = 3
polling ID = 1
Lora receive RSSI -65 packet size 29 from Node 1 seq number 6 distance 1 = 7 voltage 1 = 10.50 text = hellu
polling ID = 2
Lora receive RSSI -111 packet size 29 from Node 2 seq number 3 distance 1 = 4 voltage 1 = 7.50 text = hellr
Node failed to respond to polling ID = 3
polling ID = 3
polling ID = 1
Lora receive RSSI -65 packet size 29 from Node 1 seq number 7 distance 1 = 8 voltage 1 = 11.50 text = hellv
polling ID = 2
Lora receive RSSI -112 packet size 29 from Node 2 seq number 4 distance 1 = 5 voltage 1 = 8.50 text = hells
Node failed to respond to polling ID = 3
polling ID = 3
polling ID = 1
Lora receive RSSI -65 packet size 29 from Node 1 seq number 8 distance 1 = 9 voltage 1 = 12.50 text = hellw
polling ID = 2
Lora receive RSSI -112 packet size 29 from Node 2 seq number 5 distance 1 = 6 voltage 1 = 9.50 text = hellt
Node failed to respond to polling ID = 3
polling ID = 3
polling ID = 1
Lora receive RSSI -66 packet size 29 from Node 1 seq number 9 distance 1 = 10 voltage 1 = 13.50 text = hellx
polling ID = 2
Lora receive RSSI -111 packet size 29 from Node 2 seq number 6 distance 1 = 7 voltage 1 = 10.50 text = hellu
Node failed to respond to polling ID = 3

there are a couple of sequence errors reported on master startup as it synchronises with the slave nodes

to use polling each node must have a unique identifier so that it knows when a packet is received it is the intended recipent
in the abive example each sender node has a definition specifing its ID, e.g. node 1

#define nodeID 1      //  <<< set up required node ID

this is assigned by the programmer when programming each node

when the data structure used for communication is declared it has the NodeID as one of its members

// test packet - must match receiver
struct __attribute__((packed)) Struct1 {
  byte NodeID;  // ID of transmitting node
  int16_t seq;  // sequence number
  int16_t distance;
  float voltage;
  char text[20];
};

when the data stucture variable is defined the member NodeID is initialised

Struct1 struct1 = { nodeID, 0, 1, 4.5, "hello" }; // test data

i.e. the value if struct1.NodeID is initialised to nodeID (in this case 1)

the master node has a array containing is list of slave NodeIDs

byte nodeIDs[] = { 1, 2, 3 };   // list of nodeIDs to poll

which it loops thru transmitting a packet requesting data from each slave in turn

Although the above code is using Adafruit Feather 32u4 LoRa modules the basic concepts can be used for other LoRa and radio modules which transmit and receive packets

1 Like

it appears the LoRaRF library supports the LLCC68
also worth trying Arduino-LoRa library
get simple one way transmission working first then look at more cpmplex projects

if you are planning to use the RFM69 LoRa have a look at adafruit-rfm69hcw-and-rfm96-rfm95-rfm98-lora-packet-padio-breakouts - it give an example of connecting the RFM69 to an Arduino board etc