LoRa Multiple Communication (LoRa Duplex)

Hello to all,
First I would like to apologize for my English.
I am new to working with the LoRa system and have already managed to do some work with the Heltec LORA ESP 32 V2 boards and have been successful when it is end to end ie two boards.
I saw an example from Heltec itself (LoRaMultipleCommunication) where it is possible to send data from multiple transmitters to a single receiver, I was very excited about the idea and tried to implement. It worked very well but I have some problems that if they can help me fix grateful.

What I am implementing is this.

Imgur

The problem I am having is this that occurs from time to time.

Imgur

the correct thing i should see would be like this and i see it for a long time until the error happens.

Imgur

What could be done to prevent this from happening?

This is the code I’m using

/*
This is a simple example show the Heltec.LoRa recived data in OLED.

The onboard OLED display is SSD1306 driver and I2C interface. In order to make the
OLED correctly operation, you should output a high-low-high(1-0-1) signal by soft-
ware to OLED’s reset pin, the low-level signal at least 5ms.

OLED pins to ESP32 GPIOs via this connecthin:
OLED_SDA – GPIO4
OLED_SCL – GPIO15
OLED_RST – GPIO16

by Aaron.Lee from HelTec AutoMation, ChengDu, China
成都惠利特自动化科技有限公司
www.heltec.cn

this project also realess in GitHub:
https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series
*/
#include “heltec.h”
#include “images.h”
#define RST 14 // GPIO14 RESET
#define BAND 915E6 //you can set band here directly,e.g. 868E6,915E6
String rssi;
String packSize = “–”;
String packet ;
String loRaMessage;
String temperatura1;
String umidade1;
String pressao1;
String estacao1;
String contador1;

//********
String temperatura2;
String umidade2;
String pressao2;
String estacao2;
String contador2;
//*********
int contador;
void logo(){
Heltec.display->clear();
Heltec.display->drawXbm(0,5,logo_width,logo_height,logo_bits);
Heltec.display->display();
}

void setup() {
//WIFI Kit series V1 not support Vext control
Heltec.begin(true /DisplayEnable Enable/, true /Heltec.Heltec.Heltec.LoRa Disable/, true /Serial Enable/, true /PABOOST Enable/, BAND /long BAND/);

Heltec.display->init();
Heltec.display->flipScreenVertically();
Heltec.display->setFont(ArialMT_Plain_16);
logo();
delay(1500);
Heltec.display->clear();

Heltec.display->drawString(0, 0, “Sucesso!”);
Heltec.display->drawString(0, 16, “Esperando …”);
Heltec.display->drawString(0, 32, “Dados …”);
Heltec.display->display();
delay(1000);
LoRa.receive();
}

