+
+
+
+
@@ -220,4 +222,47 @@ 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(3.987/*checkInternalVoltage()*/, false, 0);
+ if (Config.battery.sendExternalVoltage) telemetry += generateEncodedTelemetryBytes(12.123/*checkExternalVoltage()*/, false, 1);
+ telemetry += "|";
+ return telemetry;
+ }
+
}
\ No newline at end of file
diff --git a/src/battery_utils.h b/src/battery_utils.h
index 57153c36..49b17554 100644
--- a/src/battery_utils.h
+++ b/src/battery_utils.h
@@ -14,6 +14,9 @@ namespace BATTERY_Utils {
void checkIfShouldSleep(); // ????
void startupBatteryHealth();
+ String generateEncodedTelemetryBytes(float value, bool firstBytes, byte voltageType);
+ String generateEncodedTelemetry();
+
}
#endif
\ No newline at end of file
diff --git a/src/configuration.cpp b/src/configuration.cpp
index 64e20554..9aae344a 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -65,6 +65,8 @@ void Configuration::writeFile() {
data["battery"]["externalSleepVoltage"] = battery.externalSleepVoltage;
data["battery"]["voltageDividerR1"] = battery.voltageDividerR1;
data["battery"]["voltageDividerR2"] = battery.voltageDividerR2;
+
+ data["battery"]["sendVoltageAsTelemetry"] = battery.sendVoltageAsTelemetry;
data["bme"]["active"] = bme.active;
data["bme"]["heightCorrection"] = bme.heightCorrection;
@@ -176,6 +178,8 @@ bool Configuration::readFile() {
battery.voltageDividerR1 = data["battery"]["voltageDividerR1"] | 100.0;
battery.voltageDividerR2 = data["battery"]["voltageDividerR2"] | 27.0;
+ battery.sendVoltageAsTelemetry = data["battery"]["sendVoltageAsTelemetry"] | true;
+
bme.active = data["bme"]["active"] | false;
bme.heightCorrection = data["bme"]["heightCorrection"] | 0;
bme.temperatureCorrection = data["bme"]["temperatureCorrection"] | 0.0;
@@ -295,6 +299,8 @@ void Configuration::init() {
battery.voltageDividerR1 = 100.0;
battery.voltageDividerR2 = 27.0;
+ battery.sendVoltageAsTelemetry = true;
+
lowPowerMode = false;
lowVoltageCutOff = 0;
diff --git a/src/configuration.h b/src/configuration.h
index 6ed6fbc3..f8f84a6e 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -77,6 +77,7 @@ class BATTERY {
float externalSleepVoltage;
float voltageDividerR1;
float voltageDividerR2;
+ bool sendVoltageAsTelemetry;
};
class BME {
diff --git a/src/gps_utils.cpp b/src/gps_utils.cpp
index d1210bd3..72918c3d 100644
--- a/src/gps_utils.cpp
+++ b/src/gps_utils.cpp
@@ -50,7 +50,7 @@ namespace GPS_Utils {
encodedData += helper_base91[i];
}
encodedData += symbol;
- encodedData += " x";
+ encodedData += " ";
encodedData += "\x47";
return encodedData;
}
diff --git a/src/utils.cpp b/src/utils.cpp
index aeacf295..c1f579ab 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -38,6 +38,7 @@ extern bool transmitFlag;
extern std::vector lastHeardStations;
bool statusAfterBoot = true;
+bool sendStartTelemetry = true;
bool beaconUpdate = true;
uint32_t lastBeaconTx = 0;
uint32_t lastScreenOn = millis();
@@ -102,6 +103,76 @@ namespace Utils {
fourthLine.concat(String(lastHeardStations.size()));
}
+
+ void sendInitialTelemetryPackets() {
+ String sender = Config.callsign;
+ for (int i = sender.length(); i < 9; i++) {
+ sender += ' ';
+ }
+ String baseAPRSISTelemetryPacket = Config.callsign;
+ baseAPRSISTelemetryPacket += ">APLRG1,TCPIP,qAC::";
+ baseAPRSISTelemetryPacket += sender;
+ baseAPRSISTelemetryPacket += ":";
+
+ String baseRFTelemetryPacket = Config.callsign;
+ baseRFTelemetryPacket += ">APLRG1,WIDE1-1::";
+ 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";
+ }
+
+ String telemetryPacket2 = "UNIT.";
+ if (Config.battery.sendInternalVoltage) {
+ telemetryPacket2 += "VDC";
+ }
+ if (Config.battery.sendExternalVoltage) {
+ telemetryPacket2 += String(Config.battery.sendInternalVoltage ? "," : "") + "VDC";
+ }
+
+ String telemetryPacket3 = "PARM.";
+ if (Config.battery.sendInternalVoltage) {
+ telemetryPacket3 += "V_Batt";
+ }
+ if (Config.battery.sendExternalVoltage) {
+ telemetryPacket3 += String(Config.battery.sendInternalVoltage ? "," : "") + "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) {
@@ -112,6 +183,10 @@ namespace Utils {
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
displayToggle(true);
}
+
+ if (sendStartTelemetry && Config.battery.sendVoltageAsTelemetry && !Config.bme.active && (Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage)) {
+ sendInitialTelemetryPackets();
+ }
STATION_Utils::deleteNotHeard();
@@ -133,45 +208,57 @@ namespace Utils {
#if defined(BATTERY_PIN) || defined(HAS_AXP192) || defined(HAS_AXP2101)
if (Config.battery.sendInternalVoltage || Config.battery.monitorInternalVoltage) {
float internalVoltage = BATTERY_Utils::checkInternalVoltage();
+ if (Config.battery.monitorInternalVoltage && internalVoltage < Config.battery.internalSleepVoltage) {
+ beaconPacket += " **IntBatWarning:SLEEP**";
+ secondaryBeaconPacket += " **IntBatWarning:SLEEP**";
+ shouldSleepLowVoltage = true;
+ }
+
String internalVoltageInfo = String(internalVoltage,2) + "V";
if (Config.battery.sendInternalVoltage) {
- beaconPacket += " Batt=";
- beaconPacket += internalVoltageInfo;
- secondaryBeaconPacket += " Batt=";
- secondaryBeaconPacket += internalVoltageInfo;
sixthLine = " (Batt=";
sixthLine += internalVoltageInfo;
sixthLine += ")";
- }
- if (Config.battery.monitorInternalVoltage && internalVoltage < Config.battery.internalSleepVoltage) {
- beaconPacket += " **IntBatWarning:SLEEP**";
- secondaryBeaconPacket += " **IntBatWarning:SLEEP**";
- shouldSleepLowVoltage = true;
- }
+ if (!Config.battery.sendVoltageAsTelemetry) {
+ beaconPacket += " Batt=";
+ beaconPacket += internalVoltageInfo;
+ secondaryBeaconPacket += " Batt=";
+ secondaryBeaconPacket += internalVoltageInfo;
+ }
+ }
}
#endif
#ifndef HELTEC_WP
if (Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) {
float externalVoltage = BATTERY_Utils::checkExternalVoltage();
- String externalVoltageInfo = String(externalVoltage,2) + "V";
- if (Config.battery.sendExternalVoltage) {
- beaconPacket += " Ext=";
- beaconPacket += externalVoltageInfo;
- secondaryBeaconPacket += " Ext=";
- secondaryBeaconPacket += externalVoltageInfo;
- sixthLine = " (Ext V=";
- sixthLine += externalVoltageInfo;
- sixthLine += ")";
- }
if (Config.battery.monitorExternalVoltage && externalVoltage < Config.battery.externalSleepVoltage) {
beaconPacket += " **ExtBatWarning:SLEEP**";
secondaryBeaconPacket += " **ExtBatWarning:SLEEP**";
shouldSleepLowVoltage = true;
}
+
+ String externalVoltageInfo = String(externalVoltage,2) + "V";
+ if (Config.battery.sendExternalVoltage) {
+ sixthLine = " (Ext V=";
+ sixthLine += externalVoltageInfo;
+ sixthLine += ")";
+ if (!Config.battery.sendVoltageAsTelemetry) {
+ beaconPacket += " Ext=";
+ beaconPacket += externalVoltageInfo;
+ secondaryBeaconPacket += " Ext=";
+ secondaryBeaconPacket += externalVoltageInfo;
+ }
+ }
}
#endif
+ if (Config.battery.sendVoltageAsTelemetry && !Config.bme.active){
+ String encodedTelemetry = BATTERY_Utils::generateEncodedTelemetry();
+ beaconPacket += encodedTelemetry;
+ secondaryBeaconPacket += encodedTelemetry;
+ }
+
if (Config.aprs_is.active && Config.beacon.sendViaAPRSIS && !backUpDigiMode) {
Utils::println("-- Sending Beacon to APRSIS --");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING IGATE BEACON", 0);
diff --git a/src/web_utils.cpp b/src/web_utils.cpp
index 535141ac..9ac75fe2 100644
--- a/src/web_utils.cpp
+++ b/src/web_utils.cpp
@@ -167,6 +167,8 @@ namespace WEB_Utils {
}
Config.battery.monitorExternalVoltage = request->hasParam("battery.monitorExternalVoltage", true);
Config.battery.externalSleepVoltage = request->getParam("battery.externalSleepVoltage", true)->value().toFloat();
+
+ Config.battery.sendVoltageAsTelemetry = request->hasParam("battery.sendVoltageAsTelemetry", true);
Config.bme.active = request->hasParam("bme.active", true);
Config.bme.heightCorrection = request->getParam("bme.heightCorrection", true)->value().toInt();