RX Timeout LoRa

Hi
my LoRa receiver reports IRQ_RX_TIMEOUT in function: packet_is_Error()

From serial monitor:

Elapsed time: 10944.00 s
RXTimeout

I must admit that the code is from the libraries example code and I do not full understand what happens in the if statement. (code: Stuart Robinson)

Can anybody enlighten me why I get this timeout?

Over all I get my correct LoRa packages but I assume that this timeout is part of the code for a reason.

I use library:

SPI.h
#include <SX127XLT.h>                            // include the appropriate library   
SX127XLT LT;                                     // create a library class instance called LT for LoRa

In void loop:

 if (RXPacketL == 0)  {                                            //if the LT.receive() function detects an error, RXpacketL is 0{
    packet_is_Error();
  }
  else {
    packet_is_OK();
  }

Function:

void packet_is_Error()
{
  uint16_t IRQStatus;
  IRQStatus = LT.readIrqStatus();                   //read the LoRa device IRQ status register
  printElapsedTime();                               //print elapsed time to Serial Monitor
  if (IRQStatus & IRQ_RX_TIMEOUT)                   //check for an RX timeout
  {
    Serial.println(F(" RXTimeout"));
  }
  else
  {
    errors++;
    Serial.print(F(" Packet Error Error Error Error Error Error Error Error Error Error Error "));
    Serial.print(F(" RSSI(dBm):      "));    Serial.println(PacketRSSI);
    Serial.print(F(" SNR(dB):        "));    Serial.println(PacketSNR);
    Serial.print(F(" Length:         "));    Serial.println(LT.readRXPacketL());               //get the device packet length
    Serial.print(F(" Packets:        "));    Serial.println(RXpacketCount);
    Serial.print(F(" Errors:         "));    Serial.println(errors);
    Serial.print(F(" IRQreg:         "));    Serial.print(IRQStatus, HEX);
    LT.printIrqStatus();                            //print the names of the IRQ registers set
  }
}

If nessesary I can provide all code, but hope that this message is enough to give some valid info.

Please check if your LoRa module is configured with the correct parameters such as frequency, spreading factor, and bandwidth, matching those of the transmitter.

Provide all the code !

That LoRa library has a configurable timeout, which you can choose to use or not.

Its use is explained in the documentation.

Hi

here is big part of main code and functions:

// %%%%%%%%%%%%%%%%%%%%%%%%    VIKTIGE INNSTILLINGER    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#define sWrite        1    // 1 skriver ut til serial, 0 skriver minimalt ut til serial.
int mottagerVersjon = 53;
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#include <WiFi.h>
#include <PubSubClient.h>                        // MQTT
#include <SPI.h>                                 // the lora device is SPI based so load the SPI library
#include <SX127XLT.h>                            // include the appropriate library   
#include "settings.h"                            // include the setiings file, frequencies, LoRa settings etc
SX127XLT LT;                                     // create a library class instance called LT for LoRa
uint32_t RXpacketCount;
uint32_t errors;
uint8_t RXBUFFER[RXBUFFER_SIZE];                 // create the buffer that received packets are copied into
uint8_t RXPacketL;                               // stores length of packet received
int16_t PacketRSSI;                              // stores RSSI of received packet
int8_t PacketSNR;                                // stores signal to noise ratio (SNR) of received packet

#include <Adafruit_GFX.h>                        // Libraries for OLED display
#include <Adafruit_SSD1306.h>
#include <Preferences.h>                         // for minnehåndtering
Preferences preferences;                         // Global definisjon
WiFiClient espClient;
PubSubClient client(espClient);

#if sWrite == 1                       // 1: skriver til serial, 0: skriver ikke til serial
#define sp(x)   Serial.print(x)       // Serial.print   definert som sp
#define spln(x) Serial.println(x)     // Serial.println definert som spln
#else
#define sp(x)
#define spln(x)
#endif
                              //Variabler på sender- og mottagersiden
float  vekt                 = 0;    
int    pakkeNr              = 0;
float  BStempKube           = 0;
float  BStempUte            = 0;
float  DHTtempKube          = 0;
float  DHTfuktKube          = 0;
int    alarmValue           = 0;
int    kubeNr               = 0;
float  volt                 = 0;
int    senderVersjonNr      = 0;
                              // Varabler på mottagersiden
