Paging with LoRa and Oled

Hello, i am breaking my head about my code.

I have seperate codes working. But when i combine code it doesnt parse variables.

I have a wemos D1 mini set up with LoRa. it sends message like: AT+SEND=3,1,2
on the second wemos d1 mini i recieve this message
the code breaks it up in channel_id = 3
length of message = 1
and message = 3 (this last number is important)

i have to recieve the number and convert it into a string (1 for Door, 2 for kitchen, 3 for Bar)
then i want to send that text to the oled screen.

it doesnt remember the message?!?
cant figure out why.

here is my receive code:

/***************************************************************************/
// Deze werkt tot nu toe
/***************************************************************************/
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Arduino.h>
#include <EEPROM.h>
int address = 0; // EEPROM address to store the value
// ^^^^^^^^^^^^^^^^^^^ dont use this yet ^^^^^^^^

#include <Fonts/FreeSerifBold9pt7b.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const int buttonPin = 0; // Definieer de pin waarop de knop is aangesloten
// connect switch between pin D3 (GPIO0) en GND



#define RXD2 14 //pin D6 op de Wemos D1 mini
#define TXD2 12 //pin D5 op de Wemos D1 mini

SoftwareSerial mySerial(RXD2, TXD2);

#define TARGET_ID 3 // dit DEVICE

String Message = "DIT IS DE ONTVANGER OP ADDRESS 3";
String content = "";
String lora_band = "868500000"; // setting LoRa Band frequency
String incomming = "";
String channel_ID = "";
String message = ""; // Declare 'message' as a global variable




void setup() {
  pinMode(buttonPin, INPUT); // Stel de knop in als invoer
  Serial.begin(9600);
  mySerial.begin(115200);
  delay(1000);
  mySerial.println("AT+BAND=" + lora_band);
  delay(1000);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  display.setFont(&FreeSerifBold9pt7b); //  Set custom Font (built in GFX lib)

// just for fun (small arial)
  display.drawLine(5, 5, 15, 15, SSD1306_WHITE);
  display.drawLine(15, 15,25,5, SSD1306_WHITE);
  display.drawLine(15, 5,15,30, SSD1306_WHITE);

  // Show the display buffer on the screen. You MUST call display.display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(2000);
  // display.display() is NOT necessary after every single drawing command,
  // unless that's what you want...rather, you can batch up a bunch of
  // drawing operations and then update the screen all at once by calling
  // display.display(). These examples demonstrate both approaches...
}

void loop() {
  if (Serial.available()){
    Serial.println("Writing");
    content = Serial.readString();
    content.trim();
    Serial.println();
    content = content + "\r\n";
    char* bufc = (char*) malloc(sizeof(char) * content.length() + 1);
    content.toCharArray(bufc, content.length() + 1);
    mySerial.write(bufc);
    free(bufc);
  }
  
  if (mySerial.available()) {
    String incomming = mySerial.readString();
    if (incomming.length() <= 10){  // kleiner of gelijk aan....
      digitalWrite(2, LOW);
      delay(2000); // light led for 2 seconds
      digitalWrite(2, HIGH);
      Serial.println(incomming); // voor seriele monitor input
  }else {
      String channel_ID = incomming.substring(incomming.indexOf('=') + 1, incomming.indexOf(','));
      Serial.println("Channel ID : " + channel_ID);
      
      String str = incomming.substring(incomming.indexOf(',') + 1);
      
      String msgLength = str.substring(0, str.indexOf(','));
      Serial.println("Message Length : " + msgLength);
      
      String str2 = str.substring(str.indexOf(',') + 1);
      
      String message = str2.substring(0, str2.indexOf(','));
 
      Serial.println("Message : >" + message+"<");              // dit word geprint
      testtekst(message);
     }           
  }
  /* Controleren of de knop is ingedrukt */
  if (digitalRead(buttonPin) == LOW) {
    //message = "3";
    testtekst(message);         // send message to Oled
    delay(100);
  } 
}       


//--------------------------------------------------------------------------------------------------------------------------------

void testtekst(String message) {                 // sub routine 
  //message.trim(); // Trim the message in place
  if (message == "1") {
    Serial.println("recieved >" + message +"<");
    display.clearDisplay();                 // wis buffer voor de nieuwe text (lijkt me eigenlijk overbodig)
    display.setTextSize(2);                 // text size 2
    display.setTextColor(SSD1306_WHITE);    // neem witte text kleur
    display.setCursor(20, 24);              // Start positie cursor
    display.println(F("Deur"));             // vul buffer met text (Deur)
    display.display();                      // geef buffer inhoud weer op het scherm (Deur)
    delay(2000);                            // pause 2 seconden 
    display.clearDisplay();                 // wis buffer inhoud (maar niet van de display)
    display.display();                      // geef buffer inhoud op het oled weer (in dit geval dus leeg scherm)
  } else if (message == "2") {
    Serial.println("recieved " + message);
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(SSD1306_WHITE);        // Draw white text
    display.setCursor(1, 24);
    display.println(F("Keuken"));
    display.display();
    delay(2000);
    display.clearDisplay();
    display.display();
  } else if (message == "3") {
    Serial.println("recieved " + message);
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(SSD1306_WHITE);        // Draw white text
    display.setCursor(40, 24);
    display.println(F("Bar"));
    display.display();
    delay(2000);
    display.clearDisplay();
    display.display();
  } else {
    Serial.println("Not Valid : >" + message + "<");
  } 

}
}

can sombody help me ?

this is what i recive in serial monitor:
01:54:09.148 -> Channel ID : 3
01:54:09.148 -> Message Length : 1
01:54:09.148 -> Message : >1<
01:54:09.148 -> recieved >1<

