diff --git a/include/telemetry_utils.h b/include/telemetry_utils.h
index 77df52e..dc2a160 100644
--- a/include/telemetry_utils.h
+++ b/include/telemetry_utils.h
@@ -1,17 +1,17 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
- *
+ *
* This file is part of LoRa APRS iGate.
- *
+ *
* LoRa APRS iGate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with LoRa APRS iGate. If not, see .
*/
@@ -27,7 +27,8 @@ namespace TELEMETRY_Utils {
void sendEquationsUnitsParameters();
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType);
String generateEncodedTelemetry();
-
+ void checkEUPInterval();
+
}
#endif
\ No newline at end of file
diff --git a/src/station_utils.cpp b/src/station_utils.cpp
index bcd4ea0..6831d76 100644
--- a/src/station_utils.cpp
+++ b/src/station_utils.cpp
@@ -40,6 +40,7 @@ std::vector lastHeardObjects;
struct OutputPacketBuffer {
String packet;
bool isBeacon;
+ OutputPacketBuffer(const String& p, bool b) : packet(p), isBeacon(b) {}
};
std::vector outputPacketBuffer;
@@ -57,19 +58,18 @@ namespace STATION_Utils {
std::vector loadCallsignList(const String& list) {
std::vector loadedList;
+ int start = 0;
+ int listLength = list.length();
- String callsigns = list;
- callsigns.trim();
+ while (start < listLength) {
+ while (start < listLength && list[start] == ' ') start++; // avoid blank spaces
+ if (start >= listLength) break;
- while (callsigns.length() > 0) { // != ""
- int spaceIndex = callsigns.indexOf(" ");
- if (spaceIndex == -1) { // No more spaces, add the last part
- loadedList.push_back(callsigns);
- break;
- }
- loadedList.push_back(callsigns.substring(0, spaceIndex));
- callsigns = callsigns.substring(spaceIndex + 1);
- callsigns.trim(); // Trim in case of multiple spaces
+ int end = start;
+ while (end < listLength && list[end] != ' ') end++; // find another blank space or reach listLength
+
+ loadedList.emplace_back(list.substring(start, end));
+ start = end + 1; // keep on searching if listLength not reached
}
return loadedList;
}
@@ -126,36 +126,33 @@ namespace STATION_Utils {
}
void deleteNotHeard() {
- std::vector lastHeardStation_temp;
- for (int i = 0; i < lastHeardStations.size(); i++) {
- if (millis() - lastHeardStations[i].lastHeardTime < Config.rememberStationTime * 60 * 1000) {
- lastHeardStation_temp.push_back(lastHeardStations[i]);
+ uint32_t currentTime = millis();
+ uint32_t timeout = Config.rememberStationTime * 60UL * 1000UL;
+
+ for (int i = lastHeardStations.size() - 1; i >= 0; i--) {
+ if (currentTime - lastHeardStations[i].lastHeardTime >= timeout) {
+ lastHeardStations.erase(lastHeardStations.begin() + i);
}
}
- lastHeardStations.clear();
- for (int j = 0; j < lastHeardStation_temp.size(); j++) {
- lastHeardStations.push_back(lastHeardStation_temp[j]);
- }
- lastHeardStation_temp.clear();
}
void updateLastHeard(const String& station) {
deleteNotHeard();
- bool stationHeard = false;
- for (int i = 0; i < lastHeardStations.size(); i++) {
+ uint32_t currentTime = millis();
+ for (size_t i = 0; i < lastHeardStations.size(); i++) {
if (lastHeardStations[i].station == station) {
- lastHeardStations[i].lastHeardTime = millis();
- stationHeard = true;
- break;
+ lastHeardStations[i].lastHeardTime = currentTime;
+ Utils::showActiveStations();
+ return;
}
}
- if (!stationHeard) lastHeardStations.emplace_back(LastHeardStation{millis(), station});
+ lastHeardStations.emplace_back(LastHeardStation{currentTime, station});
Utils::showActiveStations();
}
bool wasHeard(const String& station) {
deleteNotHeard();
- for (int i = 0; i < lastHeardStations.size(); i++) {
+ for (size_t i = 0; i < lastHeardStations.size(); i++) {
if (lastHeardStations[i].station == station) {
Utils::println(" ---> Listened Station");
return true;
@@ -184,9 +181,9 @@ namespace STATION_Utils {
}
bool isIn25SegHashBuffer(const String& station, const String& textMessage) {
- uint32_t newHash = makeHash(station, textMessage);
- uint32_t currentTime = millis();
clean25SegHashBuffer();
+ uint32_t newHash = makeHash(station, textMessage);
+ uint32_t currentTime = millis();
for (int i = 0; i < packet25SegBuffer.size(); i++) {
if (packet25SegBuffer[i].hash == newHash) return true;
}
@@ -243,11 +240,7 @@ namespace STATION_Utils {
}
void addToOutputPacketBuffer(const String& packet, bool flag) {
- OutputPacketBuffer entry;
- entry.packet = packet;
- entry.isBeacon = flag;
-
- outputPacketBuffer.push_back(entry);
+ outputPacketBuffer.emplace_back(OutputPacketBuffer{packet, flag});
}
}
\ No newline at end of file
diff --git a/src/telemetry_utils.cpp b/src/telemetry_utils.cpp
index 99c4310..bf14a51 100644
--- a/src/telemetry_utils.cpp
+++ b/src/telemetry_utils.cpp
@@ -1,17 +1,17 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
- *
+ *
* This file is part of LoRa APRS iGate.
- *
+ *
* LoRa APRS iGate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with LoRa APRS iGate. If not, see .
*/
@@ -29,10 +29,11 @@
#include "display.h"
-extern Configuration Config;
-extern bool sendStartTelemetry;
+extern Configuration Config;
-int telemetryCounter = random(1,999);
+int telemetryCounter = random(1,999);
+uint32_t telemetryEUPTime = 0;
+bool sendEUP = false; // Equations Units Parameters
namespace TELEMETRY_Utils {
@@ -89,7 +90,7 @@ namespace TELEMETRY_Utils {
sendBaseTelemetryPacket("EQNS.", getEquationCoefficients());
sendBaseTelemetryPacket("UNIT.", getUnitLabels());
sendBaseTelemetryPacket("PARM.", getParameterNames());
- sendStartTelemetry = false;
+ sendEUP = false;
}
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType) {
@@ -106,7 +107,7 @@ namespace TELEMETRY_Utils {
case 3: tempValue = (value * 8); break; // Pressure
default: tempValue = value; break;
}
- }
+ }
int firstByte = tempValue / 91;
tempValue -= firstByte * 91;
@@ -127,4 +128,11 @@ namespace TELEMETRY_Utils {
return telemetry;
}
+ void checkEUPInterval() {
+ if (telemetryEUPTime == 0 || millis() - telemetryEUPTime > 24UL * 60UL * 60UL * 1000UL) {
+ sendEUP = true;
+ telemetryEUPTime = millis();
+ }
+ }
+
}
\ No newline at end of file
diff --git a/src/utils.cpp b/src/utils.cpp
index 58a91f0..e4e029d 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -58,11 +58,12 @@ extern bool backupDigiMode;
extern bool shouldSleepLowVoltage;
extern bool transmitFlag;
extern bool passcodeValid;
+extern bool sendEUP; // Equations Units Parameters
extern std::vector lastHeardStations;
bool statusAfterBoot = true;
-bool sendStartTelemetry = true;
+
bool beaconUpdate = false;
uint32_t lastBeaconTx = 0;
uint32_t lastScreenOn = millis();
@@ -157,7 +158,8 @@ namespace Utils {
if (beaconUpdate) {
if (!Config.display.alwaysOn && Config.display.timeout != 0) displayToggle(true);
- if (sendStartTelemetry &&
+ TELEMETRY_Utils::checkEUPInterval();
+ if (sendEUP &&
Config.battery.sendVoltageAsTelemetry &&
!Config.wxsensor.active &&
(Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) &&