encoded Telemetry added
This commit is contained in:
parent
c1c1908de4
commit
c438928465
|
|
@ -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!)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef BATTERY_UTILS_H_
|
||||
#define BATTERY_UTILS_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
namespace BATTERY_Utils {
|
||||
|
||||
String generateEncodedTelemetry(float voltage);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
|
|
|||
Loading…
Reference in New Issue