#include #include #include #include #include #include #include // LORA Settings #define SYNC_WORD 0xCE #define RECEIVER_ID 0xAB // receiver #define SELF_ID 0xAA // sender #define LORA_SCK 5 #define LORA_MISO 19 #define LORA_MOSI 27 #define LORA_CS 18 #define LORA_RST 23 #define LORA_IRQ 26 #define LORA_FREQ 868E6 // GPS Settings #define _RX_GPS 23 #define _TX_GPS 22 #define _BAUDRATE_GPS 9600 // OLED Settings #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); SoftwareSerial gps_serial(_RX_GPS, _TX_GPS); TinyGPSPlus gps; void sendMessage(const String& msg) { LoRa.beginPacket(); LoRa.write(SYNC_WORD); LoRa.write(RECEIVER_ID); LoRa.write(msg.length()); LoRa.print(msg); LoRa.endPacket(true); } bool waitForPacket(unsigned long timeout_ms) { unsigned long t0 = millis(); while (millis() - t0 < timeout_ms) { if (LoRa.parsePacket()) return true; delay(5); } return false; // Timeout } bool getPacket(String& payload, byte& id) { LoRa.parsePacket(); byte sync = LoRa.read(); id = LoRa.read(); if (sync != SYNC_WORD || id != SELF_ID) { LoRa.flush(); Serial.println("Unidentifiziertes Paket: " + String(sync) + String(id)); return false; } byte len = LoRa.read(); while (LoRa.available()) payload += (char)LoRa.read(); return (payload.length() == len); } /* bool waitForAck(unsigned long timeout_ms = 1000) { if (!waitForPacket(timeout_ms)) return false; String payload; byte snd; if (!getPacket(payload, snd)) return false; return (snd == RECEIVER_ID && payload == "ACK"); } */ void showOnOLED(const String& line1, const String& line2 = "", const String& line3 = "", const String& line4 = "") { display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println(line1); if (line2.length()) { display.setCursor(0, 16); display.println(line2); } if (line3.length()) { display.setCursor(0, 32); display.println(line3); } if (line4.length()) { display.setCursor(0, 48); display.println(line4); } display.display(); } void setup() { Serial.begin(115200); gps_serial.begin(_BAUDRATE_GPS); // OLED init Wire.begin(); // SDA/SCL Default if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println("OLED init fehlgeschlagen"); while (1) delay(1000); } showOnOLED("LoRa OLED Init", "Bitte warten..."); // LoRa init SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS); LoRa.setPins(LORA_CS, LORA_RST, LORA_IRQ); if (!LoRa.begin(LORA_FREQ)) { Serial.println("Konnte LoRa nicht initialisieren!"); showOnOLED("LoRa Init fehl", "Neustart nötig"); while (1) delay(1000); } LoRa.enableCrc(); showOnOLED("LoRa bereit", "Creator:", "Timo Niemann"); } void loop() { if(gps_serial.available()){ gps.encode(gps_serial.read()); if(gps.location.isUpdated()){ Serial.println("GPS Update!"); } } if (waitForPacket(10)) { String cmd; byte snd; if (!getPacket(cmd, snd)) { showOnOLED("Fehler:", "Packet ungueltig"); return; } if (cmd == "g") { Serial.println("Empfangen: " + cmd); showOnOLED("Empfangen von:", "ID " + String(snd), "Cmd: " + cmd); String lat_str = "LAT: " + String(gps.location.lat()); String lng_str = "LON: " + String(gps.location.lng()); String satellites = "Satelliten: " + String(gps.satellites.value()); Serial.println("Sende GPS:\n" + lat_str + "\n" + lng_str); showOnOLED("Sende GPS Koords:", lat_str, lng_str, satellites); sendMessage(lat_str + "\n\n" + lng_str + "\n\n" + satellites); delay(1000); } } }