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);