Files
LoRaGPSSenderReceiver/LoRaSender/LoRaSender.ino
T

162 lines
3.8 KiB
Arduino

#include <SPI.h>
#include <LoRa.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
// 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);
}
}
}