Mobile LoRa short message transmitter/receiver
Need to send pre-defined short messages in uncovered wifi/4G/5G area? Check out my project!
Components and supplies
1
PCBWay Custom PCB
1
Pushbutton Switch, Momentary
1
Graphic OLED, 128 x 32 Pixels
1
Buzzer
1
FireBeetle ESP32 IOT Microcontroller (Supports Wi-Fi & Bluetooth)
Apps and platforms
1
Arduino IDE
Project description
Code
messages.h
arduino
1#define NUMBER_OF_STRING 4 2#define MAX_STRING_SIZE 40 3 4char arr[NUMBER_OF_STRING][MAX_STRING_SIZE] = 5{ "Get on the phone!", 6 "The music is too loud", 7 "I'm ready to move", 8 "See you at 10:00 AM" 9}; 10
Two-Way mobile short message device
arduino
1/* 2 LoRaNow Messaging with ESP32 3 4 This code send messages between Devices. 5 6 created 19 06 2022 7 by Carlo Stramaglia 8*/ 9 10#include <SPI.h> // include libraries 11#include <LoRa.h> 12#include <U8g2lib.h> 13#include "OneButton.h" 14#include "messages.h" 15 16#ifdef U8X8_HAVE_HW_SPI 17#include <SPI.h> 18#endif 19#ifdef U8X8_HAVE_HW_I2C 20#include <Wire.h> 21#endif 22 23U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); 24 25#define PIN_INPUT 15 // PIN for push button 26#define PIN_BUZ 4 // PIN for buzzer 27// current Buzzer state, staring with LOW (0) 28int buzState = LOW; 29OneButton button(PIN_INPUT, true); 30 31int exitFlag = 0; 32int stringNumber = -1; 33 34const int csPin = 5; // LoRa radio chip select 35const int resetPin = 14; // LoRa radio reset 36const int irqPin = 2; // change for your board; must be a hardware interrupt pin 37 38String outgoing; // outgoing message 39 40byte msgCount = 0; // count of outgoing messages 41byte localAddress = 0xBA; // address of this device 42byte destination = 0xFF; // destination to send to 43long lastSendTime = 0; // last send time 44int interval = 2000; // interval between sends 45 46 47 48void setup() { 49 Serial.begin(115200); // initialize serial 50 u8g2.begin(); 51 52 // enable the buzzer 53 pinMode(PIN_BUZ, OUTPUT); // sets the digital pin as output 54 digitalWrite(PIN_BUZ, buzState); // sets the buzzer in mute 55 56 // link the doubleclick function to be called on a doubleclick event. 57 button.attachClick(Click); 58 button.attachLongPressStart(longPressStart); 59 60 // override the default CS, reset, and IRQ pins (optional) 61 LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin 62 63 if (!LoRa.begin(866E6)) { // initialize ratio at 868 MHz 64 Serial.println("LoRa init failed. Check your connections."); 65 while (true); // if failed, do nothing 66 } 67 68 Serial.println("LoRa init succeeded."); 69} 70 71void loop() { 72 73 delay(10); 74 button.tick(); 75 // parse for a packet, and call onReceive with the result: 76 onReceive(LoRa.parsePacket()); 77} 78 79void sendMessage(String outgoing) { 80 LoRa.beginPacket(); // start packet 81 LoRa.write(destination); // add destination address 82 LoRa.write(localAddress); // add sender address 83 LoRa.write(msgCount); // add message ID 84 LoRa.write(outgoing.length()); // add payload length 85 LoRa.print(outgoing); // add payload 86 LoRa.endPacket(); // finish packet and send it 87 msgCount++; // increment message ID 88} 89 90void onReceive(int packetSize) { 91 if (packetSize == 0) return; // if there's no packet, return 92 93 // read packet header bytes: 94 int recipient = LoRa.read(); // recipient address 95 byte sender = LoRa.read(); // sender address 96 byte incomingMsgId = LoRa.read(); // incoming msg ID 97 byte incomingLength = LoRa.read(); // incoming msg length 98 99 String incoming = ""; 100 101 while (LoRa.available()) { 102 incoming += (char)LoRa.read(); 103 } 104 105 if (incomingLength != incoming.length()) { // check length for error 106 Serial.println("error: message length does not match length"); 107 return; // skip rest of function 108 } 109 110 111 112 // if the recipient isn't this device or broadcast, 113 if (recipient != localAddress && recipient != 0xFF) { 114 Serial.println("This message is not for me."); 115 return; // skip rest of function 116 } 117 118 // if message is for this device, or broadcast, print details: 119 Serial.println("Received from: 0x" + String(sender, HEX)); 120 Serial.println("Sent to: 0x" + String(recipient, HEX)); 121 Serial.println("Message ID: " + String(incomingMsgId)); 122 Serial.println("Message length: " + String(incomingLength)); 123 Serial.println("Message: " + incoming); 124 Serial.println("RSSI: " + String(LoRa.packetRssi())); 125 Serial.println("Snr: " + String(LoRa.packetSnr())); 126 Serial.println(); 127 digitalWrite(PIN_BUZ, !buzState); 128 Serial.println("Buzzer ON"); 129 delay (100); 130 digitalWrite(PIN_BUZ, buzState); 131 Serial.println("Buzzer OFF"); 132 sendDisplay(sender, incoming); 133} 134 135void sendDisplay(unsigned int nodeID, String messageLoRa) { 136 char messageLocal[MAX_STRING_SIZE]; 137 u8g2.clearBuffer(); 138 u8g2.setFont(u8g2_font_ncenB08_tr); 139 sprintf (messageLocal, "Message From: %d", nodeID); 140 u8g2.drawStr(0,10, messageLocal); 141 messageLoRa.toCharArray(messageLocal, MAX_STRING_SIZE); 142 u8g2.drawStr(0,30, messageLocal); 143 u8g2.sendBuffer(); 144 delay(1000); 145} 146 147 148void Click() 149{ 150 Serial.println("x1"); 151 stringNumber++; 152 if (stringNumber > 3) 153 stringNumber = 0; 154 displayString (stringNumber+1, arr[stringNumber]); 155 156 exitFlag = 0; 157 158} // Click 159 160void longPressStart() 161{ 162 Serial.println("Long"); 163 displaySend (stringNumber+1, arr[stringNumber]); 164 // Send data to the node 165 //LoRaNow.clear(); 166 sendMessage(arr[stringNumber]); 167 exitFlag = 1; 168 169} // LongPressStart 170 171 172void displayString (unsigned int stringNo, char* stringToDisplay) { 173 char messageLocal[MAX_STRING_SIZE]; 174 u8g2.clearBuffer(); 175 u8g2.setFont(u8g2_font_ncenB08_tr); 176 sprintf (messageLocal, "Destination: %d", destination); 177 u8g2.drawStr(0,10, messageLocal); 178 sprintf (messageLocal, "Text selection: %d of %d", stringNo, NUMBER_OF_STRING); 179 u8g2.drawStr(0,20, messageLocal); 180 u8g2.drawStr(0,30, stringToDisplay); 181 u8g2.sendBuffer(); 182 delay(100); 183} 184 185void displaySend (unsigned int stringNo, char* stringToDisplay) { 186 char messageLocal[MAX_STRING_SIZE]; 187 u8g2.clearBuffer(); 188 u8g2.setFont(u8g2_font_ncenB08_tr); 189 sprintf (messageLocal, "Destination: %d", destination); 190 u8g2.drawStr(0,10, messageLocal); 191 sprintf (messageLocal, "Sending Message: %d of %d", stringNo, NUMBER_OF_STRING); 192 u8g2.drawStr(0,20, messageLocal); 193 u8g2.drawStr(0,30, stringToDisplay); 194 u8g2.sendBuffer(); 195 delay(100); 196} 197
messages.h
arduino
1#define NUMBER_OF_STRING 4 2#define MAX_STRING_SIZE 40 3 4char arr[NUMBER_OF_STRING][MAX_STRING_SIZE] = 5{ "Get on the phone!", 6 "The music is too loud", 7 "I'm ready to move", 8 "See you at 10:00 AM" 9}; 10
Two-Way mobile short message device
arduino
1/* 2 LoRaNow Messaging with ESP32 3 4 This code send messages 5 between Devices. 6 7 created 19 06 2022 8 by Carlo Stramaglia 9*/ 10 11#include 12 <SPI.h> // include libraries 13#include <LoRa.h> 14#include <U8g2lib.h> 15#include 16 "OneButton.h" 17#include "messages.h" 18 19#ifdef U8X8_HAVE_HW_SPI 20#include 21 <SPI.h> 22#endif 23#ifdef U8X8_HAVE_HW_I2C 24#include <Wire.h> 25#endif 26 27U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C 28 u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); 29 30#define 31 PIN_INPUT 15 // PIN for push button 32#define PIN_BUZ 4 // PIN for buzzer 33// 34 current Buzzer state, staring with LOW (0) 35int buzState = LOW; 36OneButton button(PIN_INPUT, 37 true); 38 39int exitFlag = 0; 40int stringNumber = -1; 41 42const int csPin 43 = 5; // LoRa radio chip select 44const int resetPin = 14; // LoRa 45 radio reset 46const int irqPin = 2; // change for your board; must be a 47 hardware interrupt pin 48 49String outgoing; // outgoing message 50 51byte 52 msgCount = 0; // count of outgoing messages 53byte localAddress = 0xBA; 54 // address of this device 55byte destination = 0xFF; // destination to 56 send to 57long lastSendTime = 0; // last send time 58int interval = 2000; 59 // interval between sends 60 61 62 63void setup() { 64 Serial.begin(115200); 65 // initialize serial 66 u8g2.begin(); 67 68 // enable the 69 buzzer 70 pinMode(PIN_BUZ, OUTPUT); // sets the digital pin as output 71 digitalWrite(PIN_BUZ, 72 buzState); // sets the buzzer in mute 73 74 // link the doubleclick function 75 to be called on a doubleclick event. 76 button.attachClick(Click); 77 button.attachLongPressStart(longPressStart); 78 79 80 // override the default CS, reset, and IRQ pins (optional) 81 LoRa.setPins(csPin, 82 resetPin, irqPin);// set CS, reset, IRQ pin 83 84 if (!LoRa.begin(866E6)) { // 85 initialize ratio at 868 MHz 86 Serial.println("LoRa init failed. Check your 87 connections."); 88 while (true); // if failed, do nothing 89 90 } 91 92 Serial.println("LoRa init succeeded."); 93} 94 95void loop() { 96 97 98 delay(10); 99 button.tick(); 100 // parse for a packet, and call onReceive 101 with the result: 102 onReceive(LoRa.parsePacket()); 103} 104 105void sendMessage(String 106 outgoing) { 107 LoRa.beginPacket(); // start packet 108 LoRa.write(destination); 109 // add destination address 110 LoRa.write(localAddress); // 111 add sender address 112 LoRa.write(msgCount); // add message ID 113 114 LoRa.write(outgoing.length()); // add payload length 115 LoRa.print(outgoing); 116 // add payload 117 LoRa.endPacket(); // finish 118 packet and send it 119 msgCount++; // increment message 120 ID 121} 122 123void onReceive(int packetSize) { 124 if (packetSize == 0) return; 125 // if there's no packet, return 126 127 // read packet header bytes: 128 129 int recipient = LoRa.read(); // recipient address 130 byte sender = 131 LoRa.read(); // sender address 132 byte incomingMsgId = LoRa.read(); 133 // incoming msg ID 134 byte incomingLength = LoRa.read(); // incoming msg 135 length 136 137 String incoming = ""; 138 139 while (LoRa.available()) { 140 141 incoming += (char)LoRa.read(); 142 } 143 144 if (incomingLength != incoming.length()) 145 { // check length for error 146 Serial.println("error: message length does 147 not match length"); 148 return; // skip rest of 149 function 150 } 151 152 153 154 // if the recipient isn't this device or broadcast, 155 156 if (recipient != localAddress && recipient != 0xFF) { 157 Serial.println("This 158 message is not for me."); 159 return; // skip rest 160 of function 161 } 162 163 // if message is for this device, or broadcast, print 164 details: 165 Serial.println("Received from: 0x" + String(sender, HEX)); 166 Serial.println("Sent 167 to: 0x" + String(recipient, HEX)); 168 Serial.println("Message ID: " + String(incomingMsgId)); 169 170 Serial.println("Message length: " + String(incomingLength)); 171 Serial.println("Message: 172 " + incoming); 173 Serial.println("RSSI: " + String(LoRa.packetRssi())); 174 175 Serial.println("Snr: " + String(LoRa.packetSnr())); 176 Serial.println(); 177 178 digitalWrite(PIN_BUZ, !buzState); 179 Serial.println("Buzzer ON"); 180 delay 181 (100); 182 digitalWrite(PIN_BUZ, buzState); 183 Serial.println("Buzzer OFF"); 184 185 sendDisplay(sender, incoming); 186} 187 188void sendDisplay(unsigned int nodeID, 189 String messageLoRa) { 190 char messageLocal[MAX_STRING_SIZE]; 191 u8g2.clearBuffer(); 192 193 u8g2.setFont(u8g2_font_ncenB08_tr); 194 sprintf (messageLocal, 195 "Message From: %d", nodeID); 196 u8g2.drawStr(0,10, messageLocal); 197 messageLoRa.toCharArray(messageLocal, 198 MAX_STRING_SIZE); 199 u8g2.drawStr(0,30, messageLocal); 200 u8g2.sendBuffer(); 201 202 delay(1000); 203} 204 205 206void Click() 207{ 208 Serial.println("x1"); 209 210 stringNumber++; 211 if (stringNumber > 3) 212 stringNumber = 0; 213 displayString 214 (stringNumber+1, arr[stringNumber]); 215 216 exitFlag = 0; 217 218} // Click 219 220void 221 longPressStart() 222{ 223 Serial.println("Long"); 224 displaySend (stringNumber+1, 225 arr[stringNumber]); 226 // Send data to the node 227 //LoRaNow.clear(); 228 sendMessage(arr[stringNumber]); 229 230 exitFlag = 1; 231 232} // LongPressStart 233 234 235void displayString (unsigned 236 int stringNo, char* stringToDisplay) { 237 char messageLocal[MAX_STRING_SIZE]; 238 239 u8g2.clearBuffer(); 240 u8g2.setFont(u8g2_font_ncenB08_tr); 241 sprintf 242 (messageLocal, "Destination: %d", destination); 243 u8g2.drawStr(0,10, messageLocal); 244 245 sprintf (messageLocal, "Text selection: %d of %d", stringNo, NUMBER_OF_STRING); 246 247 u8g2.drawStr(0,20, messageLocal); 248 u8g2.drawStr(0,30, stringToDisplay); 249 250 u8g2.sendBuffer(); 251 delay(100); 252} 253 254void displaySend 255 (unsigned int stringNo, char* stringToDisplay) { 256 char messageLocal[MAX_STRING_SIZE]; 257 258 u8g2.clearBuffer(); 259 u8g2.setFont(u8g2_font_ncenB08_tr); 260 sprintf 261 (messageLocal, "Destination: %d", destination); 262 u8g2.drawStr(0,10, messageLocal); 263 264 sprintf (messageLocal, "Sending Message: %d of %d", stringNo, NUMBER_OF_STRING); 265 266 u8g2.drawStr(0,20, messageLocal); 267 u8g2.drawStr(0,30, stringToDisplay); 268 269 u8g2.sendBuffer(); 270 delay(100); 271} 272
Downloadable files
Mobile Two-Way short message device
Mobile Two-Way short message device

Comments
Only logged in users can leave comments