int    signalstyrke         = 0;                   
String info                 = "x";                  // for OLED M betyr les fra minne, :) er en ny pakke
int    nesteForrige         = 0;                    // variabel for å vise ny pakke, minne neste og forrige kube på OLED
int    retryMQTT            = 0;                    // Declare and initialize the retryMQTT connection variable
int    maxRetryMQTT         = 10;
const char* mqtt_username   = "x";           // MQTT username virker 2023.07.05
const char* mqtt_password   = "y";            // MQTT password virker 2023.07.05
const char* mqtt_clientID   = "z";              // MQTT client ID, må være unikt pr IoT
String MQTTstatus           = "_";                  // For å skrive til serial at kobling til HA er OK

//******************* sett opp ssid2 til et nett fra mobiltelefon """""""""
const char* ssid1           = "";               // WiFi der mottager skal stå fast
const char* password1       = "";
const char* ssid2           = "";                  // ekstra ved problemer, typisk mobilpassord
const char* password2       = "";


// LoRa receive payload
struct __attribute__((packed)) Payload {  // denne må være identisk på sendersiden
  float vekt;
  int   pakkeNr;
  float BStempKube;
  float BStempUte;
  float DHTtempKube;
  float DHTfuktKube;
  int   alarmValue;
  int   kubeNr;
  float volt;
  int   senderVersjonNr;
};

// create a character arrays to store the string to mqtt, vil gjenbrukes for de ulike kubene nr 1,2 3 etc
char vektMsg[10];
char BStempKubeMsg[10];
char BStempUteMsg[10];
char DHTtempKubeMsg[10];
char DHTfuktKubeMsg[10];
char alarmValueMsg[10];
char kubeNrMsg[10];
char pakkeNrMsg[10];
char voltMsg[10];
char senderVersjonNrMsg[10];
char signalstyrkeMsg[10];   // kun på mottager side

//Prototype functions.
void oledVelkommen();
void connectToWiFi();
void lesMinne();
void skrivTilOled();

//OLED pins LoRa TTGO
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST 23
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);