this got send:
01:55:50.610 -> BUTTON PRESSED
01:55:50.610 -> AT+SEND=4,1,1
01:55:50.610 ->
01:55:53.734 -> +OK
01:55:53.734 ->

I moved your topic to an appropriate forum category @Richard63.

In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.

This is an important part of responsible forum usage, as explained in the "How to get the best out of this forum" guide. The guide contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

not sure what you mean?
what LoRa module are you using?
upload the transmitter code
if you are transmitting strings suggest you terminate with a '\n' and use readStringUntil('\n'); to ensure you get a complete line of text

i use the rylr998 module from reyax

#include <SoftwareSerial.h>

#define RXD2 14 //pin D6 op de Wemos D1 mini
#define TXD2 12 //pin D5 op de Wemos D1 mini

SoftwareSerial mySerial(RXD2, TXD2);

#define TARGET_ID 4 // This DEVICE (TX)

// connect switch between pin D3 (GPIO0) en GND

String message = "1"; // message to be received on Button Press
String content = "";
String lora_band = "868500000"; // setting LoRa Band frequency

void setup()
{
  Serial.begin(9600);
  mySerial.begin(115200); // LoRa baudrate
  delay(1000);
  mySerial.println("AT+BAND=" + lora_band);
  delay(1000);
  pinMode(0, INPUT_PULLUP);
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);
}

void loop() {
  if (Serial.available()){
    Serial.println("Writing");
    content = Serial.readString();
    content.trim();
    Serial.println();
    content = content + "\r\n";
    char* bufc = (char*) malloc(sizeof(char) * content.length() + 1);
    content.toCharArray(bufc, content.length() + 1);
    mySerial.write(bufc);
    free(bufc);
  }

  if (mySerial.available()) {
    String incomming = mySerial.readString();
    if (incomming.length() <= 10){
      digitalWrite(2, LOW);
      delay(2000);
      digitalWrite(2, HIGH);
      Serial.println(incomming);
    } else {
      String channel_ID = incomming.substring(incomming.indexOf('=') + 1, incomming.indexOf(','));
      Serial.println("Channel ID : " + channel_ID);

      String str = incomming.substring(incomming.indexOf(',') + 1);

      String msgLength = str.substring(0, str.indexOf(','));
      Serial.println("Message Length : " + msgLength);

      String str2 = str.substring(str.indexOf(',') + 1);

      String message = str2.substring(0, str2.indexOf(','));
      Serial.println("Message : " + message);
      
      digitalWrite(2, LOW);
      delay(2000);
      digitalWrite(2, HIGH);
    }
  }

  // When the button is pressed send the message to other module
  if (digitalRead(0) == LOW) {
    delay(1000);
    Serial.println("BUTTON PRESSED");
    String data = message;
    sendLoraData(data, TARGET_ID); 
  }
}

void sendLoraData(String data, int address) {
  String myString = "AT+SEND=" + String(address) + "," + String(data.length()) + "," + data + "\r\n";
  char* buf = (char*) malloc(sizeof(char) * myString.length() + 1);
  Serial.println(myString);
  myString.toCharArray(buf, myString.length() + 1);
  mySerial.write(buf);
  free(buf);
}

I plan to build 3 Transmitters that send 1, 2 and 3 as message.
1 for the Entree, 2 for the kitchen and 3 for the bar

now when i press the button on the transmitter it sends "1" and i recieve "1" then the display reads "Deur" (wich means Door in dutch)
but when i press the button on the receiver, it dont show "Deur" (or "1"on the serial monitor)

it looks like the variable is erased.
Hope i explained it right :slight_smile:

are you using EspSoftwareSerial?
make Serial Baudrate same as or faster than mySerial
why do you read a String then convert it to char array - use readBytesUntil

you are defining message as a global String

String message = ""; // Declare 'message' as a global variable

but in loop() you define a local variable called message

void loop() {
  if (Serial.available()){
      ...
  }
  
  if (mySerial.available()) {
       ......
  }else {
        ......
     String str2 = str.substring(str.indexOf(',') + 1);
      
      String message = str2.substring(0, str2.indexOf(','));  <<<< local variable
 
      Serial.println("Message : >" + message+"<");              // dit word geprint
      testtekst(message);
     }           
  }
  /* Controleren of de knop is ingedrukt */
  if (digitalRead(buttonPin) == LOW) {
    //message = "3";
    testtekst(message);         // send message to Oled <<  this prints ontents of global varaible
    delay(100);c
  } 
}       

change to use global variable

  message = str2.substring(0, str2.indexOf(','));   // use global variable

mmm how could i overlooked that.

I am new to c++ code.

i am more experienced in python at the moment.

i got it to work!

now i can work onwards to the rest of the button code.

when i press and hold the button it flashes now after the delay, but neet to make it stay on while the button is stil pressed.

thanks Horace

you can try something along the lines of

 while (digitalRead(buttonPin) == LOW) {
      .......         // code executed while button is pressed

however, while in the loop you cannot do anything else
if a watchdog timer is enabled you may get a WDT exception if you hold it too long

i wil figure it out :slight_smile: thanks so far.

I have to print a new enclosure for it al.

i designed it in tinkercad and print on my resin printer (or maybe on my fdm)

So i made some progress.
Now i am cleaning up my code, and there is one thing that drives me crazy.

If i boot up de wemos d1 mini, it shows up the flash screen
the code part that tests for mySerial.available() is jumping to the else part and loops thru the message part with vibrating and shows up

why has Channel ID : the valu of 1 after power up?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.