Bad Data/dropped packets LoRa packets using TTGO board with Lora32 + OLED

Hello,

I am struggling with some random missed or dropped packets with in my Lora code.

Board that I am using
Link

my project is

-Remotely monitor Temp, pressure, humidity, report to the receiver board.
-Receiver board- receives data and creates web page and posts Data
-OLED display-displays data after every reading
-The project is based on this tutorial.
Tutorial

Issues
-The code works and I can send and receive data most of the time
-Screen gets locked up on a old reading, when I reset the board it updates to latest packets sent.
-Randomly packets come through garbled as weird symbols on my serial monitor, this tends to result in the OLED and web server no updating or showing a garbled message. Sometimes this clears when the next a packet is sent, sometimes it is not.

Attempted so far
-I have made the OLED reset every so often- did not fix issue
-I have tried to implement code from the site below to deal with bad/missed/dropped packets
-code
-This issues seems to have made it worse and I cannot figure out where the code is getting hung up, as it seems it should work to do a oneway filter.

Any help is greatly appreciated. Please see both sender and receiver code attached.

Receiver


/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-lora-sensor-web-server/


  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

// Import Wi-Fi library
#include <WiFi.h>
#include "ESPAsyncWebServer.h"

#include <SPIFFS.h>

//Libraries for LoRa
#include <SPI.h>
#include <LoRa.h>

//Libraries for OLED Display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Libraries to get time from NTP Server
#include <NTPClient.h>
#include <WiFiUdp.h>

//define the pins used by the LoRa transceiver module
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26

//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 915E6

//OLED pins
#define OLED_SDA 4
#define OLED_SCL 15 
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define maxPacketSize 45
#define minPacketSize 20

bool validPackage = true;

// Replace with your network credentials
const char* ssid     = "SSID";
const char* password = "Password";

// globals:
// t_minutes_LastUpdate: t in minutes since system start
//                       as moment of last good received package
unsigned long t_minutes_LastUpdate = 0;

// help flag denotes that 1st packet had been received
bool flag1stReceived = false;

bool SisNumeric(String s) { // never negative values here
  // check if s is an valid integer
  for (int i = 0; i < s.length(); i++) {
    if (!isDigit(s[i])) {
      return false,  Serial.println("BAD Numeric PACKET");
    }
  }
  return true, Serial.println("GOOD Numeric PACKET");
}

bool SisFloat(String s) {  // also negative floats possible
  // check if s is an valid float number
  bool flagDot = false;

  for (int i = 0; i < s.length(); i++) {
    if (!isDigit(s[i])) {            
      if (s[i] != '-' || i > 0) {
        if (s[i] == '.' && i > 0 && !flagDot) {
          flagDot = true;
        } else {
          return false,  Serial.print("BAD float PACKET"); 
        }
      }        
    }
  }
  return true, Serial.println("GOOD FLOAT PACKET");
}

// oled reset timer
const unsigned long OledResetDelay = 60000;
unsigned long OledResetTimer = 0;

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP); 

// Variables to save date and time
String formattedDate;
String day;
String hour;
String timestamp;


// Initialize variables to get and save LoRa data
int rssi;
String loRaMessage;
String bootCount;
String temperature;
String humidity;
String pressure;
String readingID;

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

// Replaces placeholder with DHT values
String processor(const String& var){
  Serial.println(var);
  if(var == "TEMPERATURE"){
    return temperature;
  }
  else if(var == "HUMIDITY"){
    return humidity;
  }
  else if(var == "PRESSURE"){
    return pressure;
  }
  else if(var == "TIMESTAMP"){
    return timestamp;
  }
  else if (var == "RSSI"){
    return String(rssi);
  }
  else if (var == "BOOTCOUNT") {
    return bootCount;
  }
    else if (var == "READINGID") {
    return readingID;
  }
    return String();
}

//Initialize OLED display
void startOLED(){
  //reset OLED display via software
  pinMode(OLED_RST, OUTPUT);
  digitalWrite(OLED_RST, LOW);
  delay(20);
  digitalWrite(OLED_RST, HIGH);

  //initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("LORA SENDER");
}

