LoRa response too late

Hi there!

I'm currently working on a small demo that is able to control an RGB LED strip from your computer using a LoRa connection. But sadly I ran into an issue, if i send an command from my VB program that is running on the computer, the first ESP32 LoRa board will respond to the command and sends the command to the other ESP32 board using LoRa. Which will then give a reply back to the first ESP32 board. But I get a response back that was supposed to be send 1 command earlier.

Let me explain it real quick. My VB program sends a DEVICE_OK command every 5 seconds to see if the first ESP32 board is available and it will also send that DEVICE_OK command to the second ESP32 board. The second board will then reply with LORA_OK to notify the VB program that the LoRa connection is ready. But then I select a color on my VB program and press set, which will first send the command SET_RED=[a value between 0 and 255]. The first ESP32 board receives that message and sends it to the second board using LoRa. The second ESP32 board receives the command, gets the value and then replies with RED_OK. But for some reason the first ESP32 board receives DEVICE_OK even tho the second ESP32 board should have send RED_OK (I've checked it using the serial monitor and the code that should send RED_OK is triggered). But now comes the weird part. If i make the VB program retry the SET_RED command, the first ESP32 will send it like it should and the second ESP32 board responds how it should and now suddenly the first ESP32 board actually reports RED_OK. So for some reason commands are send one command too late. I have no idea why this happens :confused:

I don't think the VB program is the issue since the serial monitor of the first ESP32 board shows that the command is one command to late. Also the serial monitor shows that the first command it receives using LoRa is just empty (which should have been a LORA_OK command from the second ESP32 board)

I hope that i have made the problem clear enough that i am facing and i really hope somebody can help me, since i have no idea why the arduino code isn't working :frowning:

Link to the Arduino and VB code: LoRa RGB LED controller.rar - Google Drive

Thanks in advance!

ps. the first ESP32 board is the server and it is the "translator" between wifi and LoRa

pps. the first ESP32 board needs to be connected to the same wifi as the computer running the VB program since the VB program and ESP32 board communicate using wifi

If you want people to be able to read your code, please see #7 and #8 here;

http://forum.arduino.cc/index.php/topic,148850.0.html

srnet:
If you want people to be able to read your code, please see #7 and #8 here;

http://forum.arduino.cc/index.php/topic,148850.0.html

I wish I could do it directly, but when I've zipped everything it is over 3MB. So I can't upload it directly. Also I can't post my code inside due to the character limit :confused:

I don't mean to be rude of impatient, but does somebody know what is going wrong with my code? :confused:
I really have no idea and I really want to continue this project

You have to make it easy for people to help.
Few people have visual basic, and nobody is going to install visual basic just to view your project. Copy your code as plain text and post it in a message or series of messages. Draw a picture showing how things are connected.

So this is the server code (the ESP32 that converts the LoRa to Wifi and back for the VB application)

#include <WiFi.h>
#include <Adafruit_SSD1306.h>

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

const char* ssid = "TESTNET";

#define SCK     5    // GPIO5  -- SX1278's SCK
#define MISO    19   // GPIO19 -- SX1278's MISO
#define MOSI    27   // GPIO27 -- SX1278's MOSI
#define SS      18   // GPIO18 -- SX1278's CS
#define RST     14   // GPIO14 -- SX1278's RESET
#define DI0     26   // GPIO26 -- SX1278's IRQ(Interrupt Request)
#define BAND    868E6

String currentLine = "";
String rssi = "RSSI --";
String rssiD;
String packSize = "--";
String packet ;
int msize;

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
WiFiServer wifiServer(8000);

void setup() {

  Serial.begin(115200);

  delay(1000);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3c);

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Connecting to WiFi...");
  display.setCursor(0, 20);
  display.println("SSID:");
  display.setCursor(0, 30);
  display.println(ssid);
  display.display();

  WiFi.begin(ssid);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println("Connected to the WiFi network");
  Serial.println(WiFi.localIP());

  SPI.begin(SCK, MISO, MOSI, SS);
  LoRa.setPins(SS, RST, DI0);
  if (!LoRa.begin(868E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }

  wifiServer.begin();


  //display.flipScreenVertically();
  //display.setFont(ArialMT_Plain_10);

  LoRa.onReceive(cbk);
  LoRa.receive();

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Server IP:");
  display.setCursor(0, 10);
  display.println(WiFi.localIP());
  display.display();
}

void loop() {
  int packetSize = LoRa.parsePacket();
  msize = LoRa.parsePacket();
  if (packetSize) {
    cbk(packetSize);
  }
  delay(10);

  WiFiClient client = wifiServer.available();

  if (client) {

    while (client.connected()) {

      if (client.available()) {
        // read incoming bytes:
        char inChar;

        while (client.available()) {
          delay(3);  //delay to allow buffer to fill
          if (client.available() > 0) {
            char inChar = client.read();  //gets one byte from serial buffer
            currentLine += inChar; //makes the string readString
          }
        }

        Serial.println("VB Command - " + currentLine);
        if (inChar == '\n') {
          currentLine = "";
        }
        if ( currentLine.startsWith("GET_STATUS")) {
          delay(25);
          client.println("DEVICE_OK");
          LoRa.beginPacket();
          LoRa.print("GET_STATUS");
          LoRa.endPacket();
          currentLine = "";
          LoRa.receive();
        } else if ( currentLine.startsWith("SET_RED=")) {
          delay(25);
          LoRa.beginPacket();
          LoRa.print(currentLine);
          LoRa.endPacket();
          currentLine = "";
          LoRa.receive();
        } else if ( currentLine.startsWith("SET_GREEN=")) {
          delay(25);
          LoRa.beginPacket();
          LoRa.print(currentLine);
          LoRa.endPacket();
          currentLine = "";
          LoRa.receive();
        } else if ( currentLine.startsWith("SET_BLUE=")) {
          delay(25);
          LoRa.beginPacket();
          LoRa.print(currentLine);
          LoRa.endPacket();
          currentLine = "";
          LoRa.receive();
        } else if ( currentLine.startsWith("SET_BRIGHT=")) {
          delay(25);
          LoRa.beginPacket();
          LoRa.print(currentLine);
          LoRa.endPacket();
          currentLine = "";
          LoRa.receive();
        }

        Serial.println("LoRa command - " + packet);
        if ( packet.startsWith("LORA_OK")) {
          delay(25);
          client.println("LORA_RSSI=" + rssiD);
          packet = "";
        } else if ( packet.startsWith("RED_OK")) {
          Serial.println("RED_OK");
          delay(25);
          client.println("RED_OK");
          packet = "";
        } else if ( packet.startsWith("GREEN_OK")) {
          Serial.println("GREEN_OK");
          delay(25);
          client.println("GREEN_OK");
          packet = "";
        } else if ( packet.startsWith("BLUE_OK")) {
          Serial.println("BLUE_OK");
          delay(25);
          client.println("BLUE_OK");
          packet = "";
        } else if ( packet.startsWith("BRIGHT_OK")) {
          Serial.println("BRIGHT_OK");
          delay(25);
          client.println("BRIGHT_OK");
          packet = "";
        } else {
          Serial.println("Unknown LoRa Command - " + packet);
        }


      }
    }
    client.stop();
    Serial.println("Client disconnected");
  }
}

void cbk(int packetSize) {
  packet = "";
  packSize = String(packetSize, DEC);
  for (int i = 0; i < packetSize; i++) {
    packet += (char) LoRa.read();
  }
  rssi = "RSSI " + String(LoRa.packetRssi(), DEC) ;
  rssiD = String(LoRa.packetRssi(), DEC);
  //Serial.println("LoRa Data = " + packet);
}

And this is the client code (the ESP32 that receives the LoRa command and sets the LED to that value)

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

//#include <FastLED.h>
#define NUM_LEDS 4 //16
#define LED_PIN 4
#define LED_TYPE    WS2812B
#define COLOR_ORDER RGB
//CRGB leds[NUM_LEDS];

#define SCK     5    // GPIO5  -- SX1278's SCK
#define MISO    19   // GPIO19 -- SX1278's MISO
#define MOSI    27   // GPIO27 -- SX1278's MOSI
#define SS      18   // GPIO18 -- SX1278's CS
#define RST     14   // GPIO14 -- SX1278's RESET
#define DI0     26   // GPIO26 -- SX1278's IRQ(Interrupt Request)
#define BAND    868E6

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
String rssi = "RSSI --";
String packSize = "--";
String packet = "";

char Message;
int msize;
int firstmessage = 0;

int Red;
int Green;
int Blue;
int Bright;

void loraData(){
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,15);
  display.println("Received "+ packSize + " bytes");
  display.setCursor(0,0);
  display.println(rssi);
  display.setCursor(0,30);
  display.println(packet);
  display.display();

  if ( packet.startsWith("GET_STATUS")) {
    Serial.println("LORA_OK");
    delay(25);
    LoRa.beginPacket();
    LoRa.print("LORA_OK");
    LoRa.endPacket();
    if (firstmessage == 0) {
      LoRa.beginPacket();
      LoRa.print("LORA_OK");
      LoRa.endPacket();
      firstmessage = 1;
    }
    packet = "";
  } else if ( packet.startsWith("SET_RED=")) {
    Serial.println("SET_RED");
    packet.remove(0, 8);
    Red = packet.toInt();
    delay(25);
    LoRa.beginPacket();
    LoRa.print("RED_OK");
    LoRa.endPacket();
    packet = "";
  } else if ( packet.startsWith("SET_GREEN=")) {
    Serial.println("SET_GREEN");
    packet.remove(0, 10);
    Green = packet.toInt();
    Serial.println(Green);
    delay(25);
    LoRa.beginPacket();
    LoRa.print("GREEN_OK");
    LoRa.endPacket();
    packet = "";
  } else if ( packet.startsWith("SET_BLUE=")) {
    Serial.println("SET_BLUE");
    packet.remove(0, 9);
    Blue = packet.toInt();
    Serial.println(Blue);
    delay(25);
    LoRa.beginPacket();
    LoRa.print("BLUE_OK");
    LoRa.endPacket();
    packet = "";
  } else if ( packet.startsWith("SET_BRIGHT=")) {
    Serial.println("SET_BRIGHT");
    packet.remove(0, 11);
    Bright = packet.toInt();
    Serial.println(Bright);
    //FastLED.setBrightness(Bright);
    for( int i = 0; i < NUM_LEDS; i++) {
    //leds[i] = CRGB( Red, Green, Blue);
    }
    //FastLED.show();
    delay(25);
    LoRa.beginPacket();
    LoRa.print("BRIGHT_OK");
    LoRa.endPacket();
    packet = "";
  } else {
    packet = "";
    }
    delay(random(25) + 50);
      LoRa.receive();
}

