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