//Initialize LoRa module
void startLoRA(){
  int counter;
  //SPI LoRa pins
  SPI.begin(SCK, MISO, MOSI, SS);
  //setup LoRa transceiver module
  LoRa.setPins(SS, RST, DIO0);

  while (!LoRa.begin(BAND) && counter < 10) {
    Serial.print(".");
    counter++;
    delay(500);
  }
  if (counter == 10) {
    // Increment readingID on every new reading
    Serial.println("Starting LoRa failed!"); 
  }
  Serial.println("LoRa Initialization OK!");
  display.setCursor(0,10);
  display.clearDisplay();
  display.print("LoRa Initializing OK!");
  display.display();
  delay(2000);
}

void connectWiFi(){
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
// Print local Ip address and start web server
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

// Read LoRa packet and get the sensor readings
void getLoRaData() {
  Serial.print("Lora packet received: ");
  // Read packet
  while (LoRa.available()) {
    String LoRaData = LoRa.readString();
    // LoRaData format: bootCount/temperature&humidity#pressure$readingID
    // String example: 1/27.43&654#95.34
     Serial.print(LoRaData); 
    
    // Get readingID, temperature and soil moisture
    int pos1 = LoRaData.indexOf('/');
    int pos2 = LoRaData.indexOf('&');
    int pos3 = LoRaData.indexOf('#');
    int pos4 = LoRaData.indexOf('$');

     if ( pos1 == 0 || pos2 == 0 || pos3 == 0 || pos4 == 0 ||
                                         LoRaData.length() > maxPacketSize )
    { validPackage = false, Serial.println("PACKAGE TOO LONG"); }
    else if ( pos1 >= pos2 || pos2 >= pos3 || pos3 >= pos4 ||
                                         LoRaData.length() < minPacketSize )

    { validPackage = false, Serial.println("PACKAGE TOO LONG");  }

    String bootCount = LoRaData.substring(0, pos1);
    String temperature = LoRaData.substring(pos1+1, pos2);
    String humidity = LoRaData.substring(pos2+1, pos3);
    String pressure = LoRaData.substring(pos3+1, pos4); 
    String readingID = LoRaData.substring(pos4+1, LoRaData.length()); 

if (validPackage) {      
   validPackage = false;  
   // assume
   if (SisNumeric(bootCount)) 
          Serial.println("GOOD BOOT");
      if (SisFloat(temperature))
          Serial.println("GOOD TEMP"); 
       if (SisFloat(humidity))
          Serial.println("GOOD HUMD"); 
         if (SisFloat(pressure))
         Serial.println("GOOD PRESSURE"); 
          if (SisNumeric(readingID))
           validPackage = true; 
                                        
 }


   //  if !validPackage this package will be rejected     //  (not processed, so another missing sample)

if (validPackage) {
  Serial.println("VALID PACKAGE is GOOD!");
  // Print local IP address and start web server
  display.clearDisplay();
  display.setCursor(0,0);
  //display.print("Access web server at: ");
  //display.setCursor(0,30);
  display.print(WiFi.localIP());
  display.setCursor(0,10);
  display.print("READINGS");
  display.setCursor(72,10);
  display.print(bootCount);
  display.setCursor(0,20);
  display.print("Temperature:");
  display.setCursor(72,20);
  display.print(temperature+"F");
  display.setCursor(0,30);
  display.print("Humidity:");
  display.setCursor(54,30);
  display.print(humidity+"%");
  display.setCursor(0,40);
  display.print("Pressure:");
  display.setCursor(54,40);
  display.print(pressure+"Pa");
  display.setCursor(0,50);
  display.print("# of readings");
  display.setCursor(80,50);
  display.print(readingID);
  display.display();
  
  }
  // Get RSSI
  rssi = LoRa.packetRssi();
  Serial.print(" with RSSI ");    
  Serial.println(rssi);
  // print bootcount
  Serial.println("The boot Count is #" + bootCount);

  }
   // insert this at end of getLoRaData()
t_minutes_LastUpdate = millis() / 60000.;
Serial.println("lastUpdate  #" + String(t_minutes_LastUpdate));
// Note(bug!): overflow within 49 days!
flag1stReceived = true; 
delay(500);


// check if validPackage was bad
if (!validPackage){
  Serial.println ("VALID PACKAGE IS BAD");
}
}


void OledReset(){
  if (millis() - OledResetTimer > OledResetDelay) {
//// Reset OLED incase it got hung up
    pinMode(OLED_RST,OUTPUT); 
    digitalWrite(OLED_RST, LOW); 
    delay(20); 
    digitalWrite(OLED_RST, HIGH); // while OLED is running, must set GPIO16 in high
    //display.setCursor(0, 10);
    //display.print("Reset");
    //display.setCursor(0, 24);
    //display.print("OLED...");
    //display.display(); 
    Serial.println("rest OLED");
    delay(600); 
    display.clearDisplay();
    OledResetTimer = millis();
 
  //initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("reset");    
 }
}


// Function to get date and time from NTPClient
void getTimeStamp() {
  while(!timeClient.update()) {
    timeClient.forceUpdate();
  }
  // The formattedDate comes with the following format:
  // 2018-05-28T16:00:13Z
  // We need to extract date and time
  formattedDate = timeClient.getFormattedDate();
  //Serial.println(formattedDate);

  // Extract date
  int splitT = formattedDate.indexOf("T");
  day = formattedDate.substring(0, splitT);
  Serial.println(day);
  // Extract time
  hour = formattedDate.substring(splitT+1, formattedDate.length()-1);
  Serial.println(hour);
  timestamp = day + " " + hour;
}

//void displayReading() {
 //}

void setup() { 
  // Initialize Serial Monitor
  Serial.begin(115200);
  startOLED();
  startLoRA();
  connectWiFi();
  
  if(!SPIFFS.begin(true)){
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }
  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/index.html", String(), false, processor);
  });
  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", temperature.c_str());
  });
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", humidity.c_str());
  });
  server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", pressure.c_str());
  });
  server.on("/timestamp", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", timestamp.c_str());
  });
  server.on("/bootCount", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", bootCount.c_str());
  });
  server.on("/rssi", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(rssi).c_str());
  });
  server.on("/winter", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/winter.jpg", "image/jpg");
  });
  // Start server
  server.begin();
  
  // Initialize a NTPClient to get time
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(-14400);
  
}

