Need to send pre-defined short messages in uncovered wifi/4G/5G area? Check out my project!
Things used in this project
Hardware components
Story
Introduction
I’ve always been fascinated by the fact that we can transmit data for a long distance between two devices.
The thing that is fantastic is that it can be done totally free or charge without the use of a mobile subscription.
These two devices allow to send and receive small messages using LoRa technology:
#ESP32#RFM95#Battery#Antenna#arduino #arduinoproject #esp32 #rfm95 #lora
VIDEO
How to change config
- In case you need to add other devices, you need to modify the "localAddress" variable and make it unique
- In case you need to address a specific device, you need to modify the "destination" variable and put the value of the device you want to message
- In case you want to message all devices, you need to put the value 255 in the "destination" variable.
- In case you want to add more messages, you need to modify the "messages.h" file and change the NUMBER_OF_STRING with a value equal to the number of messages you want to have as options. Then you need to add the string at the end of the "char arr" array.
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"
};