sandeepmistry / arduino-LoRa

An Arduino library for sending and receiving data using LoRa radios.
MIT License
1.64k stars 627 forks source link

Problem with two instances of LoRaClass. Only crap is shown in the Arduino Serial Monitor #279

Closed linuxtrainer closed 5 years ago

linuxtrainer commented 5 years ago

I startet a project with two Lora-Moduls on one Arduino Pro Mini. One of the sx1278-Module should work as receiver and the other one should be the transmitter. A picture of the breadboard with the two LoRa-AI-Thinker-Ra-02-Modules can be seen here: https://raphuscucullatus.blogspot.com/2019/07/2-mal-sx1278-und-1-mal-atmega328p.html

If I use the following code, everthing works fine:


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

#define LED_BUILTIN 13
#define MAXMESSAGEL 64

unsigned int counter1=0;
unsigned int counter2=0;
char zeichenkette1[32]="1234567890123456789012345678901";

unsigned int zuzahl1=0;

LoRaClass LoRaOut;

void setup() {
  delay(10000);

  Serial.begin(9600); 
  while (!Serial){
    delay(1);
  }

  randomSeed(analogRead(0));

  Serial.println("LoRa Sender/Empfaenger");
  //LoRaInsetPins(ss, reset, dio0);
  // Default: ss->10, reset->9, dio0->2 of the Sandeep Mistry-Library
  LoRa.setPins(10,9,2);
  LoRaOut.setPins(8,4,7);

  if (!LoRaOut.begin(433000000)) {
    Serial.println("Starting LoRa-Transmitter failed!");
    while (1){
        delay(1);
      };
  }else{
    Serial.println("Starting LoRa-Transmitter succeed!");
  }

  if (!LoRa.begin(433000000)) {  
    Serial.println("Starting LoRa-Receiver failed!");
    while (1){
       delay(1);
       };
  }else{
    Serial.println("Starting LoRa-Receiver succeed!");
  }

  LoRaOut.setPreambleLength(8);
  LoRa.setPreambleLength(12);

  LoRaOut.setSpreadingFactor(12);
  LoRa.setSpreadingFactor(10);

  LoRaOut.setSignalBandwidth(62.5E3);
  LoRa.setSignalBandwidth(62.5E3);

  LoRaOut.setCodingRate4(5);

  LoRaOut.setTxPower(2);

  LoRa.onReceive(onReceive);
  LoRa.receive();
}

void loop() {
  zuzahl1 = random(10000,50000);

  Serial.print("Sending packet: ");
  Serial.println(counter1);

  // send packet Lora1
  LoRaOut.beginPacket();
  LoRaOut.print(counter1);
  LoRaOut.print(" ");
  LoRaOut.print(zuzahl1);
  LoRaOut.print(" ");
  LoRaOut.print(zeichenkette1);
  LoRaOut.endPacket(true);
  //Serial.println("Sending Packet on LoraOut finished");
  counter1++;
  delay(15000);
}

void onReceive(int packetSize) {
  unsigned int i=0;

  // received a packet
  Serial.print("Received packet: ");
  Serial.print(counter2++);
  Serial.print(' ');
  Serial.print("Paketgroesse: ");
  Serial.print(packetSize);// print RSSI of packet
  Serial.print(" With RSSI: ");
  Serial.println(LoRa.packetRssi());
  Serial.print("available:");
  Serial.println(LoRa.available());

  // read packet
  for (i=0;i<packetSize;i++) {
      Serial.print((char)LoRa.read());
  }

}

t if I use a second instance of the LoraClass, in my example named LoraIn, crap is posted by the LoraIn.read()-function called in the callback-function:


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

#define LED_BUILTIN 13
#define MAXMESSAGEL 64

unsigned int counter1=0;
unsigned int counter2=0;
char zeichenkette1[32]="1234567890123456789012345678901";

unsigned int zuzahl1=0;

LoRaClass LoRaIn;
LoRaClass LoRaOut;

void setup() {
  delay(10000);

  Serial.begin(9600); 
  while (!Serial){
    delay(1);
  }

  randomSeed(analogRead(0));

  Serial.println("LoRa Sender/Empfaenger");
  //LoRaInsetPins(ss, reset, dio0);
  // Default: ss->10, reset->9, dio0->2 of the Sandeep Mistry-Library
  LoRaIn.setPins(10,9,2);
  LoRaOut.setPins(8,4,7);

  if (!LoRaOut.begin(433000000)) {
    Serial.println("Starting LoRa-Transmitter failed!");
    while (1){
        delay(1);
      };
  }else{
    Serial.println("Starting LoRa-Transmitter succeed!");
  }

  if (!LoRaIn.begin(433000000)) {  
    Serial.println("Starting LoRa-Receiver failed!");
    while (1){
       delay(1);
       };
  }else{
    Serial.println("Starting LoRa-Receiver succeed!");
  }

  LoRaOut.setPreambleLength(8);
  LoRaIn.setPreambleLength(12);

  LoRaOut.setSpreadingFactor(12);
  LoRaIn.setSpreadingFactor(10);

  LoRaOut.setSignalBandwidth(62.5E3);
  LoRaIn.setSignalBandwidth(62.5E3);

  LoRaOut.setCodingRate4(5);

  LoRaOut.setTxPower(2);

  LoRa.onReceive(onReceive);
  LoRaIn.receive();
}