void loop() {
  // Check if there are LoRa packets available
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    bool processPackage = true; // local flag - default true
   if (flag1stReceived) { //this is to prevent small problem at startup
     long unsigned t_minutes_now = millis() / 60000.; 
     if ((t_minutes_now - t_minutes_LastUpdate) <= .5) { 
       // Ignore! It's a repeat of same package  
       // already received and processed
       processPackage = false, Serial.println("REJECTED PACKET"); 
  
     }
     Serial.println("T Minutes now  #" + String(t_minutes_now));
   }

  if (processPackage) {
    Serial.println("Getting Lora...");
    getLoRaData();
    getTimeStamp();
//    logSDCard();
  }
   // getLoRaData();
   // getTimeStamp();
  
}
 //OledReset();
}

Sender



/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-lora-sensor-web-server/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

//Libraries for LoRa
#include <SPI.h>
#include <LoRa.h>

//Libraries for OLED Display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//Libraries for BME280
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  1200/* Time ESP32 will go to sleep (in seconds) 5mins */

RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR int readingID = 0;

//define the pins used by the LoRa transceiver module
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26

//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 915E6

//OLED pins
#define OLED_SDA 4
#define OLED_SCL 15 
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

//BME280 definition
#define SDA 21
#define SCL 13

// conCountRepeat: number of repeated sending of every package. 
//   undefine or set to 0 to disable repeated sending packages
#define conCountRepeat 3   // 0 => no repeat
#define conWaitRepeat 3000 // wait 3 seconds before next repeat

TwoWire I2Cone = TwoWire(1);
Adafruit_BME280 bme;

//packet counter
//int readingID = 0;   // Taken care of above


int counter = 0;
String LoRaMessage = "";

float temperature = 0;
float humidity = 0;
float pressure = 0;


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

//Initialize OLED display
void startOLED(){
  //reset OLED display via software
  pinMode(OLED_RST, OUTPUT);
  digitalWrite(OLED_RST, LOW);
  delay(20);
  digitalWrite(OLED_RST, LOW);  //turned to Low to shut of OLED while in the bee. Don't need it displaying if its covered.

//initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("LORA SENDER");
  /*delay(20);
  display.clearDisplay();
  delay(10);
  display.print("GOING DARK");
  delay(20);
  digitalWrite(OLED_RST, LOW);
  */
}

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