void cbk(int packetSize) {
  packet ="";
  packSize = String(packetSize,DEC);
  for (int i = 0; i < packetSize; i++) { packet += (char) LoRa.read(); }
  rssi = "RSSI " + String(LoRa.packetRssi(), DEC) ;
  loraData();
}

void setup() {
  pinMode(16,OUTPUT);
  digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
  delay(50); 
  digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high、
  
  Serial.begin(115200);
  while (!Serial);
  Serial.println();
  Serial.println("LoRa Receiver");
  Serial.println("Preparing LED...");

  delay( 3000 ); // power-up safety delay
  //FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  
  Serial.println("Starting LoRa...");
  SPI.begin(SCK,MISO,MOSI,SS);
  LoRa.setPins(SS,RST,DI0);  
  if (!LoRa.begin(868E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  //LoRa.onReceive(cbk);
  LoRa.receive();
  Serial.println("init ok");
  display.begin(SSD1306_SWITCHCAPVCC, 0x3c);

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("LoRa Receiver");
  display.display();
  
  delay(1500);
}

void loop() {
  int packetSize = LoRa.parsePacket();
  msize = LoRa.parsePacket();
  if (packetSize) { cbk(packetSize);  }
  delay(10);
}

Good to see you worked out we need to see your code.

I cant help with the use of the LoRa library I dont receognise it and you did not say which one you are using, but did you test that using just the LoRa code you can send and receive LoRa messages OK?

I'm using this library GitHub - sandeepmistry/arduino-LoRa: An Arduino library for sending and receiving data using LoRa radios., but you can also download it directly from the Arduino IDE since it is in there as well.
I've already tested it with one of the examples without modifying anything and then it works perfectly, so something is wrong about my code. (one of the 2 ESP32 boards refuses to send a responds for some reason, even tho it did receive the message and detected the command and also triggered the code that sends a response. I'm not sure if it is the ESP32 board that receives has a issue or the ESP32 board that sends)

oh and the code for the VB application is:

Imports System.Net.Sockets
Imports System.Threading
Imports System.IO

Public Class Form1

    Dim tcpClient As New System.Net.Sockets.TcpClient()
    Dim ListenerThread As New Thread(New ThreadStart(AddressOf Listening))
    Dim message As String = ""
    Dim CharRead As String = ""
    Dim RSSIString As String = ""
    Dim RSSINum As Integer
    Dim RSSIPercentage As Integer
    Dim LoRaConnected As Boolean = False

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        tmrCheckConnection.Enabled = True
        tmrUpdateForm.Enabled = True
        tcpClient.Connect(TextBox1.Text, 8000)
        ListenerThread.Start()
    End Sub

    Private Sub tmrCheckConnection_Tick(sender As Object, e As EventArgs) Handles tmrCheckConnection.Tick
        Label1.Text = "Connected: " & tcpClient.Connected.ToString
        If tcpClient.Connected = True Then
            Dim Writer As New StreamWriter(tcpClient.GetStream())
            Writer.Write("GET_STATUS")
            Writer.Flush()
        End If
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        tcpClient.Close()
    End Sub

    Private Sub tmrCheckIncomingData_Tick(sender As Object, e As EventArgs) Handles tmrUpdateForm.Tick
        If LoRaConnected = True Then
            If RSSIPercentage > 75 Then
                Label2.Text = "Connection: Good"
                Label10.Text = RSSIPercentage.ToString & "%"
                ProgressBar1.Value = RSSIPercentage
            ElseIf RSSIPercentage > 20 Then
                Label2.Text = "Connection: Medium"
                Label10.Text = RSSIPercentage.ToString & "%"
                ProgressBar1.Value = RSSIPercentage
            ElseIf RSSIPercentage < 21 And RSSIPercentage > 0 Then
                Label2.Text = "Connection: Weak"
                Label10.Text = RSSIPercentage.ToString & "%"
                ProgressBar1.Value = RSSIPercentage
            Else
                Label2.Text = "Connection: Very low"
                Label10.Text = "N/A"
                ProgressBar1.Value = 0
            End If
        End If
    End Sub

    Private Sub CheckCommand()
        If message.Contains("LORA_RSSI=") Then
            RSSIString = message.Split("="c)(1)
            Integer.TryParse(RSSIString, RSSINum)
            Dim tempvalue As Integer = 0
            tempvalue = RSSINum + 100
            If tempvalue * 2 > 100 Then
                RSSIPercentage = 100
            ElseIf tempvalue * 2 < 0 Then
                RSSIPercentage = 0
            Else
                RSSIPercentage = tempvalue * 2
            End If
            LoRaConnected = True
        ElseIf message.Contains("RED_OK") Then
            Debug.Print("Red send ok")
            Dim Writer As New StreamWriter(tcpClient.GetStream())
            Writer.Write("SET_GREEN=" & HScrollBar2.Value)
            Writer.Flush()
        ElseIf message.Contains("GREEN_OK") Then
            Debug.Print("Green send ok")
            Dim Writer As New StreamWriter(tcpClient.GetStream())
            Writer.Write("SET_BLUE=" & HScrollBar3.Value)
            Writer.Flush()
        ElseIf message.Contains("BLUE_OK") Then
            Debug.Print("Blue send ok")
            Dim Writer As New StreamWriter(tcpClient.GetStream())
            Writer.Write("SET_BRIGHT=" & HScrollBar4.Value)
            Writer.Flush()
        ElseIf message.Contains("BRIGHT_OK") Then
            Debug.Print("LED is now on")
            Button3.Enabled = True
            picTransfering.Visible = False
            tmrCheckConnection.Enabled = True
        End If
        message = ""
        Listening()
    End Sub

    Private Sub Listening()
        On Error GoTo errhandler
        'Dim Reader As New StreamReader(tcpClient.GetStream())
        'While Reader.Peek > -1
        'messagebuilder = messagebuilder + Convert.ToChar(Reader.Read()).ToString
        'Debug.Print(messagebuilder)
        'End While
        For i = 0 To 25
            CharRead = Convert.ToChar(tcpClient.GetStream.ReadByte).ToString
            If CharRead = Chr(10) Or CharRead = Chr(12) Then
                Exit For
            Else
                message = message & CharRead
            End If
        Next
        Debug.Print(message)
        CheckCommand()
        Exit Sub
errhandler:
        Debug.Print("Unable to read from datastream, error #" & Err.Number)
        Listening()
    End Sub

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        picTransfering.Visible = True
        tmrCheckConnection.Enabled = False
        Dim Writer As New StreamWriter(tcpClient.GetStream())
        Writer.Write("SET_RED=" & HScrollBar1.Value)
        Writer.Flush()
        'Button3.Enabled = False
    End Sub

    Private Sub HScrollBar1_Scroll(sender As Object, e As ScrollEventArgs) Handles HScrollBar1.Scroll
        PictureBox1.BackColor = Color.FromArgb(HScrollBar1.Value, HScrollBar2.Value, HScrollBar3.Value)
        Label7.Text = HScrollBar1.Value.ToString
    End Sub

    Private Sub HScrollBar2_Scroll(sender As Object, e As ScrollEventArgs) Handles HScrollBar2.Scroll
        PictureBox1.BackColor = Color.FromArgb(HScrollBar1.Value, HScrollBar2.Value, HScrollBar3.Value)
        Label8.Text = HScrollBar2.Value.ToString
    End Sub

    Private Sub HScrollBar3_Scroll(sender As Object, e As ScrollEventArgs) Handles HScrollBar3.Scroll
        PictureBox1.BackColor = Color.FromArgb(HScrollBar1.Value, HScrollBar2.Value, HScrollBar3.Value)
        Label9.Text = HScrollBar3.Value.ToString
    End Sub

    Private Sub HScrollBar4_Scroll(sender As Object, e As ScrollEventArgs) Handles HScrollBar4.Scroll
        PictureBox1.BackColor = Color.FromArgb(HScrollBar1.Value, HScrollBar2.Value, HScrollBar3.Value)
        Label12.Text = HScrollBar4.Value.ToString
    End Sub

    Private Sub HScrollBar1_ValueChanged(sender As Object, e As EventArgs) Handles HScrollBar1.ValueChanged
        PictureBox1.BackColor = Color.FromArgb(HScrollBar1.Value, HScrollBar2.Value, HScrollBar3.Value)
        Label7.Text = HScrollBar1.Value.ToString
    End Sub

    Private Sub HScrollBar2_ValueChanged(sender As Object, e As EventArgs) Handles HScrollBar2.ValueChanged
        PictureBox1.BackColor = Color.FromArgb(HScrollBar1.Value, HScrollBar2.Value, HScrollBar3.Value)
        Label8.Text = HScrollBar2.Value.ToString
    End Sub

    Private Sub HScrollBar3_ValueChanged(sender As Object, e As EventArgs) Handles HScrollBar3.ValueChanged
        PictureBox1.BackColor = Color.FromArgb(HScrollBar1.Value, HScrollBar2.Value, HScrollBar3.Value)
        Label9.Text = HScrollBar3.Value.ToString
    End Sub

    Private Sub HScrollBar4_ValueChanged(sender As Object, e As EventArgs) Handles HScrollBar4.ValueChanged
        PictureBox1.BackColor = Color.FromArgb(HScrollBar1.Value, HScrollBar2.Value, HScrollBar3.Value)
        Label12.Text = HScrollBar4.Value.ToString
    End Sub
End Class

I've added a picture of how the form exactly looks like (might help with identifying what the code exactly does, if you have any questions about it. please ask them!)

Naamloos.png

Oh and this is how the VB application controls the LED strip.
It will first have to go thru the first ESP32 module which sends it to the other ESP32 module that has the LED strip.
So every command first has to go thru the first ESP32 module so it can be send using LoRa.

(edit. forgot to tell this, but if you want to debug the arduino code with the actual VB application. You don't need to install Visual Studio first because inside the ZIP file I've also included a pre compiled version)

Sorry, but I'm gonna bump this topic.
I really don't know why it isn't working :confused:

CrazyVito11:
if you want to debug the arduino code with the actual VB application. You don't need to install Visual Studio first because inside the ZIP file I've also included a pre compiled version

Cant really see how anyone could do that unless they had the LoRa hardware in front of them to test your application for you.