// ########################################   VOID SETP   #####################
void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid1, password1);
  oledVelkommen();  //velkomstskjerm
  client.setServer("1xx", 1883);    // MQTT server xx riktig ift mqtt mottak

  //  loraSetup();
  SPI.begin();
  //SPI beginTranscation is normally part of library routines, but if it is disabled in the library
  //a single instance is needed here, so uncomment the program line below
  //SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));

  //setup hardware pins used by device, then check if device is found
  if (LT.begin(NSS, NRESET, DIO0, DIO1, DIO2, LORA_DEVICE))
  {
    Serial.print(F("LoRa mottager HiveMon, v ")); Serial.println(mottagerVersjon);
  }
  else
  {
    Serial.println(F("LoRa feila. Sjekk tilkoblingsdata."));
  }

  //The function call list below shows the complete setup for the LoRa device using the information defined in the
  //Settings.h file.
  //The 'Setup Lora device' list below can be replaced with a single function call;
  //LT.setupLoRa(Frequency, Offset, SpreadingFactor, Bandwidth, CodeRate, Optimisation);

  //***************************************************************************************************
  //Setup Lora device
  //***************************************************************************************************
  LT.setMode(MODE_STDBY_RC);                              //got to standby mode to configure device
  LT.setPacketType(PACKET_TYPE_LORA);                     //set for LoRa transmissions
  LT.setRfFrequency(Frequency, Offset);                   //set the operating frequency
  LT.calibrateImage(0);                                   //run calibration after setting frequency
  LT.setModulationParams(SpreadingFactor, Bandwidth, CodeRate, LDRO_AUTO);  //set LoRa modem parameters
  LT.setBufferBaseAddress(0x00, 0x00);                    //where in the SX buffer packets start, TX and RX
  LT.setPacketParams(8, LORA_PACKET_VARIABLE_LENGTH, 255, LORA_CRC_ON, LORA_IQ_NORMAL);  //set packet parameters
  LT.setSyncWord(LORA_MAC_PRIVATE_SYNCWORD);              //syncword, LORA_MAC_PRIVATE_SYNCWORD = 0x12, or LORA_MAC_PUBLIC_SYNCWORD = 0x34
  LT.setHighSensitivity();                                //set for highest sensitivity at expense of slightly higher LNA current
  LT.setDioIrqParams(IRQ_RADIO_ALL, IRQ_RX_DONE, 0, 0);   //set for IRQ on RX done
  //***************************************************************************************************
  Serial.println();
  LT.printModemSettings();                                     //reads and prints the configured LoRa settings, useful check
  Serial.println("f");
  LT.printOperatingSettings();                                 //reads and prints the configured operting settings, useful check
  Serial.println();
  Serial.println();
  LT.printRegisters(0x00, 0x4F);                               //print contents of device registers, normally 0x00 to 0x4F
  Serial.println();
  Serial.println();

  Serial.print(F("Receiver ready - RXBUFFER_SIZE "));
  Serial.println(RXBUFFER_SIZE);
  Serial.println();


  // Try to connect to the first of 2 Wi-Fi network within 10 seconds
  connectToWiFi(); // Prøver å koble til Wi-Fi ved oppstart
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {                         // Check if already connected to WiFi, om ikke koble til på nytt
    connectToWiFi();
    Serial.println("Koblet til WiFi på nytt!");
  }
  if (!client.connected()) {                                   // dersom frakoblet så kobler til på nytt
    delay(100);                                                // sjekker om delay gjør MQTT mer stabil
    while (!client.connected() && retryMQTT < maxRetryMQTT) {
      Serial.println("Kobler til MQTT (på nytt) ...");
      if (client.connect(mqtt_clientID, mqtt_username, mqtt_password)) {
        Serial.print("retryMQTT (a)= "); Serial.println(retryMQTT);            // teller
        Serial.println("MQTT koblet til HA!  IP 192.168.0.60:1883, web :8123");
        delay(1000);
        retryMQTT = 0;                                         // Reset the retry count if the connection is successful
        MQTTstatus = "Koblet til HA";
      } else {
        Serial.print("retryMQTT (b)= "); Serial.println(retryMQTT);
        Serial.print("Feila å koble til MQTT, Return Code = ");
        Serial.println(client.state());
        delay(500);
        retryMQTT++;
        MQTTstatus = "Ikke koblet til HA, RC = " + client.state();
        if (retryMQTT == maxRetryMQTT) {
          spln("ESP restarter");
          delay(5000);
          ESP.restart(); // ###################### behold denne muligheten  se på versjon tidligere
        }
      }
    }
  }
  client.loop();                // MQTT loop
  RXPacketL  = LT.receive(RXBUFFER, RXBUFFER_SIZE, 60000, WAIT_RX); //wait for a packet to arrive with 60seconds (60000mS) timeout
  PacketRSSI = LT.readPacketRSSI();                                 //read the recived RSSI value
  PacketSNR  = LT.readPacketSNR();                                  //read the received SNR value
  if (RXPacketL == 0)  {                                            //if the LT.receive() function detects an error, RXpacketL is 0{
    packet_is_Error();
  }
  else {
    packet_is_OK();
  }
}                            // End void loop

Settings.h

//*******  Setup hardware pin definitions here ! ***************
//These are the pin definitions for one of my own boards, the Easy Pro Mini,
//be sure to change the definitions to match your own setup. Some pins such as DIO1,
//DIO2, BUZZER may not be in used by this sketch so they do not need to be
//connected and should be set to -1.

#define NSS 18                                  //select pin on LoRa device
#define NRESET 14                               //reset pin on LoRa device
#define LED1 -1                                 //on board LED, high for on
#define DIO0 26                                 //DIO0 pin on LoRa device, used for RX and TX done 
#define DIO1 -1                                 //DIO1 pin on LoRa device, normally not used so set to -1 
#define DIO2 -1                                 //DIO2 pin on LoRa device, normally not used so set to -1
#define BUZZER -1                               //pin for buzzer, on when logic high
#define LORA_DEVICE DEVICE_SX1278               //we need to define the device we are using

