cstram
Published © GPL3+

Mobile LoRa short message transmitter/receiver

Need to send pre-defined short messages in uncovered wifi/4G/5G area? Check out my project!

IntermediateFull instructions provided1,553
Mobile LoRa short message transmitter/receiver

Things used in this project

Hardware components

PCBWay Custom PCB
PCBWay Custom PCB
×1
FireBeetle ESP32 IOT Microcontroller (Supports Wi-Fi & Bluetooth)
DFRobot FireBeetle ESP32 IOT Microcontroller (Supports Wi-Fi & Bluetooth)
×1
Pushbutton Switch, Momentary
Pushbutton Switch, Momentary
×1
Buzzer
Buzzer
×1
Graphic OLED, 128 x 32 Pixels
Graphic OLED, 128 x 32 Pixels
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Mobile Two-Way short message device

Code

Two-Way mobile short message device

Arduino
/*
  LoRaNow Messaging with ESP32

  This code send messages between Devices.
  
  created 19 06 2022
  by Carlo Stramaglia
*/

#include <SPI.h>              // include libraries
#include <LoRa.h>
#include <U8g2lib.h>
#include "OneButton.h"
#include "messages.h"

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

#define PIN_INPUT 15 // PIN for push button
#define PIN_BUZ 4 // PIN for buzzer
// current Buzzer state, staring with LOW (0)
int buzState = LOW;
OneButton button(PIN_INPUT, true);

int exitFlag = 0;
int stringNumber = -1;

const int csPin = 5;          // LoRa radio chip select
const int resetPin = 14;       // LoRa radio reset
const int irqPin = 2;         // change for your board; must be a hardware interrupt pin

String outgoing;              // outgoing message

byte msgCount = 0;            // count of outgoing messages
byte localAddress = 0xBA;     // address of this device
byte destination = 0xFF;      // destination to send to
long lastSendTime = 0;        // last send time
int interval = 2000;          // interval between sends



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

  // enable the buzzer
  pinMode(PIN_BUZ, OUTPUT); // sets the digital pin as output
  digitalWrite(PIN_BUZ, buzState); // sets the buzzer in mute

  // link the doubleclick function to be called on a doubleclick event.
  button.attachClick(Click);
  button.attachLongPressStart(longPressStart);
  
  // override the default CS, reset, and IRQ pins (optional)
  LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin

  if (!LoRa.begin(866E6)) {             // initialize ratio at 868 MHz
    Serial.println("LoRa init failed. Check your connections.");
    while (true);                       // if failed, do nothing
  }

  Serial.println("LoRa init succeeded.");
}

void loop() {

  delay(10);
  button.tick();
  // parse for a packet, and call onReceive with the result:
  onReceive(LoRa.parsePacket());
}

void sendMessage(String outgoing) {
  LoRa.beginPacket();                   // start packet
  LoRa.write(destination);              // add destination address
  LoRa.write(localAddress);             // add sender address
  LoRa.write(msgCount);                 // add message ID
  LoRa.write(outgoing.length());        // add payload length
  LoRa.print(outgoing);                 // add payload
  LoRa.endPacket();                     // finish packet and send it
  msgCount++;                           // increment message ID
}

void onReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return

  // read packet header bytes:
  int recipient = LoRa.read();          // recipient address
  byte sender = LoRa.read();            // sender address
  byte incomingMsgId = LoRa.read();     // incoming msg ID
  byte incomingLength = LoRa.read();    // incoming msg length

  String incoming = "";

  while (LoRa.available()) {
    incoming += (char)LoRa.read();
  }

  if (incomingLength != incoming.length()) {   // check length for error
    Serial.println("error: message length does not match length");
    return;                             // skip rest of function
  }



  // if the recipient isn't this device or broadcast,
  if (recipient != localAddress && recipient != 0xFF) {
    Serial.println("This message is not for me.");
    return;                             // skip rest of function
  }

  // if message is for this device, or broadcast, print details:
  Serial.println("Received from: 0x" + String(sender, HEX));
  Serial.println("Sent to: 0x" + String(recipient, HEX));
  Serial.println("Message ID: " + String(incomingMsgId));
  Serial.println("Message length: " + String(incomingLength));
  Serial.println("Message: " + incoming);
  Serial.println("RSSI: " + String(LoRa.packetRssi()));
  Serial.println("Snr: " + String(LoRa.packetSnr()));
  Serial.println();
  digitalWrite(PIN_BUZ, !buzState);
  Serial.println("Buzzer ON");
  delay (100);
  digitalWrite(PIN_BUZ, buzState);
  Serial.println("Buzzer OFF");
  sendDisplay(sender, incoming);
}

void sendDisplay(unsigned int nodeID, String messageLoRa) {
  char messageLocal[MAX_STRING_SIZE];
  u8g2.clearBuffer();          
  u8g2.setFont(u8g2_font_ncenB08_tr); 
  sprintf (messageLocal, "Message From: %d", nodeID);
  u8g2.drawStr(0,10, messageLocal);
  messageLoRa.toCharArray(messageLocal, MAX_STRING_SIZE);
  u8g2.drawStr(0,30, messageLocal); 
  u8g2.sendBuffer();          
  delay(1000);  
}


void Click()
{
  Serial.println("x1");
  stringNumber++;
  if (stringNumber > 3)
    stringNumber = 0;
  displayString (stringNumber+1, arr[stringNumber]);
  
  exitFlag = 0;

} // Click

void longPressStart()
{
  Serial.println("Long");
  displaySend (stringNumber+1, arr[stringNumber]);
  // Send data to the node
  //LoRaNow.clear();
  sendMessage(arr[stringNumber]);
  exitFlag = 1;
 
} // LongPressStart


void displayString (unsigned int stringNo, char* stringToDisplay) {
  char messageLocal[MAX_STRING_SIZE];
  u8g2.clearBuffer();          
  u8g2.setFont(u8g2_font_ncenB08_tr); 
  sprintf (messageLocal, "Destination: %d", destination);   
  u8g2.drawStr(0,10, messageLocal);
  sprintf (messageLocal, "Text selection: %d of %d", stringNo, NUMBER_OF_STRING); 
  u8g2.drawStr(0,20, messageLocal);
  u8g2.drawStr(0,30, stringToDisplay); 
  u8g2.sendBuffer();          
  delay(100);  
}

void displaySend (unsigned int stringNo, char* stringToDisplay) {
  char messageLocal[MAX_STRING_SIZE];
  u8g2.clearBuffer();          
  u8g2.setFont(u8g2_font_ncenB08_tr); 
  sprintf (messageLocal, "Destination: %d", destination);
  u8g2.drawStr(0,10, messageLocal);
  sprintf (messageLocal, "Sending Message: %d of %d", stringNo, NUMBER_OF_STRING);  
  u8g2.drawStr(0,20, messageLocal);
  u8g2.drawStr(0,30, stringToDisplay); 
  u8g2.sendBuffer();          
  delay(100);  
}

messages.h

Arduino
#define NUMBER_OF_STRING 4
#define MAX_STRING_SIZE 40

char arr[NUMBER_OF_STRING][MAX_STRING_SIZE] =
{ "Get on the phone!",
  "The music is too loud",
  "I'm ready to move",
  "See you at 10:00 AM"
};

Credits

cstram

cstram

16 projects • 21 followers
Passionate about IT, Electronics and DIY. Strong believer in Raspberry and Arduino devices. Experience in digital television and security.

Comments