From 8a02e953c3e0f54ee815ff96695d9055f057127b Mon Sep 17 00:00:00 2001 From: richonguzman Date: Tue, 26 Aug 2025 18:33:58 -0400 Subject: [PATCH] testNewTelemetry --- common_settings.ini | 3 +- include/battery_utils.h | 3 - include/telemetry_utils.h | 33 ++++++++++ src/battery_utils.cpp | 41 ------------ src/telemetry_utils.cpp | 130 ++++++++++++++++++++++++++++++++++++++ src/utils.cpp | 76 +--------------------- 6 files changed, 168 insertions(+), 118 deletions(-) create mode 100644 include/telemetry_utils.h create mode 100644 src/telemetry_utils.cpp diff --git a/common_settings.ini b/common_settings.ini index e195b5c..6e4b012 100644 --- a/common_settings.ini +++ b/common_settings.ini @@ -35,7 +35,8 @@ lib_deps = jgromes/RadioLib @ 7.1.0 mathieucarbou/AsyncTCP @ 3.2.5 mathieucarbou/ESPAsyncWebServer @ 3.2.3 - mikalhart/TinyGPSPlus @ 1.0.3 + mikalhart/TinyGPSPlus @ 1.0.3 + richonguzman/APRSPacketLib @1.0.0 display_libs = adafruit/Adafruit GFX Library @ 1.11.9 adafruit/Adafruit SSD1306 @ 2.5.10 diff --git a/include/battery_utils.h b/include/battery_utils.h index e766906..dfdee5b 100644 --- a/include/battery_utils.h +++ b/include/battery_utils.h @@ -32,9 +32,6 @@ namespace BATTERY_Utils { float checkExternalVoltage(); void startupBatteryHealth(); - String generateEncodedTelemetryBytes(float value, bool firstBytes, byte voltageType); - String generateEncodedTelemetry(); - } #endif \ No newline at end of file diff --git a/include/telemetry_utils.h b/include/telemetry_utils.h new file mode 100644 index 0000000..77df52e --- /dev/null +++ b/include/telemetry_utils.h @@ -0,0 +1,33 @@ +/* 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 + * (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 . + */ + +#ifndef TELEMETRY_UTILS_H_ +#define TELEMETRY_UTILS_H_ + +#include + + +namespace TELEMETRY_Utils { + + void sendEquationsUnitsParameters(); + String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType); + String generateEncodedTelemetry(); + +} + +#endif \ No newline at end of file diff --git a/src/battery_utils.cpp b/src/battery_utils.cpp index 6b0ace7..478380a 100644 --- a/src/battery_utils.cpp +++ b/src/battery_utils.cpp @@ -37,8 +37,6 @@ float multiplyCorrection = 0.035; float voltageDividerTransformation = 0.0; -int telemetryCounter = random(1,999); - #ifdef HAS_ADC_CALIBRATION @@ -228,43 +226,4 @@ namespace BATTERY_Utils { } } - String generateEncodedTelemetryBytes(float value, bool firstBytes, byte voltageType) { // 0 = internal battery(0-4,2V) , 1 = external battery(0-15V) - String encodedBytes; - int tempValue; - - if (firstBytes) { - tempValue = value; - } else { - switch (voltageType) { - case 0: - tempValue = value * 100; // Internal voltage calculation - break; - case 1: - tempValue = (value * 100) / 2; // External voltage calculation - break; - default: - tempValue = value; - break; - } - } - - int firstByte = tempValue / 91; - tempValue -= firstByte * 91; - - encodedBytes = char(firstByte + 33); - encodedBytes += char(tempValue + 33); - return encodedBytes; - } - - String generateEncodedTelemetry() { - String telemetry = "|"; - telemetry += generateEncodedTelemetryBytes(telemetryCounter, true, 0); - telemetryCounter++; - if (telemetryCounter == 1000) telemetryCounter = 0; - if (Config.battery.sendInternalVoltage) telemetry += generateEncodedTelemetryBytes(checkInternalVoltage(), false, 0); - if (Config.battery.sendExternalVoltage) telemetry += generateEncodedTelemetryBytes(checkExternalVoltage(), false, 1); - telemetry += "|"; - return telemetry; - } - } \ No newline at end of file diff --git a/src/telemetry_utils.cpp b/src/telemetry_utils.cpp new file mode 100644 index 0000000..2b86d0b --- /dev/null +++ b/src/telemetry_utils.cpp @@ -0,0 +1,130 @@ +/* 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 + * (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 . + */ + +#include +#include +#include +#include "telemetry_utils.h" +#include "aprs_is_utils.h" +#include "configuration.h" +#include "station_utils.h" +#include "battery_utils.h" +#include "lora_utils.h" +#include "wx_utils.h" +#include "display.h" + + +extern Configuration Config; +extern bool sendStartTelemetry; + +int telemetryCounter = random(1,999); + + +namespace TELEMETRY_Utils { + + String joinWithCommas(const std::vector& items) { + String result; + for (size_t i = 0; i < items.size(); ++i) { + result += items[i]; + if (i < items.size() - 1) result += ","; + } + return result; + } + + std::vector getEquationCoefficients() { + std::vector coefficients; + if (Config.battery.sendInternalVoltage) coefficients.push_back("0,0.01,0"); + if (Config.battery.sendExternalVoltage) coefficients.push_back("0,0.02,0"); + return coefficients; + } + + std::vector getUnitLabels() { + std::vector labels; + if (Config.battery.sendInternalVoltage) labels.push_back("VDC"); + if (Config.battery.sendExternalVoltage) labels.push_back("VDC"); + return labels; + } + + std::vector getParameterNames() { + std::vector names; + if (Config.battery.sendInternalVoltage) names.push_back("V_Batt"); + if (Config.battery.sendExternalVoltage) names.push_back("V_Ext"); + return names; + } + + void sendBaseTelemetryPacket(const String& prefix, const std::vector& values) { + String packet = prefix + joinWithCommas(values); + + if (Config.beacon.sendViaAPRSIS) { + String baseAPRSISTelemetryPacket = APRSPacketLib::generateMessagePacket(Config.callsign, "APLRG1", "TCPIP,qAC", Config.callsign, packet); + #ifdef HAS_A7670 + A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket); + #else + APRS_IS_Utils::upload(baseAPRSISTelemetryPacket); + #endif + delay(300); + } else if (Config.beacon.sendViaRF) { + String baseRFTelemetryPacket = APRSPacketLib::generateMessagePacket(Config.callsign, "APLRG1", Config.beacon.path, Config.callsign, packet); + LoRa_Utils::sendNewPacket(baseRFTelemetryPacket); + delay(3000); + } + } + + void sendEquationsUnitsParameters() { + sendBaseTelemetryPacket("EQNS.", getEquationCoefficients()); + sendBaseTelemetryPacket("UNIT.", getUnitLabels()); + sendBaseTelemetryPacket("PARM.", getParameterNames()); + sendStartTelemetry = false; + } + + String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType) { + String encodedBytes; + int tempValue; + + if (counterBytes) { + tempValue = value; + } else { + switch (telemetryType) { + case 0: tempValue = value * 100; break; // Internal voltage (0-4,2V), Humidity, Gas calculation + case 1: tempValue = (value * 100) / 2; break; // External voltage calculation (0-15V) + case 2: tempValue = (value * 10) + 500; break; // Temperature + case 3: tempValue = (value * 8); break; // Pressure + default: tempValue = value; break; + } + } + + int firstByte = tempValue / 91; + tempValue -= firstByte * 91; + + encodedBytes = char(firstByte + 33); + encodedBytes += char(tempValue + 33); + return encodedBytes; + } + + String generateEncodedTelemetry() { + String telemetry = "|"; + telemetry += generateEncodedTelemetryBytes(telemetryCounter, true, 0); + telemetryCounter++; + if (telemetryCounter == 1000) telemetryCounter = 0; + if (Config.battery.sendInternalVoltage) telemetry += generateEncodedTelemetryBytes(BATTERY_Utils::checkInternalVoltage(), false, 0); + if (Config.battery.sendExternalVoltage) telemetry += generateEncodedTelemetryBytes(BATTERY_Utils::checkExternalVoltage(), false, 1); + telemetry += "|"; + return telemetry; + } + +} \ No newline at end of file diff --git a/src/utils.cpp b/src/utils.cpp index 4d9cbe2..e5efa40 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -18,6 +18,7 @@ #include #include +#include "telemetry_utils.h" #include "configuration.h" #include "station_utils.h" #include "battery_utils.h" @@ -133,77 +134,6 @@ namespace Utils { fourthLine = buffer; } - void sendInitialTelemetryPackets() { - char sender[10]; // 9 characters + null terminator - snprintf(sender, sizeof(sender), "%-9s", Config.callsign.c_str()); // Left-align with spaces - - String baseAPRSISTelemetryPacket = Config.callsign; - baseAPRSISTelemetryPacket += ">APLRG1,TCPIP,qAC::"; - baseAPRSISTelemetryPacket += sender; - baseAPRSISTelemetryPacket += ":"; - - String baseRFTelemetryPacket = Config.callsign; - baseRFTelemetryPacket += ">APLRG1"; - if (Config.beacon.path.indexOf("WIDE") != -1) { - baseRFTelemetryPacket += ","; - baseRFTelemetryPacket += Config.beacon.path; - } - baseRFTelemetryPacket += "::"; - baseRFTelemetryPacket += sender; - baseRFTelemetryPacket += ":"; - - String telemetryPacket1 = "EQNS."; - if (Config.battery.sendInternalVoltage) { - telemetryPacket1 += "0,0.01,0"; - } - if (Config.battery.sendExternalVoltage) { - telemetryPacket1 += String(Config.battery.sendInternalVoltage ? ",0,0.02,0" : "0,0.02,0"); - } - - String telemetryPacket2 = "UNIT."; - if (Config.battery.sendInternalVoltage) { - telemetryPacket2 += "VDC"; - } - if (Config.battery.sendExternalVoltage) { - telemetryPacket2 += String(Config.battery.sendInternalVoltage ? ",VDC" : "VDC"); - } - - String telemetryPacket3 = "PARM."; - if (Config.battery.sendInternalVoltage) { - telemetryPacket3 += "V_Batt"; - } - if (Config.battery.sendExternalVoltage) { - telemetryPacket3 += String(Config.battery.sendInternalVoltage ? ",V_Ext" : "V_Ext"); - } - - if (Config.beacon.sendViaAPRSIS) { - #ifdef HAS_A7670 - A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket + telemetryPacket1); - delay(300); - A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket + telemetryPacket2); - delay(300); - A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket + telemetryPacket3); - delay(300); - #else - APRS_IS_Utils::upload(baseAPRSISTelemetryPacket + telemetryPacket1); - delay(300); - APRS_IS_Utils::upload(baseAPRSISTelemetryPacket + telemetryPacket2); - delay(300); - APRS_IS_Utils::upload(baseAPRSISTelemetryPacket + telemetryPacket3); - delay(300); - #endif - delay(300); - } else if (Config.beacon.sendViaRF) { - LoRa_Utils::sendNewPacket(baseRFTelemetryPacket + telemetryPacket1); - delay(3000); - LoRa_Utils::sendNewPacket(baseRFTelemetryPacket + telemetryPacket2); - delay(3000); - LoRa_Utils::sendNewPacket(baseRFTelemetryPacket + telemetryPacket3); - delay(3000); - } - sendStartTelemetry = false; - } - void checkBeaconInterval() { uint32_t lastTx = millis() - lastBeaconTx; if (lastBeaconTx == 0 || lastTx >= Config.beacon.interval * 60 * 1000) { @@ -225,7 +155,7 @@ namespace Utils { !Config.wxsensor.active && (Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) && (lastBeaconTx > 0)) { - sendInitialTelemetryPackets(); + TELEMETRY_Utils::sendEquationsUnitsParameters(); } STATION_Utils::deleteNotHeard(); @@ -309,7 +239,7 @@ namespace Utils { #endif if (Config.battery.sendVoltageAsTelemetry && !Config.wxsensor.active && (Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage)){ - String encodedTelemetry = BATTERY_Utils::generateEncodedTelemetry(); + String encodedTelemetry = TELEMETRY_Utils::generateEncodedTelemetry(); beaconPacket += encodedTelemetry; secondaryBeaconPacket += encodedTelemetry; }