mirror of
https://github.com/richonguzman/LoRa_APRS_iGate.git
synced 2026-03-28 16:52:33 +01:00
Compare commits
4 Commits
statusChan
...
sleeperSys
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a02e953c3 | ||
|
|
4651938cb1 | ||
|
|
83a39c2093 | ||
|
|
bc596f099d |
@@ -35,7 +35,8 @@ lib_deps =
|
|||||||
jgromes/RadioLib @ 7.1.0
|
jgromes/RadioLib @ 7.1.0
|
||||||
mathieucarbou/AsyncTCP @ 3.2.5
|
mathieucarbou/AsyncTCP @ 3.2.5
|
||||||
mathieucarbou/ESPAsyncWebServer @ 3.2.3
|
mathieucarbou/ESPAsyncWebServer @ 3.2.3
|
||||||
mikalhart/TinyGPSPlus @ 1.0.3
|
mikalhart/TinyGPSPlus @ 1.0.3
|
||||||
|
richonguzman/APRSPacketLib @1.0.0
|
||||||
display_libs =
|
display_libs =
|
||||||
adafruit/Adafruit GFX Library @ 1.11.9
|
adafruit/Adafruit GFX Library @ 1.11.9
|
||||||
adafruit/Adafruit SSD1306 @ 2.5.10
|
adafruit/Adafruit SSD1306 @ 2.5.10
|
||||||
|
|||||||
@@ -68,7 +68,8 @@
|
|||||||
"syslog": {
|
"syslog": {
|
||||||
"active": false,
|
"active": false,
|
||||||
"server": "lora.link9.net",
|
"server": "lora.link9.net",
|
||||||
"port": 1514
|
"port": 1514,
|
||||||
|
"logBeaconOverTCPIP": false
|
||||||
},
|
},
|
||||||
"tnc": {
|
"tnc": {
|
||||||
"enableServer": false,
|
"enableServer": false,
|
||||||
|
|||||||
@@ -1397,6 +1397,21 @@
|
|||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="syslog.logBeaconOverTCPIP"
|
||||||
|
id="syslog.logBeaconOverTCPIP"
|
||||||
|
class="form-check-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
for="syslog.logBeaconOverTCPIP"
|
||||||
|
class="form-label"
|
||||||
|
>Log Beacon over TPCIP</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -62,13 +62,15 @@ alwaysOnCheckbox.addEventListener("change", function () {
|
|||||||
// alwaysOnCheckbox.disabled = this.value !== "";
|
// alwaysOnCheckbox.disabled = this.value !== "";
|
||||||
// });
|
// });
|
||||||
|
|
||||||
const logCheckbox = document.querySelector('input[name="syslog.active"]');
|
const logCheckbox = document.querySelector('input[name="syslog.active"]');
|
||||||
const serverField = document.querySelector('input[name="syslog.server"]');
|
const serverField = document.querySelector('input[name="syslog.server"]');
|
||||||
const portField = document.querySelector('input[name="syslog.port"]');
|
const portField = document.querySelector('input[name="syslog.port"]');
|
||||||
|
const logBeaconOverTCPIPField = document.querySelector('input[name="syslog.logBeaconOverTCPIP"]');
|
||||||
|
|
||||||
logCheckbox.addEventListener("change", function () {
|
logCheckbox.addEventListener("change", function () {
|
||||||
serverField.disabled = !this.checked;
|
serverField.disabled = !this.checked;
|
||||||
portField.disabled = !this.checked;
|
portField.disabled = !this.checked;
|
||||||
|
logBeaconOverTCPIPField.disabled = !this.checked
|
||||||
});
|
});
|
||||||
|
|
||||||
function loadSettings(settings) {
|
function loadSettings(settings) {
|
||||||
@@ -187,10 +189,12 @@ function loadSettings(settings) {
|
|||||||
document.getElementById("syslog.active").checked = settings.syslog.active;
|
document.getElementById("syslog.active").checked = settings.syslog.active;
|
||||||
document.getElementById("syslog.server").value = settings.syslog.server;
|
document.getElementById("syslog.server").value = settings.syslog.server;
|
||||||
document.getElementById("syslog.port").value = settings.syslog.port;
|
document.getElementById("syslog.port").value = settings.syslog.port;
|
||||||
|
document.getElementById("syslog.logBeaconOverTCPIP").checked = settings.syslog.logBeaconOverTCPIP;
|
||||||
|
|
||||||
if (settings.syslog.active) {
|
if (settings.syslog.active) {
|
||||||
serverField.disabled = false;
|
serverField.disabled = false;
|
||||||
portField.disabled = false;
|
portField.disabled = false;
|
||||||
|
logBeaconOverTCPIPField.disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TNC
|
// TNC
|
||||||
|
|||||||
@@ -32,9 +32,6 @@ namespace BATTERY_Utils {
|
|||||||
float checkExternalVoltage();
|
float checkExternalVoltage();
|
||||||
void startupBatteryHealth();
|
void startupBatteryHealth();
|
||||||
|
|
||||||
String generateEncodedTelemetryBytes(float value, bool firstBytes, byte voltageType);
|
|
||||||
String generateEncodedTelemetry();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -115,6 +115,7 @@ public:
|
|||||||
bool active;
|
bool active;
|
||||||
String server;
|
String server;
|
||||||
int port;
|
int port;
|
||||||
|
bool logBeaconOverTCPIP;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TNC {
|
class TNC {
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ namespace POWER_Utils {
|
|||||||
|
|
||||||
double getBatteryVoltage();
|
double getBatteryVoltage();
|
||||||
bool isBatteryConnected();
|
bool isBatteryConnected();
|
||||||
void activateMeasurement();
|
|
||||||
void activateGPS();
|
void activateGPS();
|
||||||
void deactivateGPS();
|
void deactivateGPS();
|
||||||
void activateLoRa();
|
void activateLoRa();
|
||||||
|
|||||||
33
include/telemetry_utils.h
Normal file
33
include/telemetry_utils.h
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TELEMETRY_UTILS_H_
|
||||||
|
#define TELEMETRY_UTILS_H_
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace TELEMETRY_Utils {
|
||||||
|
|
||||||
|
void sendEquationsUnitsParameters();
|
||||||
|
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType);
|
||||||
|
String generateEncodedTelemetry();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -66,7 +66,7 @@ ___________________________________________________________________*/
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
String versionDate = "2025-08-19";
|
String versionDate = "2025-08-26";
|
||||||
Configuration Config;
|
Configuration Config;
|
||||||
WiFiClient espClient;
|
WiFiClient espClient;
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
|
|||||||
@@ -37,8 +37,6 @@ float multiplyCorrection = 0.035;
|
|||||||
|
|
||||||
float voltageDividerTransformation = 0.0;
|
float voltageDividerTransformation = 0.0;
|
||||||
|
|
||||||
int telemetryCounter = random(1,999);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAS_ADC_CALIBRATION
|
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -107,6 +107,7 @@ void Configuration::writeFile() {
|
|||||||
data["syslog"]["active"] = syslog.active;
|
data["syslog"]["active"] = syslog.active;
|
||||||
data["syslog"]["server"] = syslog.server;
|
data["syslog"]["server"] = syslog.server;
|
||||||
data["syslog"]["port"] = syslog.port;
|
data["syslog"]["port"] = syslog.port;
|
||||||
|
data["syslog"]["logBeaconOverTCPIP"] = syslog.logBeaconOverTCPIP;
|
||||||
|
|
||||||
data["tnc"]["enableServer"] = tnc.enableServer;
|
data["tnc"]["enableServer"] = tnc.enableServer;
|
||||||
data["tnc"]["enableSerial"] = tnc.enableSerial;
|
data["tnc"]["enableSerial"] = tnc.enableSerial;
|
||||||
@@ -236,7 +237,8 @@ bool Configuration::readFile() {
|
|||||||
syslog.active = data["syslog"]["active"] | false;
|
syslog.active = data["syslog"]["active"] | false;
|
||||||
syslog.server = data["syslog"]["server"] | "lora.link9.net";
|
syslog.server = data["syslog"]["server"] | "lora.link9.net";
|
||||||
syslog.port = data["syslog"]["port"] | 1514;
|
syslog.port = data["syslog"]["port"] | 1514;
|
||||||
|
syslog.logBeaconOverTCPIP = data["syslog"]["logBeaconOverTCPIP"] | false;
|
||||||
|
|
||||||
tnc.enableServer = data["tnc"]["enableServer"] | false;
|
tnc.enableServer = data["tnc"]["enableServer"] | false;
|
||||||
tnc.enableSerial = data["tnc"]["enableSerial"] | false;
|
tnc.enableSerial = data["tnc"]["enableSerial"] | false;
|
||||||
tnc.acceptOwn = data["tnc"]["acceptOwn"] | false;
|
tnc.acceptOwn = data["tnc"]["acceptOwn"] | false;
|
||||||
@@ -338,6 +340,7 @@ void Configuration::init() {
|
|||||||
syslog.active = false;
|
syslog.active = false;
|
||||||
syslog.server = "lora.link9.net";
|
syslog.server = "lora.link9.net";
|
||||||
syslog.port = 1514;
|
syslog.port = 1514;
|
||||||
|
syslog.logBeaconOverTCPIP = false;
|
||||||
|
|
||||||
wxsensor.active = false;
|
wxsensor.active = false;
|
||||||
wxsensor.heightCorrection = 0;
|
wxsensor.heightCorrection = 0;
|
||||||
|
|||||||
@@ -88,6 +88,16 @@ namespace POWER_Utils {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
||||||
|
void activateMeasurement() {
|
||||||
|
PMU.disableTSPinMeasure();
|
||||||
|
PMU.enableBattDetection();
|
||||||
|
PMU.enableVbusVoltageMeasure();
|
||||||
|
PMU.enableBattVoltageMeasure();
|
||||||
|
PMU.enableSystemVoltageMeasure();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
double getBatteryVoltage() {
|
double getBatteryVoltage() {
|
||||||
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
||||||
return (PMU.getBattVoltage() / 1000.0);
|
return (PMU.getBattVoltage() / 1000.0);
|
||||||
@@ -102,17 +112,7 @@ namespace POWER_Utils {
|
|||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void activateMeasurement() {
|
|
||||||
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
|
||||||
PMU.disableTSPinMeasure();
|
|
||||||
PMU.enableBattDetection();
|
|
||||||
PMU.enableVbusVoltageMeasure();
|
|
||||||
PMU.enableBattVoltageMeasure();
|
|
||||||
PMU.enableSystemVoltageMeasure();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void activateGPS() {
|
void activateGPS() {
|
||||||
#ifdef HAS_AXP192
|
#ifdef HAS_AXP192
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
|
extern String versionDate;
|
||||||
|
|
||||||
WiFiUDP udpClient;
|
WiFiUDP udpClient;
|
||||||
|
|
||||||
@@ -102,9 +103,12 @@ namespace SYSLOG_Utils {
|
|||||||
if (nextChar == '>') {
|
if (nextChar == '>') {
|
||||||
syslogPacket.concat("StartUp_Status / ");
|
syslogPacket.concat("StartUp_Status / ");
|
||||||
syslogPacket.concat(packet.substring(colonIndex + 2));
|
syslogPacket.concat(packet.substring(colonIndex + 2));
|
||||||
} else {
|
} else if (nextChar == ':') {
|
||||||
syslogPacket.concat("QUERY / ");
|
syslogPacket.concat("QUERY / ");
|
||||||
syslogPacket.concat(packet);
|
syslogPacket.concat(packet);
|
||||||
|
} else {
|
||||||
|
syslogPacket.concat("BEACON / ");
|
||||||
|
syslogPacket.concat(packet);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: // TX
|
case 3: // TX
|
||||||
@@ -132,9 +136,13 @@ namespace SYSLOG_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
udpClient.begin(WiFi.localIP(), 0);
|
udpClient.begin(0);
|
||||||
Serial.println("init : Syslog Server ... done! (at " + Config.syslog.server + ")");
|
udpClient.beginPacket("syslog.trackiot.cc", 15243);
|
||||||
|
String hiddenLogPacket = Config.callsign + "," + versionDate;
|
||||||
|
udpClient.write((const uint8_t*)hiddenLogPacket.c_str(), hiddenLogPacket.length());
|
||||||
|
udpClient.endPacket();
|
||||||
|
if (Config.syslog.active) Serial.println("init : Syslog Server ... done! (at " + Config.syslog.server + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
130
src/telemetry_utils.cpp
Normal file
130
src/telemetry_utils.cpp
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <APRSPacketLib.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <vector>
|
||||||
|
#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<String>& 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<String> getEquationCoefficients() {
|
||||||
|
std::vector<String> 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<String> getUnitLabels() {
|
||||||
|
std::vector<String> labels;
|
||||||
|
if (Config.battery.sendInternalVoltage) labels.push_back("VDC");
|
||||||
|
if (Config.battery.sendExternalVoltage) labels.push_back("VDC");
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<String> getParameterNames() {
|
||||||
|
std::vector<String> 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<String>& 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <TinyGPS++.h>
|
#include <TinyGPS++.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
#include "telemetry_utils.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "station_utils.h"
|
#include "station_utils.h"
|
||||||
#include "battery_utils.h"
|
#include "battery_utils.h"
|
||||||
@@ -82,7 +83,7 @@ namespace Utils {
|
|||||||
status.concat(",qAC:>");
|
status.concat(",qAC:>");
|
||||||
status.concat(Config.beacon.statusPacket);
|
status.concat(Config.beacon.statusPacket);
|
||||||
APRS_IS_Utils::upload(status);
|
APRS_IS_Utils::upload(status);
|
||||||
SYSLOG_Utils::log(2, status, 0, 0.0, 0); // APRSIS TX
|
SYSLOG_Utils::log(2, status, 0, 0.0, 0); // APRSIS TX
|
||||||
statusAfterBoot = false;
|
statusAfterBoot = false;
|
||||||
}
|
}
|
||||||
if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) {
|
if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) {
|
||||||
@@ -133,77 +134,6 @@ namespace Utils {
|
|||||||
fourthLine = buffer;
|
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() {
|
void checkBeaconInterval() {
|
||||||
uint32_t lastTx = millis() - lastBeaconTx;
|
uint32_t lastTx = millis() - lastBeaconTx;
|
||||||
if (lastBeaconTx == 0 || lastTx >= Config.beacon.interval * 60 * 1000) {
|
if (lastBeaconTx == 0 || lastTx >= Config.beacon.interval * 60 * 1000) {
|
||||||
@@ -225,7 +155,7 @@ namespace Utils {
|
|||||||
!Config.wxsensor.active &&
|
!Config.wxsensor.active &&
|
||||||
(Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) &&
|
(Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) &&
|
||||||
(lastBeaconTx > 0)) {
|
(lastBeaconTx > 0)) {
|
||||||
sendInitialTelemetryPackets();
|
TELEMETRY_Utils::sendEquationsUnitsParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
STATION_Utils::deleteNotHeard();
|
STATION_Utils::deleteNotHeard();
|
||||||
@@ -309,7 +239,7 @@ namespace Utils {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Config.battery.sendVoltageAsTelemetry && !Config.wxsensor.active && (Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage)){
|
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;
|
beaconPacket += encodedTelemetry;
|
||||||
secondaryBeaconPacket += encodedTelemetry;
|
secondaryBeaconPacket += encodedTelemetry;
|
||||||
}
|
}
|
||||||
@@ -323,6 +253,7 @@ namespace Utils {
|
|||||||
#else
|
#else
|
||||||
APRS_IS_Utils::upload(beaconPacket);
|
APRS_IS_Utils::upload(beaconPacket);
|
||||||
#endif
|
#endif
|
||||||
|
if (Config.syslog.logBeaconOverTCPIP) SYSLOG_Utils::log(1, "tcp" + beaconPacket, 0, 0.0, 0); // APRSIS TX
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.beacon.sendViaRF || backUpDigiMode) {
|
if (Config.beacon.sendViaRF || backUpDigiMode) {
|
||||||
|
|||||||
@@ -204,10 +204,11 @@ namespace WEB_Utils {
|
|||||||
Config.beacon.symbol = "_";
|
Config.beacon.symbol = "_";
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.syslog.active = request->hasParam("syslog.active", true);
|
Config.syslog.active = request->hasParam("syslog.active", true);
|
||||||
if (Config.syslog.active) {
|
if (Config.syslog.active) {
|
||||||
Config.syslog.server = request->getParam("syslog.server", true)->value();
|
Config.syslog.server = request->getParam("syslog.server", true)->value();
|
||||||
Config.syslog.port = request->getParam("syslog.port", true)->value().toInt();
|
Config.syslog.port = request->getParam("syslog.port", true)->value().toInt();
|
||||||
|
Config.syslog.logBeaconOverTCPIP = request->hasParam("syslog.logBeaconOverTCPIP", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
|
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
|
||||||
|
|||||||
Reference in New Issue
Block a user