void loop() {

int packetSize = LoRa.parsePacket();
if (packetSize)
{
while (LoRa.available())
{ //lora Avaliable
String LoRaData = LoRa.readString();
Serial.print("Dados Brutos: ");Serial.print(LoRaData);

if ((contador >0) && (contador<2)){   

int pos1 = LoRaData.indexOf('X');   // Contador 1
int pos2 = LoRaData.indexOf('T');  // Temperatura 1
int pos3 = LoRaData.indexOf('U');  // Umidade 1
int pos4 = LoRaData.indexOf('V');  // Pressão 1
int pos5 = LoRaData.indexOf('Z');  // Estação 1
contador1 = LoRaData.substring(pos1 +1, pos2);
temperatura1 = LoRaData.substring(pos2 +1, pos3);
umidade1 = LoRaData.substring(pos3+1, pos4);
pressao1 = LoRaData.substring(pos4+1, pos5);
estacao1 = LoRaData.substring(pos5+1, LoRaData.length());

}

/******************estaçao 2**********************************/

if ((contador >2) && (contador<5))
{
/estaçao 2****************/
int pos6 = LoRaData.indexOf(‘A’); // Contador2
int pos7 = LoRaData.indexOf(‘B’); // Temperatura 2
int pos8 = LoRaData.indexOf(‘C’); // umidade 2
int pos9 = LoRaData.indexOf(‘D’); // pressao 3
int pos10 = LoRaData.indexOf(‘E’); // Estação 2
contador2 = LoRaData.substring(pos6+1, pos7);
temperatura2 = LoRaData.substring(pos7+1, pos8);
umidade2= LoRaData.substring(pos8+1, pos9);
pressao2 = LoRaData.substring(pos9+1, pos10);
estacao2 = LoRaData.substring(pos10+1,LoRaData.length());
}
//Get RSSI
rssi = LoRa.packetRssi();
// Serial.print(" with RSSI ");
// Serial.println(rssi);

if ((contador >0) && (contador<2))
{
Heltec.display->clear();
Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
Heltec.display->setFont(ArialMT_Plain_16);
Heltec.display->drawString(0, 0, "Sinal: ");
Heltec.display->drawString(40, 0, rssi);
Heltec.display->drawString(80, 0, String(estacao1));
Heltec.display->drawString(0, 16, "Pacotes: ");
Heltec.display->drawString(90, 16, String(contador1));
Heltec.display->drawString(0, 32,"T: "+ String(temperatura1) + " U: "+String(umidade1));
Heltec.display->drawString(0, 48, "P: "+String(pressao1));
Heltec.display->display();
}

if ((contador >2) && (contador<4))
{
Heltec.display->clear();
Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
Heltec.display->setFont(ArialMT_Plain_16);
Heltec.display->drawString(0, 0, "Sinal: ");
Heltec.display->drawString(40, 0, rssi);
Heltec.display->drawString(80, 0, String(estacao2));
Heltec.display->drawString(0, 16, "Pacotes: ");
Heltec.display->drawString(90, 16, String(contador2));
Heltec.display->drawString(0, 32,"T: "+ String(temperatura2) + " U: "+String(umidade2));
Heltec.display->drawString(0, 48, "P: "+String(pressao2));
Heltec.display->display();
}

}
}
Serial.println("************* DADOS DA STATION TXA******************");

Serial.print(" TEMP-TXA; “); Serial.println(temperatura1);
Serial.print(” Umidade-TXA; “); Serial.println(umidade1);
Serial.print(” Pressão-TXA: “); Serial.println(pressao1);
Serial.print(” Estação TXA: “); Serial.println(estacao1);
Serial.print(” Contador1 TXA: "); Serial.println(contador1);

Serial.println(“DADOS DA STATION TXB*****”);

Serial.print(" TEMP-TXB: “); Serial.println(temperatura2);
Serial.print(” Umidade-TXB: “); Serial.println(umidade2);
Serial.print(” Pressão-TXB “); Serial.println(pressao2);
Serial.print(” Estação2:TXB “); Serial.println(estacao2);
Serial.print(” Contador2 TXB: “); Serial.println(contador2);
Serial.println(”***********########");

delay(1000);

contador++;
digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second

if (contador == 5)
{
contador = 0;
}
}

Can anyone help me or have a better idea?

I’m sorry to reply to you now … Because of the New Year’s holiday, China has a series of traditional ceremonies, during which almost no computer was touched.

Using a LoRa node as a gateway (Master) is not a good idea… Have you considered signal traffic jams? And problems with signal interference?

Hi @joiresende, I am doing pretty much exactly this, and a little bit more, although my set-up is really just a test bed at the moment while I’m getting several different processor configurations communicating with my LoRa Node ‘gateway’.

I currently have a WiFi LoRa Node 32, two Wireless Stick Lites, two CubeCells and two ESP32 Dev Board/RFM95W (with BME) configurations communicating through a single WiFi LoRa 32 node which is acting as an MQTT gateway, sending data to a local Node-Red/MQTT server. I’ve had this running for several months now as I work out various processor and software configuration details and it is now relatively stable, although not 100% so.

My nodes currently transmit data every 60 seconds, much more than I expect to ultimately need but precisely so that I can create some potential for congestion. I solve the problem of transmission collisions by using a formal data packet structure, not unlike UDP (if you’re familiar with data networking protocols), that includes a checksum.

I didn’t jump straight into LoRaWAN for historical reasons (I started this project 18 months ago, but I only got back to the task when I saw the CubeCell released), but that’s where I’d always planned to end up (although I only ever want to operate a closed, local IoT-style network).

My set-up is not really documented beyond the code itself and a Fritzing diagram or two, so I’m not really sure how useful it would be. Rather than post it here, if you’re interested, I’ll put the current version of the gateway code (WiFi LoRa 32) up on one of my websites (give me 24 hours to get that sorted) and you can let me know if you’re interested in anything more. I make no claims about the quality of the code or how I’m going about things. This is just a test bed for me as I develop all the hardware that I need to achieve my ultimate end, and the configuration changes regularly as I learn better ways to do things.

Hello @UniquePete,
Thank you for your reply, I am very grateful for your help.
Yes I would like to receive more information, if possible diagrams and code.
Thank you so much.

OK, this is what I currently have:


I have tried to provide all the necessary files here. Please note that this is little more than a test set-up. It works for me, but you may have to do a little bit of work to get things set up in your own environment. And while this all works for me at the moment, there is also no suggestion that any of this is the best, or even necessarily a good way to do anything. (I hope I’ve covered my backside sufficiently there…)

I did something similar to this, but using a different microcontroller and a discrete LoRa radio.

At the “gateway” side, I really only used the microcontroller for realtime timing - essentially I wrote a media access control layer for the microcontroller and had it pass all the data in and out via a serial interface (the board could do 1Mbps on the serial, which was good enough for a single LoRa channel.

The actual gateway function was written in python on a Raspberry Pi and just integrated to MQTT directly - it did not follow any LoRaWAN standards. It’s definitely possible, however I have ended up throwing this away and bought a RAK2245 concentrator card for the PI - while the single channel solution works, you have to do all your own debugging etc and it just makes sense to spend a few more dollars for a more robust solution!!

I think the best way to running a Node as a Gateway is the RadioShuttle protocol!

But due to some business issues, we have not reached consensus with RadioShuttle team on the ESP32 + LoRa series supporting this protocol.

The most big problem is frequency channel conflict if have too much devices. For now, separate each device in ID and use LBT (listen before talk) is simple and effective way.

Thank you very much for the answer and help, I am testing another solution given by our colleague @UniquePete. But I already thought about switching to this solution with the RAK2245 concentrator card, what I lack is the necessary experience with the Raspberry Pi.

Thank you, I really liked your solution and I am studying it and I intend to test it, on your website there are two files with the broken link, which are them (LoRaStickRainfallPacketSender.zip and LoRaStickTankPacketSender.zip)
Sincerely
João Resende

Yeah, it would have helped if I’d actually uploaded the files… They’re there now.

Did you check the rage of the LoRa node

Not specifically, but the ‘gateway’ is inside a timber framed and clad house with a metal roof (effectively in the roof cavity), and at the moment I have nodes that are both inside the house and outside 50-100m (and line of sight) away, getting SNR 12 to 6dB & RSSI -40 to -90dB respectively with the configuration I have [Edit: Up to 200m, SNR 6 & RSSI -100 with 3dBi antenna], but I’ve made no effort to optimise anything at this point. I have been a little slective with my antennae though, ensuring that they are indeed tuned to close to 915MHz—again, I’m using several types, generally 2-5dBi dipole antennae.

But please note that this is all just a proof-of-concept exercise. I’m not suggesting that anything I have done is ‘the’ way to do things, just that it is one way that should work for anyone who is just starting out and might want a configuration to establish that their hardware configuration is operational.

Thanks once more. Here ia a more detailed result we ran on a football field
The reading are in RSSI

0.5m 1.0m 1.5m 2.0m
5m -77 -76 -75 -71
10m -84 -82 -88 -76
15m -97 -90 -88 -79
20m -99 -91 -85 -92
25m -101 -94 -93 -90
30m -104 -99 -94 -92
35m -104 -95 -97 -92
40m -105 -102 -100 -97
45m -105 -100 -99 -97
50m -107 -102 -104 -98
55m -106 -103 -102 -97
60m -106 -107 -107 -103
65m -109 -105 -102 -103
70m -108 -107 -107 -102
75m -107 -105 -106 -103
80m -109 -108 -104 -102
85m -108 -108 -104 -102
90m -107 -104 -104 -104
95m -107 -105 -107 -103
100m -107 -108 -106 -127
105m -107 -106 -107 -102
110m -107 -107 -108 -105
115m -107 -108 -108 -127
120m -109 -107 -107 -106
125m -109 -108 -107 -107
130m -108 -108 -109 -109
135m -105 -105 -106 -107
140m -105 -105 -104 -107
145m -105 -105 -106 -107
150m -104 -104 -105 -105
155m -105 -104 -105 -105
160m -106 -106 -106 -106
165m -108 -105 -104 -108
170m -106 -107 -107 -106
175m -106 -106 -106 -104
180m -106 -105 -106 -107
185m -110 -106 -105 -108
190m -105 -106 -105 -107
195m -107 -105 -108 -107
200m -103 -105 -104 -108
205m -103 -106 -106 107
210m -107 -107 -105 -107
215m -107 -107 -107 -107
220m -108 -106 -106 -105
225m -105 -106 -105 -106
230m
235m
240m
245m
250m
255m
260m
265m

Refer to the RSSI value, it’s obviously abnormal. Please update this library via git: https://github.com/HelTecAutomation/Heltec_ESP32

and make sure you had set the right frequency compatible with your hardware.