//*******  Setup LoRa Parameters Here ! ***************
//LoRa Modem Parameters
const uint32_t Frequency = 868000000;           //frequency of transmissions in hertz
const uint32_t Offset = 0;                      //offset frequency for calibration purposes
const uint8_t Bandwidth = LORA_BW_125;          //LoRa bandwidth
const uint8_t SpreadingFactor = LORA_SF7;       //LoRa spreading factor
const uint8_t CodeRate = LORA_CR_4_5;           //LoRa coding rate
const uint8_t Optimisation = LDRO_AUTO;         //low data rate optimisation setting, normally set to auto
const int8_t TXpower = 2;                       //LoRa transmit power in dBm
const uint16_t packet_delay = 1000;             //mS delay between packets
#define RXBUFFER_SIZE  50 //32                        //RX buffer size  


/*******************************************************************************************************
  Programs for Arduino - Copyright of the author Stuart Robinson - 02/03/20

  This program is supplied as is, it is up to the user of the program to decide if the program is
  suitable for the intended purpose and free from errors.
*******************************************************************************************************/

CRC_functions and other functions

void packet_is_OK() {
  uint16_t IRQStatus, localCRC;
  IRQStatus = LT.readIrqStatus();
  RXpacketCount++;

  // Extract payload without modifying its byte order
  Payload payload;
  memcpy(&payload, RXBUFFER, sizeof(Payload));

  //Serial.print(F("Received data: "));
  //printReceivedPayload(payload);  // Add this line to print raw bytes

  spln();
  localCRC = LT.CRCCCITT(reinterpret_cast<uint8_t*>(&payload), sizeof(Payload), 0xFFFF);
  sp(F("CRC:     "));  Serial.println(localCRC, HEX);    // dette virker ikke sp(localCRC); sp(", "); spln(HEX);
  sp(F("RSSI:    "));  sp(PacketRSSI); spln(F(" dBm"));
  sp(F("SNR:     "));  spln(PacketSNR);
  sp(F("Length:  "));  spln(RXPacketL);
  sp(F("Packets: "));  spln(RXpacketCount);
  sp(F("Errors:  "));  spln(errors);
  sp(F("IRQreg:  "));  Serial.println(IRQStatus, HEX);
  spln("---------------------------------------------");

  if (payload.vekt > 150) {                                            // feilhåndtering om vekt blir gærn, holder OLED ryddig:
    payload.vekt = -99;
  }
  if (payload.alarmValue == 1) {                                       // sjekker om alarm
    Serial.println("Alarm!!! ");                                       // skriver til OLED
    display.clearDisplay();
    display.setTextColor(WHITE);
    display.setTextSize(2);
    display.setCursor(20, 1);  display.print("ALARM");                 // 15 fra venstre, 21 fra topp
    display.display();                                                 // selve skrivingen til display fra buffer
    delay(1000);
  }
  else {
    payload.alarmValue = 9;                                            // kan ikke bruke 0 pga HA, sørger for å sende verdi til HA og ikke nan
    Serial.print(F("    alarmValue:      ")); Serial.println(payload.alarmValue);
  }
  // DYNAMISK tildeling av topic string ift kubeNr slik at hver pakke kommer til riktig HA system
  String topicKubeNr   = String(payload.kubeNr);
  String vektTopic            = "bikuber/kube" + topicKubeNr + "/vekt";            // riktig
  String pakkeNrTopic         = "bikuber/kube" + topicKubeNr + "/pakkeNr";
  String BStempKubeTopic      = "bikuber/kube" + topicKubeNr + "/BStempKube";
  String BStempUteTopic       = "bikuber/kube" + topicKubeNr + "/BStempUte";
  String DHTtempKubeTopic     = "bikuber/kube" + topicKubeNr + "/DHTtempKube";
  String DHTfuktKubeTopic     = "bikuber/kube" + topicKubeNr + "/DHTfuktKube";
  String alarmValueTopic      = "bikuber/kube" + topicKubeNr + "/alarmValue";
  String kubeNrTopic          = "bikuber/kube" + topicKubeNr + "/kubeNr";
  String voltTopic            = "bikuber/kube" + topicKubeNr + "/volt";
  String senderVersjonNrTopic = "bikuber/kube" + topicKubeNr + "/senderVersjonNr";
  String signalstyrkeTopic    = "bikuber/kube" + topicKubeNr + "/signalstyrke";

  // Convert payload into Msg strings. PASS PÅ INT VS FLOAT %d vs %f
  snprintf(vektMsg            , 10, " %.1f" , payload.vekt);                     //riktig
  snprintf(pakkeNrMsg         , 10, " %d"   , payload.pakkeNr);
  snprintf(BStempKubeMsg      , 10, " %.1f" , payload.BStempKube);
  snprintf(BStempUteMsg       , 10, " %.1f" , payload.BStempUte);
  snprintf(DHTtempKubeMsg     , 10, " %.1f" , payload.DHTtempKube);
  snprintf(DHTfuktKubeMsg     , 10, " %.lf" , payload.DHTfuktKube);
  snprintf(alarmValueMsg      , 10, " %.d"  , payload.alarmValue);
  snprintf(kubeNrMsg          , 10, " %.d"  , payload.kubeNr);
  snprintf(voltMsg            , 10, " %.1f" , payload.volt);
  snprintf(senderVersjonNrMsg , 10, " %d"   , payload.senderVersjonNr);
  snprintf(signalstyrkeMsg    , 10, " %.d"  , PacketRSSI);

  // Publish message to Home Assistant, OLED and serial, basert på kubeNr
  // sorterer ut data, kubeNr, som er utenfor scope
  client.publish(vektTopic.c_str()           , vektMsg);                         // riktig
  client.publish(pakkeNrTopic.c_str()        , pakkeNrMsg);
  client.publish(BStempKubeTopic.c_str()     , BStempKubeMsg);
  client.publish(BStempUteTopic.c_str()      , BStempUteMsg);
  client.publish(DHTtempKubeTopic.c_str()    , DHTtempKubeMsg);
  client.publish(DHTfuktKubeTopic.c_str()    , DHTfuktKubeMsg);
  client.publish(alarmValueTopic.c_str()     , alarmValueMsg);
  client.publish(kubeNrTopic.c_str()         , kubeNrMsg);
  client.publish(voltTopic.c_str()           , voltMsg);
  client.publish(senderVersjonNrTopic.c_str(), senderVersjonNrMsg);
  client.publish(signalstyrkeTopic.c_str()   , signalstyrkeMsg);

  sp("MQTT publisert til HA path: bikuber/kube" + topicKubeNr + "/" );
  vekt            = payload.vekt;                              // legger payload inn i variablene, burde være unødig da de ligger i myPayload
  pakkeNr         = payload.pakkeNr;
  BStempKube      = payload.BStempKube;
  BStempUte       = payload.BStempUte;
  DHTtempKube     = payload.DHTtempKube;
  DHTfuktKube     = payload.DHTfuktKube;
  alarmValue      = payload.alarmValue;
  kubeNr          = payload.kubeNr;
  volt            = payload.volt;
  senderVersjonNr = payload.senderVersjonNr;
  signalstyrke    = PacketRSSI;

  // Save the values to preferences og namspace pr kubeNr
  String kubeNrStringPut = String(kubeNr);                      // var String(kubeNr);konverterer int kubeNr til å blir en namspace
  preferences.begin   (kubeNrStringPut.c_str(), false);         // namspace er dynamisk: kubeNrString.c_str()  typisk "my-app", her er det "1"
  preferences.putFloat("vekt",            payload.vekt);
  preferences.putInt  ("pakkeNr",         payload.pakkeNr);
  preferences.putFloat("BStempKube",      payload.BStempKube);
  preferences.putFloat("BStempUte",       payload.BStempUte);
  preferences.putFloat("DHTtempKube",     payload.DHTtempKube);
  preferences.putFloat("DHTfuktKube",     payload.DHTfuktKube);
  preferences.putInt  ("alarmValue",      payload.alarmValue);
  preferences.putInt  ("kubeNr",          payload.kubeNr);
  preferences.putFloat("volt",            payload.volt);
  preferences.putInt  ("senderVersjonNr", payload.senderVersjonNr);
  preferences.putInt  ("signalstyrke",    PacketRSSI);
  preferences.end();

  info = ":)";                                                 // for OLED *SMIL* dersom ny pakke
  skrivTilOled(kubeNr);
  skrivTilSerial(kubeNr);
}

