encoded Telemetry added

This commit is contained in:
richonguzman 2024-09-17 22:24:48 -03:00
parent c1c1908de4
commit c438928465
9 changed files with 197 additions and 83 deletions

View File

@ -49,6 +49,7 @@ ____________________________________________________
____________________________________________________
## Timeline (Versions):
- 2024.09.17 Battery Info now as Encoded Telemetry in GPS Beacon.
- 2024.08.26 New reformating of code ahead of WebInstaller: SmartBeacon change.
- 2024.08.16 BLE support for Android devices (not APRSDroid yet).
- 2024.08.12 Added support for EByte E220 400M30S 1Watt LoRa module for DIY ESP32 Tracker (LLCC68 supports spreading factor only in range of 5 - 11!)

View File

@ -37,6 +37,11 @@
"timeout": 4,
"turn180" : false
},
"battery": {
"sendVoltage": true,
"voltageAsTelemetry": true,
"sendVoltageAlways": true
},
"other": {
"simplifiedTrackerMode": false,
"sendCommentAfterXBeacons": 10,
@ -46,7 +51,6 @@
"maxDistanceToTracker": 30,
"standingUpdateTime": 15,
"sendAltitude": true,
"sendBatteryInfo": false,
"bluetoothType": 0,
"bluetoothActive": true,
"disableGPS": false

View File

@ -41,13 +41,13 @@ Configuration Config;
HardwareSerial neo6m_gps(1);
TinyGPSPlus gps;
#ifdef HAS_BT_CLASSIC
BluetoothSerial SerialBT;
BluetoothSerial SerialBT;
#endif
#ifdef BUTTON_PIN
OneButton userButton = OneButton(BUTTON_PIN, true, true);
#endif
String versionDate = "2024.09.10";
String versionDate = "2024.09.17";
uint8_t myBeaconsIndex = 0;
int myBeaconsSize = Config.beacons.size();

50
src/battery_utils.cpp Normal file
View File

@ -0,0 +1,50 @@
#include <Arduino.h>
#include "battery_utils.h"
int telemetryCounter = random(1,999);
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(float voltage) {
String telemetry = "|";
telemetry += generateEncodedTelemetryBytes(telemetryCounter, true, 0);
telemetryCounter++;
if (telemetryCounter == 1000) {
telemetryCounter = 0;
}
telemetry += generateEncodedTelemetryBytes(voltage, false, 0);
telemetry += "|";
return telemetry;
}
}

13
src/battery_utils.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef BATTERY_UTILS_H_
#define BATTERY_UTILS_H_
#include <Arduino.h>
namespace BATTERY_Utils {
String generateEncodedTelemetry(float voltage);
}
#endif

View File

