From f230dc841ed0bf83cb1efd2a43bdaa619d6064d3 Mon Sep 17 00:00:00 2001 From: angoosh Date: Fri, 28 Mar 2025 01:17:38 +0100 Subject: [PATCH] added LoRa communication device code --- LoRa_esp32_comm/LoRa_esp32_comm.ino | 618 ++++++++++++++++++++++++++++ 1 file changed, 618 insertions(+) create mode 100644 LoRa_esp32_comm/LoRa_esp32_comm.ino diff --git a/LoRa_esp32_comm/LoRa_esp32_comm.ino b/LoRa_esp32_comm/LoRa_esp32_comm.ino new file mode 100644 index 0000000..d76df5b --- /dev/null +++ b/LoRa_esp32_comm/LoRa_esp32_comm.ino @@ -0,0 +1,618 @@ +#include +#include +#include +#include +#include +#include + +HardwareSerial uart(0); + +// WiFi credential +// Use different ssid for both module to avoid confusion +// example: +// const char* ssid = "ESP32-LoRa-Chat1"; for user 1 +// const char* ssid = "ESP32-LoRa-Chat2"; for user 2 +const char* ssid = "ESP32-LoRa-Chat"; +const char* password = "chatpass123"; + +WebServer server(80); + +#define MAX_MESSAGES 50 +String messageBuffer[MAX_MESSAGES]; +int messageCount = 0; + +const char index_html[] PROGMEM = R"rawliteral( + + + + + + ESP32 LoRa Chat + + + +
+ +
+ +
+ Connecting... +
+ +
+
+
+ + +
+
+ + + + +)rawliteral"; + +void LoRa_Join(){ + uint32_t time = millis(); + bool msg_done = true; + + uart.println("AT+MODE=LWOTAA"); + delay(1000); + + while(1){ + if(msg_done){ + uart.println("AT+JOIN"); + msg_done = false; + } + if(uart.available()){ + String str = uart.readStringUntil('\n'); + Serial.println(str); + + if(strcmp(str.c_str(), "+JOIN: Join failed\r") == 0){ + msg_done = true; + } + if(strcmp(str.c_str(), "+JOIN: Done\r") == 0){ + if(!msg_done){ + break; + } + } + } + } +} + +void LoRa_Send_MSG(char* msg){ + uart.println(msg); + while(1){ + if(uart.available()){ + String str = uart.readStringUntil('\n'); + Serial.println(str); + if(strcmp(str.c_str(), "+MSG: Done\r") == 0){ + break; + } + } + } +} + +uint8_t lora_msg[32][51]; + +void LoRa_Send_MSGHEX(const char* msg){//parses string into multiple messages if needed + //clear send buffer + for(int i = 0; i < 32; i++){ + for(int j = 0; j < 51; j++){ + lora_msg[i][j] = 0; + } + } + //get how many messages we will need (32 max = 1536 characters) + int len = strlen(msg); + int msg_no = len / 48; + if((len % 48) != 0){ + msg_no ++; + } + //prepare messages + for(int i = 0; i < msg_no; i++){ + if(len > 48){ + lora_msg[i][0] = 51; + lora_msg[i][1] = i+1; + lora_msg[i][2] = msg_no; + for(int j = 0; j < 48; j++){ + lora_msg[i][3+j] = msg[j+i*48]; + } + len -= 48; + } + else{ + lora_msg[i][0] = len+3; + lora_msg[i][1] = i+1; + lora_msg[i][2] = msg_no; + for(int j = 0; j < len; j++){ + lora_msg[i][3+j] = msg[j+i*48]; + } + len = 0; + } + } + //send messages + for(int i = 0; i < 32; i++){ + if(lora_msg[i][0] != 0){ + uart.print("AT+MSGHEX=\""); + Serial.print("AT+MSGHEX=\""); + for(int j = 0; j < lora_msg[i][0]; j++){ + uart.printf("%02X",lora_msg[i][j]); + Serial.printf("%02X",lora_msg[i][j]); + } + uart.println("\""); + Serial.println("\""); + } + else{ + return; + } + + while(1){ + if(uart.available()){ + String str = uart.readStringUntil('\n'); + Serial.println(str); + if(strcmp(str.c_str(), "+MSGHEX: Done\r") == 0){ + break; + } + } + } + } +} + +int asciiToHex(char *asciiHexChar){ + uint8_t hi, lo; + uint8_t x; + + x = (asciiHexChar[0] & 0x4F); + hi = (x & 0x0F) + ((x >> 6) * 9); + x = (asciiHexChar[1] & 0x4F); + lo = (x & 0x0F) + ((x >> 6) * 9); + + return (hi << 4) + lo; +} + + +int rx_buffer[32][51]; +int rx_index = 0; + +void LoRa_Receive_MSG(){ + if(uart.available()){ + String str = uart.readStringUntil('\n'); + Serial.println(str); + if(str.indexOf("MSG: PORT: 1; RX:") > 0){ + char rxBytes[3] = {0,0,0}; + int rx_len = 51; + for(int i = 0; i < rx_len; i++){ + for(int j = 0; j < 2; j++){ + rxBytes[j] = str.c_str()[i*2+j+20]; + } + rx_buffer[rx_index][i] = asciiToHex(rxBytes); + if(i == 0){ + rx_len = rx_buffer[rx_index][0]; + } + } + if(rx_buffer[rx_index][1] == rx_buffer[rx_index][2]){ + //transmit whole message + rx_index = 0; + String rxString = ""; + + for(int i = 0; i < 32; i++){ + for(int j = 3; j < (rx_buffer[i][0]); j++){ + rxString += (char)rx_buffer[i][j]; + } + if(rx_buffer[i][0] < 51){ + break; + } + } + addMessageToBuffer(rxString); + } + } + } +} + +void setup() { + Serial.begin(115200); + uart.begin(9600, SERIAL_8N1, RX, TX); + + if(!SPIFFS.begin(true)) { + Serial.println("SPIFFS initialization failed!"); + return; + } + + Serial.println("Initializing LoRa..."); + //add LoRa E5 module init here + pinMode(5, OUTPUT); + digitalWrite(5, LOW); + delay(1000); + digitalWrite(5, HIGH); + delay(2000); + + LoRa_Join(); + LoRa_Send_MSG("AT+MSG=\"hello\""); + delay(1000); + uart.println("AT+CLASS=C"); + //LoRa E5 module init done + + WiFi.softAP(ssid, password); + Serial.println("Access Point Started"); + Serial.print("IP Address: "); + Serial.println(WiFi.softAPIP()); + + server.on("/", HTTP_GET, handleRoot); + server.on("/send", HTTP_POST, handleSendMessage); + server.on("/messages", HTTP_GET, handleGetMessages); + + server.begin(); + Serial.println("Web Server Started"); +} + +void handleRoot() { + server.send(200, "text/html", index_html); +} + +void handleSendMessage() { + if (server.hasArg("plain")) { + StaticJsonDocument<200> doc; + DeserializationError error = deserializeJson(doc, server.arg("plain")); + + if (!error) { + String message = doc["message"].as(); + String sender = doc["sender"].as(); + + Serial.println("Sending message"); + Serial.print("Sender: "); + Serial.println(sender); + Serial.print("Message: "); + Serial.println(message); + + String lora_msg = sender + ": " + message; + LoRa_Send_MSGHEX(lora_msg.c_str()); + + addMessageToBuffer(sender + ": " + message); + + server.send(200, "application/json", "{\"status\":\"sent\"}"); + } else { + server.send(400, "application/json", "{\"error\":\"Invalid JSON\"}"); + } + } +} + +void handleGetMessages() { + StaticJsonDocument<2048> doc; + JsonArray array = doc.createNestedArray("messages"); + + for(int i = 0; i < messageCount; i++) { + array.add(messageBuffer[i]); + } + + String response; + serializeJson(doc, response); + server.send(200, "application/json", response); +} + +void addMessageToBuffer(String message) { + if (messageCount >= MAX_MESSAGES) { + for(int i = 0; i < MAX_MESSAGES - 1; i++) { + messageBuffer[i] = messageBuffer[i + 1]; + } + messageCount--; + } + messageBuffer[messageCount++] = message; +} + +String incoming = ""; +int incomingByte = 0; + +void loop() { + server.handleClient(); + + LoRa_Receive_MSG(); + + //if(uart.available()){ + // String str = uart.readStringUntil('\n'); + // Serial.println(str); + // if(str.indexOf("MSG: PORT: 1; RX:") > 0){ + // Serial.println("yayy"); + // } + //} + //delay(1000); + + //if(Serial.available()){ + // String str = Serial.readStringUntil('\n'); + // uart.println(str); + //} + /* + if (Serial.available() > 0) { + incomingByte = Serial.read(); + + if(incomingByte != '#'){ + incoming += (char)incomingByte; + } + + if(incomingByte == '#'){ + addMessageToBuffer(incoming); + incoming = ""; + } + } + */ + /* + int packetSize = LoRa.parsePacket(); + if (packetSize) { + byte recipient = LoRa.read(); + byte sender = LoRa.read(); + + String incoming = ""; + while (LoRa.available()) { + incoming += (char)LoRa.read(); + } + + if (recipient == localAddress) { + addMessageToBuffer(incoming); + } + }*/ +}