// denne er ikke i bruk
void printReceivedPayload(const Payload& payload) {
  Serial.print(F("Raw Bytes: "));
  for (size_t i = 0; i < sizeof(Payload); i++) {
    Serial.print(reinterpret_cast<const uint8_t*>(&payload)[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
  Serial.print(F("    vekt: a           ")); Serial.println(payload.vekt);
  Serial.print(F("    pakkeNr:         ")); Serial.println(payload.pakkeNr);
  Serial.print(F("    BStempKube:      ")); Serial.println(payload.BStempKube);
  Serial.print(F("    BStempUte:       ")); Serial.println(payload.BStempUte);
  Serial.print(F("    DHTtempKube:     ")); Serial.println(payload.DHTtempKube);
  Serial.print(F("    DHTfuktKube:     ")); Serial.println(payload.DHTfuktKube);
  Serial.print(F("    alarmValue:      ")); Serial.println(payload.alarmValue);
  Serial.print(F("    volt:            ")); Serial.println(payload.volt);
  Serial.print(F("    sender-versjon:  ")); Serial.println(payload.senderVersjonNr);
}

void packet_is_Error()
{
  uint16_t IRQStatus;
  IRQStatus = LT.readIrqStatus();                   //read the LoRa device IRQ status register
  printElapsedTime();                               //print elapsed time to Serial Monitor
  if (IRQStatus & IRQ_RX_TIMEOUT)                   //check for an RX timeout
  {
    Serial.println(F(" RXTimeout"));
  }
  else
  {
    errors++;
    Serial.print(F(" Packet Error Error Error Error Error Error Error Error Error Error Error "));
    Serial.print(F(" RSSI(dBm):      "));    Serial.println(PacketRSSI);
    Serial.print(F(" SNR(dB):        "));    Serial.println(PacketSNR);
    Serial.print(F(" Length:         "));    Serial.println(LT.readRXPacketL());               //get the device packet length
    Serial.print(F(" Packets:        "));    Serial.println(RXpacketCount);
    Serial.print(F(" Errors:         "));    Serial.println(errors);
    Serial.print(F(" IRQreg:         "));    Serial.print(IRQStatus, HEX);
    LT.printIrqStatus();                            //print the names of the IRQ registers set
  }
}

void printElapsedTime()
{
  float seconds;
  seconds = millis() / 1000;
  Serial.print(F("Elapsed time: ")); Serial.print(seconds, 2); Serial.println(F(" s"));
}

what LoRa module are you using? give a link to documentation
I tend to use the Sandeep Mistry LorA library for LoRa point-to=point communications with SX127x modules

Hi

I have also used Sandeep, but to enable CRC I went for <SX127XLT.h> and example from Stuart Robinson.

Receiver is liligo oled esp32 v1.6.1 -> SX1276

Sender is AI thinker RA01h

M

You have this code;

RXPacketL = LT.receive(RXBUFFER, RXBUFFER_SIZE, 60000, WAIT_RX); //wait for a packet to arrive with 60seconds (60000mS) timeout

So your code is waiting for 60 seconds for a packet to arrive and if it does not there is a timeout.

Note that the SX128X and SX126X devices (which the library alaso supports) have a native built in timeout function so a software timeout was added to the SX127X part to provide sketch compatibility across the different modules.

1 Like

Ahhh. I only get packages each 15 min....

Maybe this code can be deleted? I receive packages what I need, I use CRC to determine good or bad package.

I try now

You can as the doccumentation makes clear;

"If WAIT_RX is selected then the program will wait for the time-out period (in mS) for a packet to arrive before signalling a timeout, this is a blocking command. To have the receiver wait continuously for a packet set the timeout to 0.

To use the receiver in non-blocking mode set NO_WAIT in which case you will need to check DIO0 (SX127X) or DIO1 (SX126X and SX128X) going high to indicate a packet has arrived.'

Or set the timeout to just more than 15 minutes ............

1 Like

I also struggle with mqtt reconnect:
Kobler til MQTT (på nytt) ... EN: "Connect to MQTT (again)..."

Pleas also take a lock at that :slight_smile:

14:20:38.730 -> MQTT koblet til! IP 192.168.0.60:1883, web :8123 -> states that is connected
14:21:39.731 -> Elapsed time: 1533.00 s
14:21:39.731 -> RXTimeout
14:21:39.867 -> Kobler til MQTT (på nytt) ... -> states that it connects again
14:21:39.867 -> retryMQTT (1)= 0
14:21:39.867 -> MQTT koblet til! IP 192.168.0.60:1883, web :8123

Also realise that by default that library uses automatic CRC checking on packets, which other libraries do not.

If you want additional error checking to prevent rogue packets from other sources being read the library provides transmit and receive functions that automatically add and check on receipt a provided 16 bit network ID and an additional 16 bit CRC on the payload, the chances of then receiving a packet that you did not send are remote indeed.

1 Like

Hi
Thanks!

I did receive packages that messed up my data, im no expert in this lora game so I decided to add CRC (probably then in addition to embedded crc in library)
This changed my "gosht" packages and now I have "only" good packages, before i could get weight like 1 million kg that completely disturbed my graphs:

After CRC:

// Extract payload without modifying its byte order
  Payload payload;
  memcpy(&payload, RXBUFFER, sizeof(Payload));
  localCRC = LT.CRCCCITT(reinterpret_cast<uint8_t*>(&payload), sizeof(Payload), 0xFFFF);
  sp(F("CRC:     "));  Serial.println(localCRC, HEX); 

Thanks, this is for me little foggy, I have used default, and it seems to work. Do you have any input regarding this, is it some place to find good values.

That is lkely the 'phantom packet' problem.

An SX127X can internally generate, maybe 2 or more a hour, 'phantom packets' that appear to have been received. They contain random data.

1 Like

Thanks for info, i have read about phantom pakages, but a bit over my head.
On receiver side after enabling crc i can count "error" packages, typically up to 10 in 24 h

This is my "package" info:

CRC: BA86
RSSI: -61 dBm
SNR: 10
Length: 40
Packets: 81
Errors: 7
IRQreg: 50

The phantoms tend to be long and have an RSSI of circa -110dBm and an SNR of -10dB.

So if the packets are longer than normal or a lot weaker than normal they could well be rubbish packets.

Or just use the reliable packet functions from that library and stop worrying about it.

1 Like

@srnet
interesting reading, looks like my packages are similar to description from Stuart; "Phantom".

I'm not skilled in reading code and libraries. May I ask you to comment my Sender code where I do CRC according to Stuarts library <SX127XLT.h>, is my implementation a "Reliable Packets with LoRa" code?

My code is to monitor a bee hive.

Thanks up front!

sp and spln is macro I can enable/disable Serial.print/ln, for battery saving purpose

Code:

Part of void loop:
======================================================
  Payload myPayload;         // the container for what we want to send over LoRa and store sensor readings into myPayload
  myPayload.vekt             = vekt;
  myPayload.pakkeNr          = pakkeNr;
  myPayload.BStempKube       = BStempKube;
  myPayload.BStempUte        = BStempUte;
  myPayload.DHTtempKube      = DHTtempKube;
  myPayload.DHTfuktKube      = DHTfuktKube;
  myPayload.alarmValue       = alarmValue;
  myPayload.kubeNr           = kubeNr;
  myPayload.volt             = volt;
  myPayload.senderVersjonNr  = senderVersjonNr;

  sp("    TXpower: "); sp(TXpower); spln(F(" dBm "));
  printASCIIPacket(reinterpret_cast<uint8_t*>(&myPayload), sizeof(Payload));
  sp("");
  startmS =  millis();
  if (LT.transmit(reinterpret_cast<uint8_t*>(&myPayload), sizeof(Payload), 10000, TXpower, WAIT_TX)) {
    endmS = millis();
    TXPacketCount++;
    packet_is_OK(myPayload);  // overfører myPayload til function
  } else {
    packet_is_Error();
  }

===================================



void packet_is_OK(Payload functionPayload) {
  uint16_t localCRC;
  localCRC = LT.CRCCCITT(reinterpret_cast<uint8_t*>(&functionPayload), sizeof(Payload), 0xFFFF);
  sp("    Bytes sent:    "); spln(sizeof(Payload));
  sp("    TransmitTime:  "); sp((endmS - startmS)); spln(F(" mS"));
  sp("    PacketsSent:   "); spln(TXPacketCount);
  spln();
  Serial.print("    CRC:               "); Serial.println(localCRC, HEX);                          // skrives alltid ut
  spln();
  spln(F("    Payload sent: "));
  Serial.print("    kubeNr:            "); Serial.println(functionPayload.kubeNr);                 // skrives alltid ut
  Serial.print("    Vekt:              "); Serial.println(functionPayload.vekt);                   // skrives alltid ut
  Serial.print("    PakkeNr:           "); Serial.println(functionPayload.pakkeNr);                // skrives alltid ut
  Serial.print("    Senderversjon:     "); Serial.println(functionPayload.senderVersjonNr);        // skrives alltid ut
  sp("    Pakkenr:           "); spln(functionPayload.pakkeNr);
  sp("    BStempKube:        "); spln(functionPayload.BStempKube);
  sp("    BSStempUte:        "); spln(functionPayload.BStempUte);
  sp("    DHTtempKube:       "); spln(functionPayload.DHTtempKube);
  sp("    DHTfuktKube:       "); spln(functionPayload.DHTfuktKube);
  sp("    Alarm:             "); spln(functionPayload.alarmValue);
  sp("    Batteri V:         "); spln(functionPayload.volt);
  spln();
} 
  

Use the reliable packet functions such as ;

LT.transmitReliable((uint8_t *) &controller1, sizeof(controller1), NetworkID, TXtimeout, TXpower, WAIT_TX);

Which sends the structure controller1 and automatically appends the payload CRC and network ID to the packet which the matching receive function uses to check the packet for validity.

See the examples and document in the \Reliable folder.

Reading code and delving into libraries is a fairly common requiredment if you choose Arduino as a hobby ...................

1 Like

Thanks, I know, I'm still learning, and I have come to that point I understand that I need to go into libraries in a more detailed manner. I'm so lucky to have a son who helps me when I struggle, computer science from NYU, but no LoRa expert. No excuse, but in that way I at least goes step by step. And also so lucky to have a forum with helpful and skilled members, like you :slight_smile:

M

Hi

I did set the timeout to 0, continuously wait, and it fixed the timeout "problem" I had.
Now a new issue has arisen... code stops and wait and void loop is "stuck".

Tried to read about this in library but did not find the answer...

Code for continuously waiting, present code:

RXPacketL  = LT.receive(RXBUFFER, RXBUFFER_SIZE, **0**, WAIT_RX);

But..
in my code I need more than wait for package, I also wait for serial input, this code is not running more that once for each packet, and makes it not work as intended:

  // ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤      if Neste  /  Forrige   ¤¤¤¤¤¤¤¤¤¤¤¤¤
 
  char input = Serial.read();
  if (input == 's') {                                
     info = "M";                                      // for OLED les fra minne
    nesteForrige++;
    lesMinne();
    skrivTilSerial(nesteForrige);
    skrivTilOled(nesteForrige);

  }

  //  if (digitalRead(switchForrigeKube) == LOW) {       // dette skal være knapp forrige
  if (input == 'a') {  // dette skal være knapp neste
    info = "M";                                          // for OLED les fra minne
    nesteForrige--;
    lesMinne();
    skrivTilSerial(nesteForrige);
    skrivTilOled(nesteForrige);
  }

Q:
Is there an option to let code run and listen for packet all the time, and also listen for serial.read (let the void loop() run all time?

My idea is to set timeout to 1 mS, but I dont see that as the best option, but maybe is it?

RXPacketL  = LT.receive(RXBUFFER, RXBUFFER_SIZE, **1**, WAIT_RX);

Any tip for me?