void loop() {
  zuzahl1 = random(10000,50000);

  Serial.print("Sending packet: ");
  Serial.println(counter1);

  // send packet Lora1
  LoRaOut.beginPacket();
  LoRaOut.print(counter1);
  LoRaOut.print(" ");
  LoRaOut.print(zuzahl1);
  LoRaOut.print(" ");
  LoRaOut.print(zeichenkette1);
  LoRaOut.endPacket(true);
  //Serial.println("Sending Packet on LoraOut finished");
  counter1++;
  delay(15000);
}

void onReceive(int packetSize) {
  unsigned int i=0;
  Serial.println("Callback");

  // received a packet
  Serial.print("Received packet: ");
  Serial.print(counter2++);
  Serial.print(' ');
  Serial.print("Paketgroesse: ");
  Serial.print(packetSize);// print RSSI of packet
  Serial.print(" With RSSI: ");
  Serial.println(LoRaIn.packetRssi());
  Serial.print("available:");
  Serial.println(LoRaIn.available());

  // read packet
  for (i=0;i<packetSize;i++) {
      Serial.print((char)LoRaIn.read());
  }

}

with the last sketch using LoRaIn, this is what can be seen in the Arduino Serial Monitor:


Starting LoRa-Transmitter succeed! Starting LoRa-Receiver succeed! Callback Received packet: 0 Paketgroesse: 0 With RSSI: -164 available:0 Sending packet: 0 Sending packet: 1 Callback Received packet: 1 Paketgroesse: 40 With RSSI: -40 available:40 28 29720 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdeCallback Received packet: 2 Paketgroesse: 40 With RSSI: -62 available:0 ����������������������������������������Sending packet: 2 Callback Received packet: 3 Paketgroesse: 40 With RSSI: -62 available:0 ����������������������������������������Sending packet: 3 Callback Received packet: 4 Paketgroesse: 40 With RSSI: -61 available:0 ����������������������������������������Sending packet: 4 Callback Received packet: 5 Paketgroesse: 40 With RSSI: -61 available:0 ����������������������������������������Sending packet: 5 Callback Received packet: 6 Paketgroesse: 40 With RSSI: -61 available:0 ����������������������������������������Sending packet: 6


Interestingly the very first receive packet will be displayed as it should, but from all following packets only crap is shown. I know that not every packet will be received, as there is perhaps an interference between transmitter and incoming data, what sometimes happens. This sort of data lose is not the problem at the moment. This projekt is for educational purpose only, and the aim is one transmitter and one receiver on one arduino pro mini.

I am only interested whats the problem with two LoRaClass-Instances. Perhaps someone can help me? Thanks for answer and best regards!

Leo

morganrallen commented 5 years ago

Interestingly the very first receive packet will be displayed as it should, but from all following packets only crap is shown.

Based on this it might be the same issue of the FIFO buffer position being incorrectly reset. I released version 0.6.0 last night that contains this fix. Give this a try before we dig into this issue. Reopen if the problem persists.

paidforby commented 4 years ago

Hey @linuxtrainer and @morganrallen, I'm working on a very similar idea for disaster radio's LoRaLayer2 library.

I have a strong feeling that what @linuxtrainer is trying to do is not possible with the arduino-LoRa library as is.

The problem lies with the onReceive callback. Inside of the function that ultimately handles the receive callback, onDio0Rise, there is a reference to the global LoRa class in which LoRa.handleDio0Rise() is called, see LoRa.cpp line 715.

This means that any call to onReceive will not care if you read from a locally created LoRa object (in this case LoRaIn), it will always read from the register of the global LoRa object, even if you never setPins or begin that object.

This explains why the second example only reads the first message, because the register of LoraIn is never being cleared and reset, so the subsequent reads are just reading the garbage in the remainder of the register.

Currently, the only "right" way (that I can see) to use two LoRa modules in the same sketch is with @linuxtrainer first example. Using the global LoRa object as your receiver and an additional LoRa object as your transmitter. Even if you create a local LoRa object for your receiver and it appears to work, you are only disguising the fact that you are actually using the global object.

@morganrallen does my theory sound right? I'm interested to setup proper bi-directional communication on multiple LoRa modules, but I'm almost sure it will require forking this repo. I can open a new issue for that, since it maybe outside the scope of the original issue.

morganrallen commented 4 years ago

Good catch @paidforby, yes please open a new issue as this needs to be addressed. I just tried a quick test by removing Lora. from that function call but it complains about calls to member functions without object.... So yeah, start a new issue and will discuss getting this fixed.

Thanks Grant!