//Initialize LoRa module
void startLoRA(){
  //SPI LoRa pins
  SPI.begin(SCK, MISO, MOSI, SS);
  //setup LoRa transceiver module
  LoRa.setPins(SS, RST, DIO0);

  while (!LoRa.begin(BAND) && counter < 10) {
    Serial.print(".");
    counter++;
    delay(500);
  }
    if (counter == 10) {
    //Increment readingID on every new reading
    readingID++;
    Serial.println("Starting LoRa failed!"); 
  }
  Serial.println("LoRa Initialization OK!");
  display.setCursor(0,10);
  display.clearDisplay();
  display.print("LoRa Initializing OK!");
  display.display();
  delay(2000);
}

void startBME(){
  I2Cone.begin(SDA, SCL, 100000); 
  bool status1 = bme.begin(0x76, &I2Cone);  
  if (!status1) {
    Serial.println("Could not find a valid BME280_1 sensor, check wiring!");
    while (1);
  }
}

void getReadings(){
  temperature = (bme.readTemperature())*1.8+32;
  humidity = bme.readHumidity();
  pressure = bme.readPressure() / 100.0F;
}

void sendReadings() {
  LoRaMessage = String(bootCount) + "/" + String(temperature) + "&" + String(humidity) + "#" + String(pressure) + "$" + String(readingID);
  //Send LoRa packet to receiver
  LoRa.beginPacket();
  LoRa.print(LoRaMessage);
  LoRa.endPacket();
  /*display.clearDisplay();
  display.setCursor(0,0);
  display.setTextSize(1);
  display.print("LoRa packet sent!");
  display.setCursor(0,20);
  display.print("Temperature:");
  display.setCursor(72,20);
  display.print(temperature);
  display.setCursor(0,30);
  display.print("Humidity:");
  display.setCursor(54,30);
  display.print(humidity);
  display.setCursor(0,40);
  display.print("Pressure:");
  display.setCursor(54,40);
  display.print(pressure);
  display.setCursor(0,50);
  display.print("Reading #:");
  display.setCursor(66,50);
  display.print(bootCount);
  Serial.print("Sending packet: ");
  Serial.println(readingID);
  display.display();
  */
  readingID++;
}

void setup() {
  //initialize Serial Monitor
  Serial.begin(115200);

  // Increment boot number and print it every boot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  
  ++readingID;
  Serial.println("Reading #: " + String(readingID));
  startOLED();
  startBME();
  startLoRA();

//Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up every 5 seconds
  */
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
  " Seconds");

  Serial.println("Boot number: " + String(bootCount));
  startOLED();
  startBME();
  startLoRA();

  getReadings();
  sendReadings();
  
     #if (conCountRepeat > 0)
  for (int i = 1; i <= conCountRepeat; i++) {
    delay(conWaitRepeat);
    sendReadings();   // or repeatSendReadings(); see Note
  }
  #endif
  

/*
  Now that we have setup a wake cause and if needed setup the
  peripherals state in deep sleep, we can now start going to
  deep sleep.
  In the case that no wake up sources were provided but deep
  sleep was started, it will sleep forever unless hardware
  reset occurs.
  */
  Serial.println("Going to sleep now");
  delay(1000);
  Serial.flush(); 
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}
void loop() {
}

Sender


/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-lora-sensor-web-server/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

//Libraries for LoRa
#include <SPI.h>
#include <LoRa.h>

//Libraries for OLED Display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//Libraries for BME280
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  1200/* Time ESP32 will go to sleep (in seconds) 5mins */

RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR int readingID = 0;

//define the pins used by the LoRa transceiver module
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26

//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 915E6

//OLED pins
#define OLED_SDA 4
#define OLED_SCL 15 
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

//BME280 definition
#define SDA 21
#define SCL 13

// conCountRepeat: number of repeated sending of every package. 
//   undefine or set to 0 to disable repeated sending packages
#define conCountRepeat 3   // 0 => no repeat
#define conWaitRepeat 3000 // wait 3 seconds before next repeat

TwoWire I2Cone = TwoWire(1);
Adafruit_BME280 bme;

//packet counter
//int readingID = 0;   // Taken care of above


int counter = 0;
String LoRaMessage = "";

