From 00db358cc3c932c57d29433688801cc3ebfed144 Mon Sep 17 00:00:00 2001 From: richonguzman Date: Mon, 14 Oct 2024 17:04:28 -0300 Subject: [PATCH] GPS for iGate --- data_embed/index.html | 30 ++++++++++++++++ data_embed/script.js | 3 ++ platformio.ini | 8 +++++ src/LoRa_APRS_iGate.cpp | 27 ++++++++------ src/boards_pinout.h | 10 ++++++ src/configuration.cpp | 9 +++++ src/configuration.h | 2 ++ src/gps_utils.cpp | 80 ++++++++++++++++++++++++++++++----------- src/gps_utils.h | 7 ++-- src/ntp_utils.cpp | 5 +-- src/power_utils.cpp | 34 ++++++++++++++++++ src/power_utils.h | 2 ++ src/utils.cpp | 19 ++++++++-- src/web_utils.cpp | 3 ++ 14 files changed, 201 insertions(+), 38 deletions(-) diff --git a/data_embed/index.html b/data_embed/index.html index dea140f..3c942de 100644 --- a/data_embed/index.html +++ b/data_embed/index.html @@ -540,6 +540,36 @@ +
+
+ + +
+
+
+
+ + +
+

diff --git a/data_embed/script.js b/data_embed/script.js index 86d42da..068ef0e 100644 --- a/data_embed/script.js +++ b/data_embed/script.js @@ -134,6 +134,9 @@ function loadSettings(settings) { document.getElementById("beacon.sendViaAPRSIS").checked = settings.beacon.sendViaAPRSIS; document.getElementById("beacon.sendViaRF").checked = settings.beacon.sendViaRF; + document.getElementById("beacon.gpsActive").checked = settings.beacon.gpsActive; + document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity; + // Digi document.getElementById("digi.mode").value = settings.digi.mode; document.getElementById("digi.ecoMode").checked = settings.digi.ecoMode; diff --git a/platformio.ini b/platformio.ini index baf5bc6..13788e5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -113,6 +113,8 @@ build_flags = -Werror -Wall -DHELTEC_WSL_V3 -DHAS_SX1262 + -DHAS_GPS + -DGPS_BAUDRATE=115200 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = ${common.lib_deps} @@ -212,6 +214,7 @@ build_flags = -DTTGO_T_Beam_V1_2 -DHAS_SX1278 -DHAS_AXP2101 + -DHAS_GPS -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = ${common.lib_deps} @@ -226,6 +229,7 @@ build_flags = -DTTGO_T_Beam_V1_2_915 -DHAS_SX1276 -DHAS_AXP2101 + -DHAS_GPS -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = ${common.lib_deps} @@ -240,6 +244,7 @@ build_flags = -DTTGO_T_Beam_V1_0 -DHAS_SX1278 -DHAS_AXP192 + -DHAS_GPS -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = ${common.lib_deps} @@ -254,6 +259,7 @@ build_flags = -DTTGO_T_Beam_V1_0_915 -DHAS_SX1276 -DHAS_AXP192 + -DHAS_GPS -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = ${common.lib_deps} @@ -268,6 +274,7 @@ build_flags = -DTTGO_T_Beam_V1_0_SX1268 -DHAS_SX1268 -DHAS_AXP192 + -DHAS_GPS -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = ${common.lib_deps} @@ -282,6 +289,7 @@ build_flags = -DTTGO_T_Beam_V1_2_SX1262 -DHAS_SX1262 -DHAS_AXP2101 + -DHAS_GPS -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = ${common.lib_deps} diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 55d045e..ebaec36 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -13,6 +13,7 @@ ______________________________________________________________________________________________________________*/ #include +#include #include #include #include @@ -39,19 +40,23 @@ ________________________________________________________________________________ #include "A7670_utils.h" #endif -String versionDate = "2024.10.14"; -Configuration Config; -WiFiClient espClient; +String versionDate = "2024.10.14"; +Configuration Config; +WiFiClient espClient; +#ifdef HAS_GPS + HardwareSerial gpsSerial(1); + TinyGPSPlus gps; +#endif -uint8_t myWiFiAPIndex = 0; -int myWiFiAPSize = Config.wifiAPs.size(); -WiFi_AP *currentWiFi = &Config.wifiAPs[myWiFiAPIndex]; +uint8_t myWiFiAPIndex = 0; +int myWiFiAPSize = Config.wifiAPs.size(); +WiFi_AP *currentWiFi = &Config.wifiAPs[myWiFiAPIndex]; -bool isUpdatingOTA = false; -uint32_t lastBatteryCheck = 0; +bool isUpdatingOTA = false; +uint32_t lastBatteryCheck = 0; -bool backUpDigiMode = false; -bool modemLoggedToAPRSIS = false; +bool backUpDigiMode = false; +bool modemLoggedToAPRSIS = false; std::vector receivedPackets; @@ -65,7 +70,7 @@ void setup() { Utils::setupDisplay(); LoRa_Utils::setup(); Utils::validateFreqs(); - GPS_Utils::generateBeacons(); + GPS_Utils::setup(); #ifdef STARTUP_DELAY // (TEST) just to wait for WiFi init of Routers displayShow("", " STARTUP DELAY ...", "", "", 0); diff --git a/src/boards_pinout.h b/src/boards_pinout.h index fba633d..f9fe579 100644 --- a/src/boards_pinout.h +++ b/src/boards_pinout.h @@ -256,6 +256,16 @@ #define RADIO_BUSY_PIN 8 #endif +#if defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_2_915) || defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_0_915) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262) + #define GPS_RX 12 + #define GPS_TX 34 +#endif + +#if defined( HELTEC_WIRELESS_TRACKER) + #define GPS_RX 34 + #define GPS_TX 33 +#endif + /* (Same pins for LILYGO LoRa32 and ESP32 Wroom Dev ) SX1278-------------------> ESP32 ttgo-lora32-v21 and ESP32 WROOM Dev GND GND diff --git a/src/configuration.cpp b/src/configuration.cpp index 93077ca..1f677aa 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -40,6 +40,9 @@ void Configuration::writeFile() { data["beacon"]["sendViaRF"] = beacon.sendViaRF; data["beacon"]["path"] = beacon.path; + data["beacon"]["gpsActive"] = beacon.gpsActive; + data["beacon"]["gpsAmbiguity"] = beacon.gpsAmbiguity; + data["digi"]["mode"] = digi.mode; data["digi"]["ecoMode"] = digi.ecoMode; @@ -146,6 +149,9 @@ bool Configuration::readFile() { beacon.path = data["beacon"]["path"] | "WIDE1-1"; beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"] | false; beacon.sendViaRF = data["beacon"]["sendViaRF"] | false; + + beacon.gpsActive = data["beacon"]["gpsActive"] | false; + beacon.gpsAmbiguity = data["beacon"]["gpsAmbiguity"] | false; aprs_is.active = data["aprs_is"]["active"] | false; aprs_is.passcode = data["aprs_is"]["passcode"] | "XYZWV"; @@ -253,6 +259,9 @@ void Configuration::init() { beacon.sendViaAPRSIS = true; beacon.sendViaRF = false; beacon.path = "WIDE1-1"; + + beacon.gpsActive = false; + beacon.gpsAmbiguity = false; digi.mode = 0; digi.ecoMode = false; diff --git a/src/configuration.h b/src/configuration.h index 8ff6d02..6f964ea 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -28,6 +28,8 @@ public: String path; bool sendViaRF; bool sendViaAPRSIS; + bool gpsActive; + bool gpsAmbiguity; }; class APRS_IS { diff --git a/src/gps_utils.cpp b/src/gps_utils.cpp index 72918c3..8be82f2 100644 --- a/src/gps_utils.cpp +++ b/src/gps_utils.cpp @@ -1,13 +1,22 @@ #include #include #include "configuration.h" +#include "boards_pinout.h" #include "gps_utils.h" #include "display.h" #include "utils.h" -extern Configuration Config; -extern WiFiClient espClient; -String distance, iGateBeaconPacket, iGateLoRaBeaconPacket; +#ifdef GPS_BAUDRATE + #define GPS_BAUD GPS_BAUDRATE +#else + #define GPS_BAUD 9600 +#endif + +extern Configuration Config; +extern WiFiClient espClient; +extern HardwareSerial gpsSerial; +extern TinyGPSPlus gps; +String distance, iGateBeaconPacket, iGateLoRaBeaconPacket; namespace GPS_Utils { @@ -24,20 +33,32 @@ namespace GPS_Utils { return(s); } + float roundToTwoDecimals(float degrees) { + return round(degrees * 100) / 100; + } + String encodeGPS(float latitude, float longitude, const String& overlay, const String& symbol) { String encodedData = overlay; uint32_t aprs_lat, aprs_lon; - aprs_lat = 900000000 - latitude * 10000000; + + float processedLatitude = latitude; + float processedLongitude = longitude; + if (Config.beacon.gpsActive && Config.beacon.gpsAmbiguity) { + processedLatitude = roundToTwoDecimals(latitude); + processedLongitude = roundToTwoDecimals(longitude); + } + + aprs_lat = 900000000 - processedLatitude * 10000000; aprs_lat = aprs_lat / 26 - aprs_lat / 2710 + aprs_lat / 15384615; - aprs_lon = 900000000 + longitude * 10000000 / 2; + aprs_lon = 900000000 + processedLongitude * 10000000 / 2; aprs_lon = aprs_lon / 26 - aprs_lon / 2710 + aprs_lon / 15384615; String Ns, Ew, helper; - if(latitude < 0) { Ns = "S"; } else { Ns = "N"; } - if(latitude < 0) { latitude= -latitude; } + if(processedLatitude < 0) { Ns = "S"; } else { Ns = "N"; } + if(processedLatitude < 0) { processedLatitude = -processedLatitude; } - if(longitude < 0) { Ew = "W"; } else { Ew = "E"; } - if(longitude < 0) { longitude= -longitude; } + if(processedLongitude < 0) { Ew = "W"; } else { Ew = "E"; } + if(processedLongitude < 0) { processedLongitude = -processedLongitude; } char helper_base91[] = {"0000\0"}; int i; @@ -55,6 +76,19 @@ namespace GPS_Utils { return encodedData; } + void generateBeaconFirstPart() { + String beaconPacket = Config.callsign; + beaconPacket += ">APLRG1"; + if (Config.beacon.path.indexOf("WIDE") == 0) { + beaconPacket += ","; + beaconPacket += Config.beacon.path; + } + iGateBeaconPacket = beaconPacket; + iGateBeaconPacket += ",qAC:!"; + iGateLoRaBeaconPacket = beaconPacket; + iGateLoRaBeaconPacket += ":!"; + } + void generateBeacons() { if (Config.callsign.indexOf("NOCALL-10") != 0 && !Utils::checkValidCallsign(Config.callsign)) { displayShow("***** ERROR ******", "CALLSIGN = NOT VALID!", "", "Only Rx Mode Active", 3000); @@ -64,19 +98,8 @@ namespace GPS_Utils { Config.beacon.sendViaRF = false; Config.digi.mode = 0; Config.backupDigiMode = false; - } - String beaconPacket = Config.callsign; - beaconPacket += ">APLRG1"; - if (Config.beacon.path.indexOf("WIDE") == 0) { - beaconPacket += ","; - beaconPacket += Config.beacon.path; } - - iGateBeaconPacket = beaconPacket; - iGateBeaconPacket += ",qAC:!"; - iGateLoRaBeaconPacket = beaconPacket; - iGateLoRaBeaconPacket += ":!"; - + generateBeaconFirstPart(); String encodedGPS = encodeGPS(Config.beacon.latitude, Config.beacon.longitude, Config.beacon.overlay, Config.beacon.symbol); iGateBeaconPacket += encodedGPS; iGateLoRaBeaconPacket += encodedGPS; @@ -184,4 +207,19 @@ namespace GPS_Utils { } } + void setup() { + #ifdef HAS_GPS + if (Config.beacon.gpsActive) { + gpsSerial.begin(GPS_BAUD, SERIAL_8N1, GPS_TX, GPS_RX); + } + #endif + generateBeacons(); + } + + void getData() { + while (gpsSerial.available() > 0) { + gps.encode(gpsSerial.read()); + } + } + } \ No newline at end of file diff --git a/src/gps_utils.h b/src/gps_utils.h index bd20a0d..42c8d19 100644 --- a/src/gps_utils.h +++ b/src/gps_utils.h @@ -5,16 +5,19 @@ namespace GPS_Utils { - + String getiGateLoRaBeaconPacket(); char *ax25_base91enc(char *s, uint8_t n, uint32_t v); String encodeGPS(float latitude, float longitude, const String& overlay, const String& symbol); + void generateBeaconFirstPart(); void generateBeacons(); - //double calculateDistanceCourse(double latitude, double longitude); String decodeEncodedGPS(const String& packet); String getReceivedGPS(const String& packet); String getDistanceAndComment(const String& packet); + void setup(); + void getData(); + } #endif \ No newline at end of file diff --git a/src/ntp_utils.cpp b/src/ntp_utils.cpp index 2955f0a..3fb1dff 100644 --- a/src/ntp_utils.cpp +++ b/src/ntp_utils.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "configuration.h" #include "ntp_utils.h" #include "time.h" @@ -14,7 +15,7 @@ NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 15 * 60 * 1000); // Update in namespace NTP_Utils { void setup() { - if (!Config.digi.ecoMode && Config.callsign != "NOCALL-10") { + if (WiFi.status() == WL_CONNECTED && !Config.digi.ecoMode && Config.callsign != "NOCALL-10") { int gmt = Config.ntp.gmtCorrection * 3600; timeClient.setTimeOffset(gmt); timeClient.begin(); @@ -22,7 +23,7 @@ namespace NTP_Utils { } void update() { - if (!Config.digi.ecoMode && Config.callsign != "NOCALL-10") timeClient.update(); + if (WiFi.status() == WL_CONNECTED && !Config.digi.ecoMode && Config.callsign != "NOCALL-10") timeClient.update(); } String getFormatedTime() { diff --git a/src/power_utils.cpp b/src/power_utils.cpp index ae2ff3a..5a394a9 100644 --- a/src/power_utils.cpp +++ b/src/power_utils.cpp @@ -47,6 +47,36 @@ namespace POWER_Utils { #endif } + void activateGPS() { + #ifdef HAS_AXP192 + PMU.setLDO3Voltage(3300); + PMU.enableLDO3(); + #endif + + #ifdef HAS_AXP2101 + PMU.setALDO3Voltage(3300); + PMU.enableALDO3(); + #endif + #ifdef HELTEC_WIRELESS_TRACKER + digitalWrite(VEXT_CTRL, HIGH); + #endif + //gpsIsActive = true; + } + + void deactivateGPS() { + #ifdef HAS_AXP192 + PMU.disableLDO3(); + #endif + + #ifdef HAS_AXP2101 + PMU.disableALDO3(); + #endif + #ifdef HELTEC_WIRELESS_TRACKER + digitalWrite(VEXT_CTRL, LOW); + #endif + //gpsIsActive = false; + } + void activateLoRa() { #ifdef HAS_AXP192 PMU.setLDO2Voltage(3300); @@ -159,6 +189,10 @@ namespace POWER_Utils { #endif #endif + #ifdef HAS_GPS + if (Config.beacon.gpsActive) activateGPS(); + #endif + #ifdef ADC_CTRL pinMode(ADC_CTRL, OUTPUT); #endif diff --git a/src/power_utils.h b/src/power_utils.h index 8388f3b..0320cc3 100644 --- a/src/power_utils.h +++ b/src/power_utils.h @@ -14,6 +14,8 @@ namespace POWER_Utils { double getBatteryVoltage(); bool isBatteryConnected(); void activateMeasurement(); + void activateGPS(); + void deactivateGPS(); void activateLoRa(); void deactivateLoRa(); bool begin(TwoWire &port); diff --git a/src/utils.cpp b/src/utils.cpp index bfc6953..77ba1dd 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,3 +1,4 @@ +#include #include #include "configuration.h" #include "station_utils.h" @@ -13,8 +14,10 @@ #include "display.h" #include "utils.h" + extern Configuration Config; extern WiFiClient espClient; +extern TinyGPSPlus gps; extern String versionDate; extern String firstLine; extern String secondLine; @@ -195,8 +198,20 @@ namespace Utils { activeStations(); - String beaconPacket = iGateBeaconPacket; - String secondaryBeaconPacket = iGateLoRaBeaconPacket; + String beaconPacket = iGateBeaconPacket; + String secondaryBeaconPacket = iGateLoRaBeaconPacket; + #ifdef HAS_GPS + if (Config.beacon.gpsActive && !Config.digi.ecoMode) { + GPS_Utils::getData(); + if (gps.location.isUpdated()) { + GPS_Utils::generateBeaconFirstPart(); + String encodedGPS = GPS_Utils::encodeGPS(gps.location.lat(), gps.location.lng(), Config.beacon.overlay, Config.beacon.symbol); + beaconPacket = iGateBeaconPacket + encodedGPS; + secondaryBeaconPacket = iGateLoRaBeaconPacket + encodedGPS; + } + } + #endif + if (Config.wxsensor.active && wxModuleType != 0) { String sensorData = WX_Utils::readDataSensor(); beaconPacket += sensorData; diff --git a/src/web_utils.cpp b/src/web_utils.cpp index 00d7b02..698dd11 100644 --- a/src/web_utils.cpp +++ b/src/web_utils.cpp @@ -134,6 +134,9 @@ namespace WEB_Utils { Config.beacon.symbol = request->getParam("beacon.symbol", true)->value(); Config.beacon.path = request->getParam("beacon.path", true)->value(); + Config.beacon.gpsActive = request->hasParam("beacon.gpsActive", true); + Config.beacon.gpsAmbiguity = request->hasParam("beacon.gpsAmbiguity", true); + Config.digi.mode = request->getParam("digi.mode", true)->value().toInt(); Config.digi.ecoMode = request->hasParam("digi.ecoMode", true);