@ -27,76 +27,79 @@ void Configuration::readFile(fs::FS &fs, const char *fileName) {
for (int i = 0; i < BeaconsArray.size(); i++) {
Beacon bcn;
bcn.callsign = BeaconsArray[i]["callsign"] | "NOCALL-7";
bcn.callsign = BeaconsArray[i]["callsign"] | "NOCALL-7";
bcn.callsign.toUpperCase();
bcn.symbol = BeaconsArray[i]["symbol"] | ">";
bcn.overlay = BeaconsArray[i]["overlay"] | "/";
bcn.comment = BeaconsArray[i]["comment"] | "";
bcn.smartBeaconActive = BeaconsArray[i]["smartBeaconActive"] | true;
bcn.smartBeaconSetting = BeaconsArray[i]["smartBeaconSetting"] | 0;
bcn.micE = BeaconsArray[i]["micE"] | "";
bcn.gpsEcoMode = BeaconsArray[i]["gpsEcoMode"] | false;
bcn.symbol = BeaconsArray[i]["symbol"] | ">";
bcn.overlay = BeaconsArray[i]["overlay"] | "/";
bcn.comment = BeaconsArray[i]["comment"] | "";
bcn.smartBeaconActive = BeaconsArray[i]["smartBeaconActive"] | true;
bcn.smartBeaconSetting = BeaconsArray[i]["smartBeaconSetting"] | 0;
bcn.micE = BeaconsArray[i]["micE"] | "";
bcn.gpsEcoMode = BeaconsArray[i]["gpsEcoMode"] | false;
beacons.push_back(bcn);
}
display.showSymbol = data["display"]["showSymbol"] | true;
display.ecoMode = data["display"]["ecoMode"] | false;
display.timeout = data["display"]["timeout"] | 4;
display.turn180 = data["display"]["turn180"] | false;
display.showSymbol = data["display"]["showSymbol"] | true;
display.ecoMode = data["display"]["ecoMode"] | false;
display.timeout = data["display"]["timeout"] | 4;
display.turn180 = data["display"]["turn180"] | false;
winlink.password = data["winlink"]["password"] | "NOPASS";
battery.sendVoltage = data["battery"]["sendVoltage"] | false;
battery.voltageAsTelemetry = data["battery"]["voltageAsTelemetry"] | false;
battery.sendVoltageAlways = data["battery"]["sendVoltageAlways"] | false;
bme.active = data["bme"]["active"] | false;
bme.temperatureCorrection = data["bme"]["temperatureCorrection"] | 0.0;
bme.sendTelemetry = data["bme"]["sendTelemetry"] | false;
winlink.password = data["winlink"]["password"] | "NOPASS";
notification.ledTx = data["notification"]["ledTx"] | false;
notification.ledTxPin = data["notification"]["ledTxPin"]| 13;
notification.ledMessage = data["notification"]["ledMessage"] | false;
notification.ledMessagePin = data["notification"]["ledMessagePin"] | 2;
notification.ledFlashlight = data["notification"]["ledFlashlight"] | false;
notification.ledFlashlightPin = data["notification"]["ledFlashlightPin"] | 14;
notification.buzzerActive = data["notification"]["buzzerActive"] | false;
notification.buzzerPinTone = data["notification"]["buzzerPinTone"] | 33;
notification.buzzerPinVcc = data["notification"]["buzzerPinVcc"] | 25;
notification.bootUpBeep = data["notification"]["bootUpBeep"] | false;
notification.txBeep = data["notification"]["txBeep"] | false;
notification.messageRxBeep = data["notification"]["messageRxBeep"] | false;
notification.stationBeep = data["notification"]["stationBeep"] | false;
notification.lowBatteryBeep = data["notification"]["lowBatteryBeep"] | false;
notification.shutDownBeep = data["notification"]["shutDownBeep"] | false;
bme.active = data["bme"]["active"] | false;
bme.temperatureCorrection = data["bme"]["temperatureCorrection"] | 0.0;
bme.sendTelemetry = data["bme"]["sendTelemetry"] | false;
notification.ledTx = data["notification"]["ledTx"] | false;
notification.ledTxPin = data["notification"]["ledTxPin"]| 13;
notification.ledMessage = data["notification"]["ledMessage"] | false;
notification.ledMessagePin = data["notification"]["ledMessagePin"] | 2;
notification.ledFlashlight = data["notification"]["ledFlashlight"] | false;
notification.ledFlashlightPin = data["notification"]["ledFlashlightPin"] | 14;
notification.buzzerActive = data["notification"]["buzzerActive"] | false;
notification.buzzerPinTone = data["notification"]["buzzerPinTone"] | 33;
notification.buzzerPinVcc = data["notification"]["buzzerPinVcc"] | 25;
notification.bootUpBeep = data["notification"]["bootUpBeep"] | false;
notification.txBeep = data["notification"]["txBeep"] | false;
notification.messageRxBeep = data["notification"]["messageRxBeep"] | false;
notification.stationBeep = data["notification"]["stationBeep"] | false;
notification.lowBatteryBeep = data["notification"]["lowBatteryBeep"] | false;
notification.shutDownBeep = data["notification"]["shutDownBeep"] | false;
JsonArray LoraTypesArray = data["lora"];
for (int j = 0; j < LoraTypesArray.size(); j++) {
LoraType loraType;
loraType.frequency = LoraTypesArray[j]["frequency"] | 433775000;
loraType.spreadingFactor = LoraTypesArray[j]["spreadingFactor"] | 12;
loraType.signalBandwidth = LoraTypesArray[j]["signalBandwidth"] | 125000;
loraType.codingRate4 = LoraTypesArray[j]["codingRate4"] | 5;
loraType.power = LoraTypesArray[j]["power"] | 20;
loraType.frequency = LoraTypesArray[j]["frequency"] | 433775000;
loraType.spreadingFactor = LoraTypesArray[j]["spreadingFactor"] | 12;
loraType.signalBandwidth = LoraTypesArray[j]["signalBandwidth"] | 125000;
loraType.codingRate4 = LoraTypesArray[j]["codingRate4"] | 5;
loraType.power = LoraTypesArray[j]["power"] | 20;
loraTypes.push_back(loraType);
}
ptt.active = data["pttTrigger"]["active"] | false;
ptt.io_pin = data["pttTrigger"]["io_pin"] | 4;
ptt.preDelay = data["pttTrigger"]["preDelay"] | 0;
ptt.postDelay = data["pttTrigger"]["postDelay"] | 0;
ptt.reverse = data["pttTrigger"]["reverse"] | false;
ptt.active = data["pttTrigger"]["active"] | false;
ptt.io_pin = data["pttTrigger"]["io_pin"] | 4;
ptt.preDelay = data["pttTrigger"]["preDelay"] | 0;
ptt.postDelay = data["pttTrigger"]["postDelay"] | 0;
ptt.reverse = data["pttTrigger"]["reverse"] | false;
simplifiedTrackerMode = data["other"]["simplifiedTrackerMode"] | false;
sendCommentAfterXBeacons = data["other"]["sendCommentAfterXBeacons"] | 10;
path = data["other"]["path"] | "WIDE1-1";
nonSmartBeaconRate = data["other"]["nonSmartBeaconRate"] | 15;
rememberStationTime = data["other"]["rememberStationTime"] | 30;
maxDistanceToTracker = data["other"]["maxDistanceToTracker"] | 30;
standingUpdateTime = data["other"]["standingUpdateTime"] | 15;
sendAltitude = data["other"]["sendAltitude"] | true;
sendBatteryInfo = data["other"]["sendBatteryInfo"] | false;
bluetoothType = data["other"]["bluetoothType"] | 1;
bluetoothActive = data["other"]["bluetoothActive"] | true;
disableGPS = data["other"]["disableGPS"] | false;
simplifiedTrackerMode = data["other"]["simplifiedTrackerMode"] | false;
sendCommentAfterXBeacons = data["other"]["sendCommentAfterXBeacons"] | 10;
path = data["other"]["path"] | "WIDE1-1";
nonSmartBeaconRate = data["other"]["nonSmartBeaconRate"] | 15;
rememberStationTime = data["other"]["rememberStationTime"] | 30;
maxDistanceToTracker = data["other"]["maxDistanceToTracker"] | 30;
standingUpdateTime = data["other"]["standingUpdateTime"] | 15;
sendAltitude = data["other"]["sendAltitude"] | true;
bluetoothType = data["other"]["bluetoothType"] | 1;
bluetoothActive = data["other"]["bluetoothActive"] | true;
disableGPS = data["other"]["disableGPS"] | false;
configFile.close();
}