float temperature = 0;
float humidity = 0;
float pressure = 0;


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

//Initialize OLED display
void startOLED(){
  //reset OLED display via software
  pinMode(OLED_RST, OUTPUT);
  digitalWrite(OLED_RST, LOW);
  delay(20);
  digitalWrite(OLED_RST, LOW);  //turned to Low to shut of OLED while in the bee. Don't need it displaying if its covered.

//initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("LORA SENDER");
  /*delay(20);
  display.clearDisplay();
  delay(10);
  display.print("GOING DARK");
  delay(20);
  digitalWrite(OLED_RST, LOW);
  */
}

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

//Initialize LoRa module
void startLoRA(){
  //SPI LoRa pins
  SPI.begin(SCK, MISO, MOSI, SS);
  //setup LoRa transceiver module
  LoRa.setPins(SS, RST, DIO0);

  while (!LoRa.begin(BAND) && counter < 10) {
    Serial.print(".");
    counter++;
    delay(500);
  }
    if (counter == 10) {
    //Increment readingID on every new reading
    readingID++;
    Serial.println("Starting LoRa failed!"); 
  }
  Serial.println("LoRa Initialization OK!");
  display.setCursor(0,10);
  display.clearDisplay();
  display.print("LoRa Initializing OK!");
  display.display();
  delay(2000);
}

void startBME(){
  I2Cone.begin(SDA, SCL, 100000); 
  bool status1 = bme.begin(0x76, &I2Cone);  
  if (!status1) {
    Serial.println("Could not find a valid BME280_1 sensor, check wiring!");
    while (1);
  }
}

void getReadings(){
  temperature = (bme.readTemperature())*1.8+32;
  humidity = bme.readHumidity();
  pressure = bme.readPressure() / 100.0F;
}

void sendReadings() {
  LoRaMessage = String(bootCount) + "/" + String(temperature) + "&" + String(humidity) + "#" + String(pressure) + "$" + String(readingID);
  //Send LoRa packet to receiver
  LoRa.beginPacket();
  LoRa.print(LoRaMessage);
  LoRa.endPacket();
  /*display.clearDisplay();
  display.setCursor(0,0);
  display.setTextSize(1);
  display.print("LoRa packet sent!");
  display.setCursor(0,20);
  display.print("Temperature:");
  display.setCursor(72,20);
  display.print(temperature);
  display.setCursor(0,30);
  display.print("Humidity:");
  display.setCursor(54,30);
  display.print(humidity);
  display.setCursor(0,40);
  display.print("Pressure:");
  display.setCursor(54,40);
  display.print(pressure);
  display.setCursor(0,50);
  display.print("Reading #:");
  display.setCursor(66,50);
  display.print(bootCount);
  Serial.print("Sending packet: ");
  Serial.println(readingID);
  display.display();
  */
  readingID++;
}

void setup() {
  //initialize Serial Monitor
  Serial.begin(115200);

  // Increment boot number and print it every boot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  
  ++readingID;
  Serial.println("Reading #: " + String(readingID));
  startOLED();
  startBME();
  startLoRA();

//Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up every 5 seconds
  */
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
  " Seconds");

  Serial.println("Boot number: " + String(bootCount));
  startOLED();
  startBME();
  startLoRA();

  getReadings();
  sendReadings();
  
     #if (conCountRepeat > 0)
  for (int i = 1; i <= conCountRepeat; i++) {
    delay(conWaitRepeat);
    sendReadings();   // or repeatSendReadings(); see Note
  }
  #endif
  

/*
  Now that we have setup a wake cause and if needed setup the
  peripherals state in deep sleep, we can now start going to
  deep sleep.
  In the case that no wake up sources were provided but deep
  sleep was started, it will sleep forever unless hardware
  reset occurs.
  */
  Serial.println("Going to sleep now");
  delay(1000);
  Serial.flush(); 
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}
void loop() {
}

Dump the display and sensor stuff, for now.

If you use the simple examples in the LoRa library you are using, do your modules send and receive test LoRa packets without error ?

-I set up the LoRa simple examples and ran them. I ran it for about 7,500 packets and of those there was about 5 bad packets.

  • The code seem to be able to recover after a bad packet was sent which is not always the case with my code.
    -My code typically locks up after 30-40 packets, but that is not always the norm. It can be all over the place.