View File

@ -25,6 +25,13 @@ public:
bool turn180;
};
class Battery {
public:
bool sendVoltage;
bool voltageAsTelemetry;
bool sendVoltageAlways;
};
class Winlink {
public:
String password;
@ -79,6 +86,7 @@ public:
std::vector<Beacon> beacons;
Display display;
Battery battery;
Winlink winlink;
BME bme;
Notification notification;
@ -93,7 +101,6 @@ public:
int maxDistanceToTracker;
int standingUpdateTime;
bool sendAltitude;
bool sendBatteryInfo;
int bluetoothType;
bool bluetoothActive;
bool disableGPS;

View File

@ -164,7 +164,7 @@ namespace POWER_Utils {
BatteryIsConnected = isBatteryConnected();
if (BatteryIsConnected) {
#ifdef HAS_AXP2101
batteryVoltage = String(PMU.getBattVoltage());
batteryVoltage = String(PMU.getBattVoltage()/1000);
#else
batteryVoltage = String(getBatteryVoltage(), 2);
#endif

View File

@ -2,6 +2,7 @@
#include <SPIFFS.h>
#include "APRSPacketLib.h"
#include "station_utils.h"
#include "battery_utils.h"
#include "configuration.h"
#include "boards_pinout.h"
#include "power_utils.h"
@ -43,7 +44,7 @@ bool sendStandingUpdate = false;
uint8_t updateCounter = Config.sendCommentAfterXBeacons;
bool sendStartTelemetry = true;
uint32_t lastTelemetryTx = 0;
uint32_t telemetryTx = millis();
@ -176,6 +177,38 @@ namespace STATION_Utils {
}
void sendBeacon(uint8_t type) {
if (sendStartTelemetry && Config.battery.voltageAsTelemetry) {
String sender = currentBeacon->callsign;
for (int i = sender.length(); i < 9; i++) {
sender += ' ';
}
String basePacket = currentBeacon->callsign;
basePacket += ">APLRT1";
if (Config.path != "") {
basePacket += ",";
basePacket += Config.path;
}
basePacket += "::";
basePacket += sender;
basePacket += ":";
String tempPacket = basePacket;
tempPacket += "EQNS.0,0.01,0";
LoRa_Utils::sendNewPacket(tempPacket);
delay(3000);
tempPacket = basePacket;
tempPacket += "UNIT.VDC";
LoRa_Utils::sendNewPacket(tempPacket);
delay(3000);
tempPacket = basePacket;
tempPacket += "PARM.V_Batt";
LoRa_Utils::sendNewPacket(tempPacket);
delay(3000);
sendStartTelemetry = false;
}
String packet;
if (Config.bme.sendTelemetry && type == 1) { // WX
packet = APRSPacketLib::generateGPSBeaconPacket(currentBeacon->callsign, "APLRT1", Config.path, "/", APRSPacketLib::encodeGPS(gps.location.lat(),gps.location.lng(), gps.course.deg(), 0.0, currentBeacon->symbol, Config.sendAltitude, gps.altitude.feet(), sendStandingUpdate, "Wx"));
@ -197,36 +230,39 @@ namespace STATION_Utils {
}
String comment;
int sendCommentAfterXBeacons;
if (winlinkCommentState) {
comment = " winlink";
if (winlinkCommentState || Config.battery.sendVoltageAlways) {
if (winlinkCommentState) comment = " winlink";
sendCommentAfterXBeacons = 1;
} else {
comment = currentBeacon->comment;
sendCommentAfterXBeacons = Config.sendCommentAfterXBeacons;
}
String batteryVoltage = POWER_Utils::getBatteryInfoVoltage();
if (Config.sendBatteryInfo) {
//String batteryVoltage = POWER_Utils::getBatteryInfoVoltage();
String batteryChargeCurrent = POWER_Utils::getBatteryInfoCurrent();
#ifdef HAS_AXP192
comment += " Bat=";
comment += batteryVoltage;
comment += "V (";
comment += batteryChargeCurrent;
comment += "mA)";
#endif
#ifdef HAS_AXP2101
comment += " Bat=";
comment += String(batteryVoltage.toFloat()/1000,2);
comment += "V (";
comment += batteryChargeCurrent;
comment += "%)";
#endif
#if defined(HELTEC_V3_GPS) || defined(HELTEC_WIRELESS_TRACKER) || defined(TTGO_T_DECK_GPS)
comment += " Bat=";
comment += String(batteryVoltage.toFloat(),2);
comment += "V";
#endif
if (Config.battery.sendVoltage) {
if (Config.battery.voltageAsTelemetry) {
comment += BATTERY_Utils::generateEncodedTelemetry(batteryVoltage.toFloat());
} else {
String batteryChargeCurrent = POWER_Utils::getBatteryInfoCurrent();
#ifdef HAS_AXP192
comment += " Bat=";
comment += batteryVoltage;
comment += "V (";
comment += batteryChargeCurrent;
comment += "mA)";
#endif
#ifdef HAS_AXP2101
comment += " Bat=";
comment += String(batteryVoltage.toFloat(),2);
comment += "V (";
comment += batteryChargeCurrent;
comment += "%)";
#endif
#if defined(HELTEC_V3_GPS) || defined(HELTEC_WIRELESS_TRACKER) || defined(TTGO_T_DECK_GPS)
comment += " Bat=";
comment += String(batteryVoltage.toFloat(),2);
comment += "V";
#endif
}
}
if (comment != "") {
updateCounter++;