Compare commits

..

21 Commits

Author SHA1 Message Date
richonguzman 37162b9708 display font size correction 2025-03-03 12:22:22 -03:00
richonguzman 44d9732aa2 TbeamSupreme Added 2025-03-03 12:15:50 -03:00
richonguzman 312bdc9d9f refactor and blacklist2.0 2025-03-03 11:19:25 -03:00
richonguzman ff0b96bfe4 readme update again 2025-02-28 16:56:54 -03:00
richonguzman 36a8ef0ffb readme update for epaper 2025-02-28 16:53:16 -03:00
richonguzman 5ce8059040 epaper updated 2025-02-28 16:48:26 -03:00
richonguzman 60aef00b24 function name correction 2025-02-25 14:15:30 -03:00
richonguzman 72c2c144ae last corrections 2025-02-25 14:01:14 -03:00
richonguzman a1c552f197 readme update 2025-02-25 13:56:27 -03:00
richonguzman 8ede848199 ready for testing 2025-02-25 13:54:36 -03:00
richonguzman a4a82b75c5 more testing 2025-02-24 18:49:17 -03:00
richonguzman 64ac924f1f first proposal 2025-02-24 17:57:24 -03:00
richonguzman bde4a7f042 trim mod 2025-02-24 17:08:53 -03:00
richonguzman d54b63df22 telemetry conf packet start after first beacon 2025-02-24 16:36:52 -03:00
richonguzman c3d94d673a height correction with gps 2025-02-24 16:17:01 -03:00
richonguzman 45edf2ffa3 gps satelites indicator 2025-02-24 16:10:02 -03:00
richonguzman d628de9c9c code cleaned to lighter versions 2025-02-12 15:28:48 -03:00
richonguzman f879182f62 new mods 2025-02-12 14:15:36 -03:00
richonguzman c9ed618a8b t-deck readme update 2025-01-22 09:52:22 -03:00
richonguzman 6c7b8f9918 readme update 2025-01-22 09:40:42 -03:00
richonguzman c2b4b3b92f readme update 2025-01-22 01:35:28 -03:00
19 changed files with 497 additions and 278 deletions
+2
View File
@@ -57,6 +57,8 @@ jobs:
chip: esp32s3 chip: esp32s3
- name: ttgo_t_deck_GPS - name: ttgo_t_deck_GPS
chip: esp32s3 chip: esp32s3
- name: ttgo_t_beam_s3_SUPREME_v3
chip: esp32s3
- name: ESP32_DIY_LoRa_A7670 - name: ESP32_DIY_LoRa_A7670
chip: esp32 chip: esp32
- name: ESP32_DIY_LoRa_A7670_915 - name: ESP32_DIY_LoRa_A7670_915
+6 -2
View File
@@ -36,6 +36,8 @@ ____________________________________________________
- TTGO T-Beam V1.0 , V1.1, V1.2 (also variations with SX1262 and SX1268 LoRa Modules). - TTGO T-Beam V1.0 , V1.1, V1.2 (also variations with SX1262 and SX1268 LoRa Modules).
- T-Deck Plus (and also regular T-Deck with/without GPS).
- HELTEC V2, V3 , Wireless Stick, Wireless Stick Lite, HT-CT62, Wireless Tracker, Wireless Paper. - HELTEC V2, V3 , Wireless Stick, Wireless Stick Lite, HT-CT62, Wireless Tracker, Wireless Paper.
- QRP Labs LightGateway 1.0. - QRP Labs LightGateway 1.0.
@@ -52,7 +54,9 @@ ____________________________________________________
## Timeline (Versions): ## Timeline (Versions):
- 2025-01.22 Added LILYGO T-DECK PLUS (and DIY+GPS version) board support. - 2025.02.28 Heltec Wireless Paper with Epaper working. Thanks SzymonPriv for pointing to the right library.
- 2025.02.25 Objects Rules update, GPS Boards: Satellites on Screen, Wx Height Correction from GPS Data.
- 2025.01.22 Added LILYGO T-DECK PLUS (and DIY+GPS version) board support.
- 2025.01.11 Added HELTEC V3.2 board support. - 2025.01.11 Added HELTEC V3.2 board support.
- 2025.01.07 TROY_LoRa_APRS board added. GMT in quarter hour fix and Beacon fix for TNC. - 2025.01.07 TROY_LoRa_APRS board added. GMT in quarter hour fix and Beacon fix for TNC.
- 2025.01.02 Callsign Black List added. - 2025.01.02 Callsign Black List added.
@@ -63,7 +67,7 @@ ____________________________________________________
- 2024.10.25 Added QRP Labs LightGateway 1.0 support. - 2024.10.25 Added QRP Labs LightGateway 1.0 support.
- 2024.10.21 Boards with GPS can now send Real-GPS Beacon (also posible: GPS ambiguity of ~ 1 km). - 2024.10.21 Boards with GPS can now send Real-GPS Beacon (also posible: GPS ambiguity of ~ 1 km).
- 2024.10.14 Received Packets in WebUI show real Local Time (NTP with GMT offset). - 2024.10.14 Received Packets in WebUI show real Local Time (NTP with GMT offset).
- 2024.10.08 New EcoMode for Remote Digipeaters without WiFi/WiFiAP, Screen, Leds (Example: LILYGO LoRa32 uses only 24mA, with WifiAP and all was 150mA). APRS Message/Queries can start/stop this mode too. - 2024.10.08 New EcoMode for Remote Digipeaters without WiFi/WiFiAP, Screen, Leds (Example: LILYGO LoRa32 uses only 24mA, with WifiAP 150mA). APRS Message/Queries can start/stop this mode too.
- 2024.10.06 Cross Frequency Digipeater Rules added. - 2024.10.06 Cross Frequency Digipeater Rules added.
- 2024.09.23 Libraries Update for SDK3 - 2024.09.23 Libraries Update for SDK3
- 2024.09.23 Added Enconded Telemetry for Battery (+ External Voltage) in Station GPS Beacon Packet. - 2024.09.23 Added Enconded Telemetry for Battery (+ External Voltage) in Station GPS Beacon Packet.
+1
View File
@@ -20,6 +20,7 @@ namespace STATION_Utils {
void loadBlackList(); void loadBlackList();
bool checkBlackList(const String& callsign); bool checkBlackList(const String& callsign);
bool checkObjectTime(const String& packet);
void deleteNotHeard(); void deleteNotHeard();
void updateLastHeard(const String& station); void updateLastHeard(const String& station);
bool wasHeard(const String& station); bool wasHeard(const String& station);
+1 -1
View File
@@ -13,7 +13,7 @@ default_envs = ttgo-lora32-v21
extra_configs = extra_configs =
common_settings.ini common_settings.ini
variants/*/platformio.ini variants/*/platformio.ini
[env] [env]
platform = espressif32 @ 6.7.0 platform = espressif32 @ 6.7.0
+41 -4
View File
@@ -48,12 +48,14 @@ ___________________________________________________________________*/
#include "A7670_utils.h" #include "A7670_utils.h"
#endif #endif
String versionDate = "2025.01.22"; String versionDate = "2025.03.03";
Configuration Config; Configuration Config;
WiFiClient espClient; WiFiClient espClient;
#ifdef HAS_GPS #ifdef HAS_GPS
HardwareSerial gpsSerial(1); HardwareSerial gpsSerial(1);
TinyGPSPlus gps; TinyGPSPlus gps;
uint32_t gpsSatelliteTime = 0;
bool gpsInfoToggle = false;
#endif #endif
uint8_t myWiFiAPIndex = 0; uint8_t myWiFiAPIndex = 0;
@@ -66,10 +68,14 @@ uint32_t lastBatteryCheck = 0;
bool backUpDigiMode = false; bool backUpDigiMode = false;
bool modemLoggedToAPRSIS = false; bool modemLoggedToAPRSIS = false;
#ifdef HAS_EPAPER
uint32_t lastEpaperTime = 0;
extern String lastEpaperText;
#endif
std::vector<ReceivedPacket> receivedPackets; std::vector<ReceivedPacket> receivedPackets;
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine; String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
//#define STARTUP_DELAY 5 //min //#define STARTUP_DELAY 5 //min
void setup() { void setup() {
@@ -152,7 +158,26 @@ void loop() {
BATTERY_Utils::checkIfShouldSleep(); BATTERY_Utils::checkIfShouldSleep();
} }
thirdLine = Utils::getLocalIP(); #ifdef HAS_GPS
if (Config.beacon.gpsActive) {
if (millis() - gpsSatelliteTime > 5000) {
gpsInfoToggle = !gpsInfoToggle;
gpsSatelliteTime = millis();
}
if (gpsInfoToggle) {
thirdLine = "Satellite(s): ";
String gpsData = String(gps.satellites.value());
if (gpsData.length() < 2) gpsData = "0" + gpsData; // Ensure two-digit formatting
thirdLine += gpsData;
} else {
thirdLine = Utils::getLocalIP();
}
} else {
thirdLine = Utils::getLocalIP();
}
#else
thirdLine = Utils::getLocalIP();
#endif
#ifdef HAS_A7670 #ifdef HAS_A7670
if (Config.aprs_is.active && !modemLoggedToAPRSIS) A7670_Utils::APRS_IS_connect(); if (Config.aprs_is.active && !modemLoggedToAPRSIS) A7670_Utils::APRS_IS_connect();
@@ -198,7 +223,19 @@ void loop() {
STATION_Utils::processOutputPacketBuffer(); STATION_Utils::processOutputPacketBuffer();
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0); #ifdef HAS_EPAPER // Only consider updating every 10 seconds (when data to show is different from before)
if(lastEpaperTime == 0 || millis() - lastEpaperTime > 10000) {
String posibleEpaperText = firstLine + secondLine + thirdLine + fourthLine + fifthLine + sixthLine + seventhLine;
if (lastEpaperText != posibleEpaperText) {
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
lastEpaperText = posibleEpaperText;
lastEpaperTime = millis();
}
}
#else
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
#endif
Utils::checkRebootTime(); Utils::checkRebootTime();
Utils::checkSleepByLowBatteryVoltage(1); Utils::checkSleepByLowBatteryVoltage(1);
} }
+43 -39
View File
@@ -173,37 +173,35 @@ namespace APRS_IS_Utils {
void processLoRaPacket(const String& packet) { void processLoRaPacket(const String& packet) {
if (passcodeValid && (espClient.connected() || modemLoggedToAPRSIS)) { if (passcodeValid && (espClient.connected() || modemLoggedToAPRSIS)) {
if (packet != "") { if (packet.indexOf("NOGATE") == -1 && packet.indexOf("RFONLY") == -1) {
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) { int firstColonIndex = packet.indexOf(":");
int firstColonIndex = packet.indexOf(":"); if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) {
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) { const String& Sender = packet.substring(3, packet.indexOf(">"));
const String& Sender = packet.substring(3, packet.indexOf(">")); if (Sender != Config.callsign && Utils::checkValidCallsign(Sender)) {
if (Sender != Config.callsign && Utils::checkValidCallsign(Sender) && !STATION_Utils::checkBlackList(Sender)) { STATION_Utils::updateLastHeard(Sender);
STATION_Utils::updateLastHeard(Sender); Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS
Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2); String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":")); Addressee.trim();
Addressee.trim(); bool queryMessage = false;
bool queryMessage = false; if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me! queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false);
queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false); }
} if (!queryMessage) {
if (!queryMessage) { const String& aprsPacket = buildPacketToUpload(packet);
const String& aprsPacket = buildPacketToUpload(packet); if (!Config.display.alwaysOn && Config.display.timeout != 0) {
if (!Config.display.alwaysOn && Config.display.timeout != 0) { displayToggle(true);
displayToggle(true);
}
lastScreenOn = millis();
#ifdef HAS_A7670
stationBeacon = true;
A7670_Utils::uploadToAPRSIS(aprsPacket);
stationBeacon = false;
#else
upload(aprsPacket);
#endif
Utils::println("---> Uploaded to APRS-IS");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} }
lastScreenOn = millis();
#ifdef HAS_A7670
stationBeacon = true;
A7670_Utils::uploadToAPRSIS(aprsPacket);
stationBeacon = false;
#else
upload(aprsPacket);
#endif
Utils::println("---> Uploaded to APRS-IS");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} }
} }
} }
@@ -298,7 +296,7 @@ namespace APRS_IS_Utils {
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1); receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1);
} }
if (receivedMessage.indexOf("?") == 0) { if (receivedMessage.indexOf("?") == 0) {
Utils::println("Received Query APRS-IS : " + packet); Utils::println("Rx Query (APRS-IS) : " + packet);
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false); String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n"))); //Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
if (!Config.display.alwaysOn && Config.display.timeout != 0) { if (!Config.display.alwaysOn && Config.display.timeout != 0) {
@@ -322,22 +320,28 @@ namespace APRS_IS_Utils {
seventhLine = "QUERY = "; seventhLine = "QUERY = ";
seventhLine += receivedMessage; seventhLine += receivedMessage;
} }
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} else { } else {
Utils::print("Received Message from APRS-IS : " + packet); Utils::print("Rx Message (APRS-IS): " + packet);
if (STATION_Utils::wasHeard(Addressee) && packet.indexOf("EQNS.") == -1 && packet.indexOf("UNIT.") == -1 && packet.indexOf("PARM.") == -1) { if (STATION_Utils::wasHeard(Addressee) && packet.indexOf("EQNS.") == -1 && packet.indexOf("UNIT.") == -1 && packet.indexOf("PARM.") == -1) {
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1)); STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1));
displayToggle(true); displayToggle(true);
lastScreenOn = millis(); lastScreenOn = millis();
Utils::typeOfPacket(packet, 1); // APRS-LoRa Utils::typeOfPacket(packet, 1); // APRS-LoRa
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} }
} }
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) { } else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
Utils::println("Received Object from APRS-IS : " + packet); Utils::print("Rx Object (APRS-IS) : " + packet);
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5)); if (STATION_Utils::checkObjectTime(packet)) {
displayToggle(true); STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5));
lastScreenOn = millis(); displayToggle(true);
Utils::typeOfPacket(packet, 1); // APRS-LoRa lastScreenOn = millis();
Utils::typeOfPacket(packet, 1); // APRS-LoRa
Serial.println();
} else {
Serial.println(" ---> Rejected (Time): No Tx");
}
} }
} }
} }
@@ -349,7 +353,7 @@ namespace APRS_IS_Utils {
if (espClient.connected()) { if (espClient.connected()) {
if (espClient.available()) { if (espClient.available()) {
String aprsisPacket = espClient.readStringUntil('\r'); String aprsisPacket = espClient.readStringUntil('\r');
// Serial.println(aprsisPacket); aprsisPacket.trim(); // Serial.println(aprsisPacket);
processAPRSISPacket(aprsisPacket); processAPRSISPacket(aprsisPacket);
lastRxTime = millis(); lastRxTime = millis();
} }
+35 -37
View File
@@ -117,46 +117,44 @@ namespace DIGI_Utils {
} }
void processLoRaPacket(const String& packet) { void processLoRaPacket(const String& packet) {
if (packet != "") { if (packet.indexOf("NOGATE") == -1) {
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1)) { bool thirdPartyPacket = false;
bool thirdPartyPacket = false; String temp, Sender;
String temp, Sender; int firstColonIndex = packet.indexOf(":");
int firstColonIndex = packet.indexOf(":"); if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] == '}' && packet.indexOf("TCPIP") > 0) { // 3rd Party
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] == '}' && packet.indexOf("TCPIP") > 0) { // 3rd Party thirdPartyPacket = true;
thirdPartyPacket = true; temp = packet.substring(packet.indexOf(":}") + 2);
temp = packet.substring(packet.indexOf(":}") + 2); Sender = temp.substring(0, temp.indexOf(">"));
Sender = temp.substring(0, temp.indexOf(">")); } else {
} else { temp = packet.substring(3);
temp = packet.substring(3); Sender = packet.substring(3, packet.indexOf(">"));
Sender = packet.substring(3, packet.indexOf(">")); }
if (Sender != Config.callsign) { // Avoid listening to own packets
if (!thirdPartyPacket && !Utils::checkValidCallsign(Sender)) {
return;
} }
if (Sender != Config.callsign && !STATION_Utils::checkBlackList(Sender)) { // Avoid listening to own packets if (STATION_Utils::check25SegBuffer(Sender, temp.substring(temp.indexOf(":") + 2)) || Config.lowPowerMode) {
if (!thirdPartyPacket && !Utils::checkValidCallsign(Sender)) { STATION_Utils::updateLastHeard(Sender);
return; Utils::typeOfPacket(temp, 2); // Digi
} bool queryMessage = false;
if (STATION_Utils::check25SegBuffer(Sender, temp.substring(temp.indexOf(":") + 2)) || Config.lowPowerMode) { if (temp.indexOf("::") > 10) { // it's a message
STATION_Utils::updateLastHeard(Sender); String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2);
Utils::typeOfPacket(temp, 2); // Digi String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
bool queryMessage = false; Addressee.trim();
if (temp.indexOf("::") > 10) { // it's a message if (Addressee == Config.callsign) { // it's a message for me!
String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2); queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
if (Addressee == Config.callsign) { // it's a message for me!
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
}
} }
if (!queryMessage) { }
String loraPacket = generateDigipeatedPacket(packet.substring(3), thirdPartyPacket); if (!queryMessage) {
if (loraPacket != "") { String loraPacket = generateDigipeatedPacket(packet.substring(3), thirdPartyPacket);
if (Config.lowPowerMode) { if (loraPacket != "") {
LoRa_Utils::sendNewPacket(loraPacket); if (Config.lowPowerMode) {
} else { LoRa_Utils::sendNewPacket(loraPacket);
STATION_Utils::addToOutputPacketBuffer(loraPacket); } else {
} STATION_Utils::addToOutputPacketBuffer(loraPacket);
displayToggle(true);
lastScreenOn = millis();
} }
displayToggle(true);
lastScreenOn = millis();
} }
} }
} }
+98 -29
View File
@@ -24,14 +24,22 @@
uint16_t redColor = 0xc8a2; uint16_t redColor = 0xc8a2;
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
// #include <heltec-eink-modules.h>
#include "Fonts/FreeSansBold9pt7b.h"
EInkDisplay_WirelessPaperV1_1 display;
String lastEpaperText;
#else #else
#include <Adafruit_GFX.h> #include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> #if defined(TTGO_T_Beam_S3_SUPREME_V3)
#ifdef HELTEC_WSL_V3_DISPLAY #include <Adafruit_SH110X.h>
Adafruit_SSD1306 display(128, 64, &Wire1, OLED_RST); Adafruit_SH1106G display(128, 64, &Wire, OLED_RST);
#else #else
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST); #include <Adafruit_SSD1306.h>
#ifdef HELTEC_WSL_V3_DISPLAY
Adafruit_SSD1306 display(128, 64, &Wire1, OLED_RST);
#else
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);
#endif
#endif #endif
#endif #endif
#endif #endif
@@ -63,7 +71,9 @@ void displaySetup() {
#endif #endif
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
// display.landscape();
display.printCenter("LoRa APRS iGate Initialising...");
display.update();
#else #else
#ifdef OLED_DISPLAY_HAS_RST_PIN #ifdef OLED_DISPLAY_HAS_RST_PIN
pinMode(OLED_RST, OUTPUT); pinMode(OLED_RST, OUTPUT);
@@ -72,17 +82,30 @@ void displaySetup() {
digitalWrite(OLED_RST, HIGH); digitalWrite(OLED_RST, HIGH);
#endif #endif
if(display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { #if defined(TTGO_T_Beam_S3_SUPREME_V3)
displayFound = true; if (!display.begin(0x3c, false)) {
if (Config.display.turn180) display.setRotation(2); displayFound = true;
display.clearDisplay(); if (Config.display.turn180) display.setRotation(2);
display.setTextColor(WHITE); display.clearDisplay();
display.setTextSize(1); display.setTextColor(SH110X_WHITE);
display.setCursor(0, 0); display.setTextSize(1);
display.ssd1306_command(SSD1306_SETCONTRAST); display.setCursor(0, 0);
display.ssd1306_command(1); display.setContrast(1);
display.display(); display.display();
} }
#else
if(display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
displayFound = true;
if (Config.display.turn180) display.setRotation(2);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
}
#endif
#endif #endif
#endif #endif
delay(1000); delay(1000);
@@ -96,9 +119,14 @@ void displayToggle(bool toggle) {
digitalWrite(TFT_BL, HIGH); digitalWrite(TFT_BL, HIGH);
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
// ... to be continued display.printCenter("EPAPER Display Disabled by toggle...");
display.update();
#else #else
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYON); #if defined(TTGO_T_Beam_S3_SUPREME_V3)
if (displayFound) display.oled_command(SH110X_DISPLAYON);
#else
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYON);
#endif
#endif #endif
#endif #endif
} else { } else {
@@ -106,9 +134,15 @@ void displayToggle(bool toggle) {
digitalWrite(TFT_BL, LOW); digitalWrite(TFT_BL, LOW);
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
// ... to be continued display.printCenter("Enabled EPAPER Display...");
display.update();
#else #else
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYOFF); #if defined(TTGO_T_Beam_S3_SUPREME_V3)
if (displayFound) display.oled_command(SH110X_DISPLAYOFF);
#else
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYOFF);
#endif
#endif #endif
#endif #endif
} }
@@ -141,11 +175,24 @@ void displayShow(const String& header, const String& line1, const String& line2,
sprite.pushSprite(0,0); sprite.pushSprite(0,0);
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
// ... to be continued display.clearMemory();
display.setCursor(5,10);
display.setFont(&FreeSansBold9pt7b);
display.println(header);
display.setFont(NULL);
for (int i = 0; i < 3; i++) {
display.setCursor(0, 25 + (14 * i));
display.println(*lines[i]);
}
display.update();
#else #else
if (displayFound) { if (displayFound) {
display.clearDisplay(); display.clearDisplay();
display.setTextColor(WHITE); #if defined(TTGO_T_Beam_S3_SUPREME_V3)
display.setTextColor(SH110X_WHITE);
#else
display.setTextColor(WHITE);
#endif
display.setTextSize(1); display.setTextSize(1);
display.setCursor(0, 0); display.setCursor(0, 0);
display.println(header); display.println(header);
@@ -153,8 +200,12 @@ void displayShow(const String& header, const String& line1, const String& line2,
display.setCursor(0, 8 + (8 * i)); display.setCursor(0, 8 + (8 * i));
display.println(*lines[i]); display.println(*lines[i]);
} }
display.ssd1306_command(SSD1306_SETCONTRAST); #if defined(TTGO_T_Beam_S3_SUPREME_V3)
display.ssd1306_command(1); display.setContrast(1);
#else
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
#endif
display.display(); display.display();
} }
#endif #endif
@@ -189,11 +240,25 @@ void displayShow(const String& header, const String& line1, const String& line2,
sprite.pushSprite(0,0); sprite.pushSprite(0,0);
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
// ... to be continued lastEpaperText = header + line1 + line2 + line3 + line4 + line5 + line6;
display.clearMemory();
display.setCursor(5,10);
display.setFont(&FreeSansBold9pt7b);
display.println(header);
display.setFont(NULL);
for (int i = 0; i < 6; i++) {
display.setCursor(0, 25 + (14 * i));
display.println(*lines[i]);
}
display.update();
#else #else
if (displayFound) { if (displayFound) {
display.clearDisplay(); display.clearDisplay();
display.setTextColor(WHITE); #if defined(TTGO_T_Beam_S3_SUPREME_V3)
display.setTextColor(SH110X_WHITE);
#else
display.setTextColor(WHITE);
#endif
display.setTextSize(2); display.setTextSize(2);
display.setCursor(0, 0); display.setCursor(0, 0);
display.println(header); display.println(header);
@@ -202,8 +267,12 @@ void displayShow(const String& header, const String& line1, const String& line2,
display.setCursor(0, 16 + (8 * i)); display.setCursor(0, 16 + (8 * i));
display.println(*lines[i]); display.println(*lines[i]);
} }
display.ssd1306_command(SSD1306_SETCONTRAST); #if defined(TTGO_T_Beam_S3_SUPREME_V3)
display.ssd1306_command(1); display.setContrast(1);
#else
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
#endif
display.display(); display.display();
} }
#endif #endif
+26 -19
View File
@@ -2,6 +2,7 @@
#include <WiFi.h> #include <WiFi.h>
#include "configuration.h" #include "configuration.h"
#include "aprs_is_utils.h" #include "aprs_is_utils.h"
#include "station_utils.h"
#include "board_pinout.h" #include "board_pinout.h"
#include "syslog_utils.h" #include "syslog_utils.h"
#include "ntp_utils.h" #include "ntp_utils.h"
@@ -139,7 +140,7 @@ namespace LoRa_Utils {
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) { if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
SYSLOG_Utils::log(3, newPacket, 0, 0.0, 0); // TX SYSLOG_Utils::log(3, newPacket, 0, 0.0, 0); // TX
} }
Utils::print("---> LoRa Packet Tx : "); Utils::print("---> LoRa Packet Tx : ");
Utils::println(newPacket); Utils::println(newPacket);
} else { } else {
Utils::print(F("failed, code ")); Utils::print(F("failed, code "));
@@ -182,27 +183,33 @@ namespace LoRa_Utils {
int state = radio.readData(packet); int state = radio.readData(packet);
if (state == RADIOLIB_ERR_NONE) { if (state == RADIOLIB_ERR_NONE) {
if (packet != "") { if (packet != "") {
rssi = radio.getRSSI();
snr = radio.getSNR();
freqError = radio.getFrequencyError();
Utils::println("<--- LoRa Packet Rx : " + packet.substring(3));
Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
if (!Config.lowPowerMode && !Config.digi.ecoMode) { String sender = packet.substring(3, packet.indexOf(">"));
if (receivedPackets.size() >= 10) { if (packet.substring(0,3) == "\x3c\xff\x01" && !STATION_Utils::checkBlackList(sender)){ // avoid processing BlackListed stations
receivedPackets.erase(receivedPackets.begin()); rssi = radio.getRSSI();
snr = radio.getSNR();
freqError = radio.getFrequencyError();
Utils::println("<--- LoRa Packet Rx : " + packet.substring(3));
Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
if (!Config.lowPowerMode && !Config.digi.ecoMode) {
if (receivedPackets.size() >= 10) {
receivedPackets.erase(receivedPackets.begin());
}
ReceivedPacket receivedPacket;
receivedPacket.rxTime = NTP_Utils::getFormatedTime();
receivedPacket.packet = packet.substring(3);
receivedPacket.RSSI = rssi;
receivedPacket.SNR = snr;
receivedPackets.push_back(receivedPacket);
} }
ReceivedPacket receivedPacket;
receivedPacket.rxTime = NTP_Utils::getFormatedTime();
receivedPacket.packet = packet.substring(3);
receivedPacket.RSSI = rssi;
receivedPacket.SNR = snr;
receivedPackets.push_back(receivedPacket);
}
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) { if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX
} }
} else {
packet = "";
}
lastRxTime = millis(); lastRxTime = millis();
return packet; return packet;
} }
+7 -7
View File
@@ -48,13 +48,13 @@ namespace OTA_Utils {
void onOTAEnd(bool success) { void onOTAEnd(bool success) {
displayToggle(true); displayToggle(true);
lastScreenOn = millis(); lastScreenOn = millis();
if (success) {
Serial.println("OTA update finished successfully!"); String statusMessage = success ? "OTA update success!" : "OTA update fail!";
displayShow("", "", " OTA update success!", "", " Rebooting ...", "", "", 4000); String rebootMessage = success ? "Rebooting ..." : "";
} else {
Serial.println("There was an error during OTA update!"); Serial.println(success ? "OTA update finished successfully!" : "There was an error during OTA update!");
displayShow("", "", " OTA update fail!", "", "", "", "", 4000); displayShow("", "", statusMessage, "", rebootMessage, "", "", 4000);
}
isUpdatingOTA = false; isUpdatingOTA = false;
} }
+55 -12
View File
@@ -4,9 +4,17 @@
#include "power_utils.h" #include "power_utils.h"
#if defined(HAS_AXP192) || defined(HAS_AXP2101) #if defined(HAS_AXP192) || defined(HAS_AXP2101)
#define I2C_SDA 21 #ifdef TTGO_T_Beam_S3_SUPREME_V3
#define I2C_SCL 22 #define I2C0_SDA 17
#define IRQ_PIN 35 #define I2C0_SCL 18
#define I2C1_SDA 42
#define I2C1_SCL 41
#define IRQ_PIN 40
#else
#define I2C_SDA 21
#define I2C_SCL 22
#define IRQ_PIN 35
#endif
#endif #endif
#ifdef HAS_AXP192 #ifdef HAS_AXP192
@@ -54,8 +62,13 @@ namespace POWER_Utils {
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
#ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.setALDO4Voltage(3300);
PMU.enableALDO4();
#else
PMU.setALDO3Voltage(3300); PMU.setALDO3Voltage(3300);
PMU.enableALDO3(); PMU.enableALDO3();
#endif
#endif #endif
#ifdef HELTEC_WIRELESS_TRACKER #ifdef HELTEC_WIRELESS_TRACKER
digitalWrite(VEXT_CTRL, HIGH); digitalWrite(VEXT_CTRL, HIGH);
@@ -69,7 +82,11 @@ namespace POWER_Utils {
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
PMU.disableALDO3(); #ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.disableALDO4();
#else
PMU.disableALDO3();
#endif
#endif #endif
#ifdef HELTEC_WIRELESS_TRACKER #ifdef HELTEC_WIRELESS_TRACKER
digitalWrite(VEXT_CTRL, LOW); digitalWrite(VEXT_CTRL, LOW);
@@ -83,8 +100,13 @@ namespace POWER_Utils {
PMU.enableLDO2(); PMU.enableLDO2();
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
PMU.setALDO2Voltage(3300); #ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.enableALDO2(); PMU.setALDO3Voltage(3300);
PMU.enableALDO3();
#else
PMU.setALDO2Voltage(3300);
PMU.enableALDO2();
#endif
#endif #endif
} }
@@ -93,7 +115,11 @@ namespace POWER_Utils {
PMU.disableLDO2(); PMU.disableLDO2();
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
PMU.disableALDO2(); #ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.disableALDO3();
#else
PMU.disableALDO2();
#endif
#endif #endif
} }
@@ -111,20 +137,29 @@ namespace POWER_Utils {
} }
return result; return result;
#elif defined(HAS_AXP2101) #elif defined(HAS_AXP2101)
bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL); #ifdef TTGO_T_Beam_S3_SUPREME_V3
bool result = PMU.begin(Wire1, AXP2101_SLAVE_ADDRESS, I2C1_SDA, I2C1_SCL);
#else
bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
#endif
if (result) { if (result) {
PMU.disableDC2(); PMU.disableDC2();
PMU.disableDC3(); PMU.disableDC3();
PMU.disableDC4(); PMU.disableDC4();
PMU.disableDC5(); PMU.disableDC5();
PMU.disableALDO1(); #ifndef TTGO_T_Beam_S3_SUPREME_V3
PMU.disableALDO4(); PMU.disableALDO1();
PMU.disableALDO4();
#endif
PMU.disableBLDO1(); PMU.disableBLDO1();
PMU.disableBLDO2(); PMU.disableBLDO2();
PMU.disableDLDO1(); PMU.disableDLDO1();
PMU.disableDLDO2(); PMU.disableDLDO2();
PMU.setDC1Voltage(3300); PMU.setDC1Voltage(3300);
PMU.enableDC1(); PMU.enableDC1();
#ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.setALDO1Voltage(3300);
#endif
PMU.setButtonBatteryChargeVoltage(3300); PMU.setButtonBatteryChargeVoltage(3300);
PMU.enableButtonBatteryCharge(); PMU.enableButtonBatteryCharge();
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ); PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
@@ -152,8 +187,16 @@ namespace POWER_Utils {
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
Wire.begin(SDA, SCL); bool beginStatus = false;
if (begin(Wire)) { #ifdef TTGO_T_Beam_S3_SUPREME_V3
Wire1.begin(I2C1_SDA, I2C1_SCL);
Wire.begin(I2C0_SDA, I2C0_SCL);
if (begin(Wire1)) beginStatus = true;
#else
Wire.begin(SDA, SCL);
if (begin(Wire)) beginStatus = true;
#endif
if (beginStatus) {
Serial.println("AXP2101 init done!"); Serial.println("AXP2101 init done!");
} else { } else {
Serial.println("AXP2101 init failed!"); Serial.println("AXP2101 init failed!");
+29 -20
View File
@@ -17,6 +17,7 @@ std::vector<LastHeardStation> lastHeardStations;
std::vector<String> outputPacketBuffer; std::vector<String> outputPacketBuffer;
std::vector<Packet25SegBuffer> packet25SegBuffer; std::vector<Packet25SegBuffer> packet25SegBuffer;
std::vector<String> blackList; std::vector<String> blackList;
std::vector<LastHeardStation> lastHeardObjects;
bool saveNewDigiEcoModeConfig = false; bool saveNewDigiEcoModeConfig = false;
@@ -50,7 +51,30 @@ namespace STATION_Utils {
return false; return false;
} }
void cleanObjectsHeard() {
for (auto it = lastHeardObjects.begin(); it != lastHeardObjects.end(); ) {
if (millis() - it->lastHeardTime >= 9.75 * 60 * 1000) { // 9.75 = 9min 45secs
it = lastHeardObjects.erase(it); // erase() returns the next valid iterator
} else {
++it; // Only increment if not erasing
}
}
}
bool checkObjectTime(const String& packet) {
cleanObjectsHeard();
int objectIDIndex = packet.indexOf(":;");
String object = packet.substring(objectIDIndex + 2, objectIDIndex + 11);
object.trim();
for (int i = 0; i < lastHeardObjects.size(); i++) { // Check if i should Tx object
if (lastHeardObjects[i].station == object) return false;
}
lastHeardObjects.emplace_back(LastHeardStation{millis(), object}); // Add new object and Tx
return true;
}
void deleteNotHeard() { void deleteNotHeard() {
std::vector<LastHeardStation> lastHeardStation_temp; std::vector<LastHeardStation> lastHeardStation_temp;
for (int i = 0; i < lastHeardStations.size(); i++) { for (int i = 0; i < lastHeardStations.size(); i++) {
@@ -72,22 +96,11 @@ namespace STATION_Utils {
if (lastHeardStations[i].station == station) { if (lastHeardStations[i].station == station) {
lastHeardStations[i].lastHeardTime = millis(); lastHeardStations[i].lastHeardTime = millis();
stationHeard = true; stationHeard = true;
break;
} }
} }
if (!stationHeard) { if (!stationHeard) lastHeardStations.emplace_back(LastHeardStation{millis(), station});
LastHeardStation lastStation; Utils::activeStations();
lastStation.lastHeardTime = millis();
lastStation.station = station;
lastHeardStations.push_back(lastStation);
}
fourthLine = "Stations (";
fourthLine += String(Config.rememberStationTime);
fourthLine += "min) = ";
if (lastHeardStations.size() < 10) {
fourthLine += " ";
}
fourthLine += String(lastHeardStations.size());
} }
bool wasHeard(const String& station) { bool wasHeard(const String& station) {
@@ -98,7 +111,7 @@ namespace STATION_Utils {
return true; return true;
} }
} }
Utils::println(" ---> Station not Heard for last 30 min (Not Tx)\n"); Utils::println(" ---> Station not Heard in " + String(Config.rememberStationTime) + " min: No Tx");
return false; return false;
} }
@@ -112,11 +125,7 @@ namespace STATION_Utils {
if (packet25SegBuffer[i].station == station && packet25SegBuffer[i].payload == textMessage) return false; if (packet25SegBuffer[i].station == station && packet25SegBuffer[i].payload == textMessage) return false;
} }
} }
Packet25SegBuffer packet; packet25SegBuffer.emplace_back(Packet25SegBuffer{millis(), station, textMessage});
packet.receivedTime = millis();
packet.station = station;
packet.payload = textMessage;
packet25SegBuffer.push_back(packet);
return true; return true;
} }
+33 -32
View File
@@ -20,6 +20,10 @@ namespace SYSLOG_Utils {
char signalData[35]; char signalData[35];
snprintf(signalData, sizeof(signalData), " / %ddBm / %.2fdB / %dHz", rssi, snr, freqError); snprintf(signalData, sizeof(signalData), " / %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
int colonIndex = packet.indexOf(":");
char nextChar = packet[colonIndex + 1];
String sender = packet.substring(3, packet.indexOf(">"));
switch (type) { switch (type) {
case 0: // CRC case 0: // CRC
syslogPacket.concat("CRC / CRC-ERROR / "); syslogPacket.concat("CRC / CRC-ERROR / ");
@@ -28,59 +32,56 @@ namespace SYSLOG_Utils {
break; break;
case 1: // RX case 1: // RX
syslogPacket.concat("RX / "); syslogPacket.concat("RX / ");
if (packet.indexOf("::") > 10) { if (nextChar == ':') {
syslogPacket.concat("MESSAGE / "); syslogPacket.concat("MESSAGE / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">"))); syslogPacket.concat(sender);
syslogPacket.concat(" ---> "); syslogPacket.concat(packet.substring(packet.indexOf("::") + 2)); syslogPacket.concat(" ---> ");
syslogPacket.concat(signalData); syslogPacket.concat(packet.substring(colonIndex + 2));
} else if (packet.indexOf(":!") > 10 || packet.indexOf(":=") > 10) { } else if (nextChar == '!' || nextChar == '=') {
syslogPacket.concat("GPS / "); syslogPacket.concat("GPS / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">"))); syslogPacket.concat(sender);
syslogPacket.concat(" / "); syslogPacket.concat(" / ");
if (packet.indexOf("WIDE1-1") > 10) { if (packet.indexOf("WIDE1-1") > 10) {
syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, packet.indexOf(","))); syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, packet.indexOf(",")));
syslogPacket.concat(" / WIDE1-1"); syslogPacket.concat(" / WIDE1-1");
} else { } else {
syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, packet.indexOf(":"))); syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, colonIndex));
syslogPacket.concat(" / -"); syslogPacket.concat(" / -");
} }
syslogPacket.concat(signalData); } else if (nextChar == '>') {
syslogPacket.concat(" / ");
syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet));
} else if (packet.indexOf(":>") > 10) {
syslogPacket.concat("STATUS / "); syslogPacket.concat("STATUS / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">"))); syslogPacket.concat(sender);
syslogPacket.concat(" ---> "); syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":>") + 2)); syslogPacket.concat(packet.substring(colonIndex + 2));
syslogPacket.concat(signalData); } else if (nextChar == '`') {
} else if (packet.indexOf(":`") > 10) {
syslogPacket.concat("MIC-E / "); syslogPacket.concat("MIC-E / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">"))); syslogPacket.concat(sender);
syslogPacket.concat(" ---> "); syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":`") + 2)); syslogPacket.concat(packet.substring(colonIndex + 2));
syslogPacket.concat(signalData); } else if (nextChar == ';') {
syslogPacket.concat("OBJECT / ");
syslogPacket.concat(sender);
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(colonIndex + 2));
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) { } else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) {
syslogPacket.concat("TELEMETRY / "); syslogPacket.concat("TELEMETRY / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">"))); syslogPacket.concat(sender);
syslogPacket.concat(" ---> "); syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":T#") + 3)); syslogPacket.concat(packet.substring(packet.indexOf(":T#") + 3));
syslogPacket.concat(signalData);
} else if (packet.indexOf(":;") > 10) {
syslogPacket.concat("OBJECT / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":;") + 2));
syslogPacket.concat(signalData);
} else { } else {
syslogPacket.concat(packet); syslogPacket.concat(packet);
syslogPacket.concat(signalData); }
syslogPacket.concat(signalData);
if (nextChar == '!' || nextChar == '=') {
syslogPacket.concat(" / ");
syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet));
} }
break; break;
case 2: // APRSIS TX case 2: // APRSIS TX
syslogPacket.concat("APRSIS TX / "); syslogPacket.concat("APRSIS TX / ");
if (packet.indexOf(":>") > 10) { if (nextChar == '>') {
syslogPacket.concat("StartUp_Status / "); syslogPacket.concat("StartUp_Status / ");
syslogPacket.concat(packet.substring(packet.indexOf(":>") + 2)); syslogPacket.concat(packet.substring(colonIndex + 2));
} else { } else {
syslogPacket.concat("QUERY / "); syslogPacket.concat("QUERY / ");
syslogPacket.concat(packet); syslogPacket.concat(packet);
@@ -91,11 +92,11 @@ namespace SYSLOG_Utils {
if (packet.indexOf("RFONLY") > 10) { if (packet.indexOf("RFONLY") > 10) {
syslogPacket.concat("RFONLY / "); syslogPacket.concat("RFONLY / ");
syslogPacket.concat(packet); syslogPacket.concat(packet);
} else if (packet.indexOf("::") > 10) { } else if (nextChar == ':') {
syslogPacket.concat("MESSAGE / "); syslogPacket.concat("MESSAGE / ");
syslogPacket.concat(packet.substring(0,packet.indexOf(">"))); syslogPacket.concat(sender);
syslogPacket.concat(" ---> "); syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf("::") + 2)); syslogPacket.concat(packet.substring(colonIndex + 2));
} else { } else {
syslogPacket.concat(packet); syslogPacket.concat(packet);
} }
+3 -10
View File
@@ -44,16 +44,9 @@ namespace TNC_Utils {
} }
void handleInputData(char character, int bufferIndex) { void handleInputData(char character, int bufferIndex) {
String* data; String* data = (bufferIndex == -1) ? &inputSerialBuffer : &inputServerBuffer[bufferIndex];
if (bufferIndex == -1) { if (data->length() == 0 && character != (char)FEND) return;
data = &inputSerialBuffer;
} else {
data = &inputServerBuffer[bufferIndex];
}
if (data->length() == 0 && character != (char)FEND) {
return;
}
data->concat(character); data->concat(character);
if (character == (char)FEND && data->length() > 3) { if (character == (char)FEND && data->length() > 3) {
+52 -58
View File
@@ -103,20 +103,15 @@ namespace Utils {
} }
void activeStations() { void activeStations() {
fourthLine = "Stations ("; char buffer[30]; // Adjust size as needed
fourthLine.concat(String(Config.rememberStationTime)); sprintf(buffer, "Stations (%dmin) = %2d", Config.rememberStationTime, lastHeardStations.size());
fourthLine.concat("min) = "); fourthLine = buffer;
if (lastHeardStations.size() < 10) {
fourthLine += " ";
}
fourthLine.concat(String(lastHeardStations.size()));
} }
void sendInitialTelemetryPackets() { void sendInitialTelemetryPackets() {
String sender = Config.callsign; char sender[10]; // 9 characters + null terminator
for (int i = sender.length(); i < 9; i++) { snprintf(sender, sizeof(sender), "%-9s", Config.callsign.c_str()); // Left-align with spaces
sender += ' ';
}
String baseAPRSISTelemetryPacket = Config.callsign; String baseAPRSISTelemetryPacket = Config.callsign;
baseAPRSISTelemetryPacket += ">APLRG1,TCPIP,qAC::"; baseAPRSISTelemetryPacket += ">APLRG1,TCPIP,qAC::";
baseAPRSISTelemetryPacket += sender; baseAPRSISTelemetryPacket += sender;
@@ -137,7 +132,7 @@ namespace Utils {
telemetryPacket1 += "0,0.01,0"; telemetryPacket1 += "0,0.01,0";
} }
if (Config.battery.sendExternalVoltage) { if (Config.battery.sendExternalVoltage) {
telemetryPacket1 += String(Config.battery.sendInternalVoltage ? "," : "") + "0,0.02,0"; telemetryPacket1 += String(Config.battery.sendInternalVoltage ? ",0,0.02,0" : "0,0.02,0");
} }
String telemetryPacket2 = "UNIT."; String telemetryPacket2 = "UNIT.";
@@ -145,7 +140,7 @@ namespace Utils {
telemetryPacket2 += "VDC"; telemetryPacket2 += "VDC";
} }
if (Config.battery.sendExternalVoltage) { if (Config.battery.sendExternalVoltage) {
telemetryPacket2 += String(Config.battery.sendInternalVoltage ? "," : "") + "VDC"; telemetryPacket2 += String(Config.battery.sendInternalVoltage ? ",VDC" : "VDC");
} }
String telemetryPacket3 = "PARM."; String telemetryPacket3 = "PARM.";
@@ -153,7 +148,7 @@ namespace Utils {
telemetryPacket3 += "V_Batt"; telemetryPacket3 += "V_Batt";
} }
if (Config.battery.sendExternalVoltage) { if (Config.battery.sendExternalVoltage) {
telemetryPacket3 += String(Config.battery.sendInternalVoltage ? "," : "") + "V_Ext"; telemetryPacket3 += String(Config.battery.sendInternalVoltage ? ",V_Ext" : "V_Ext");
} }
if (Config.beacon.sendViaAPRSIS) { if (Config.beacon.sendViaAPRSIS) {
@@ -200,7 +195,12 @@ namespace Utils {
if (beaconUpdate) { if (beaconUpdate) {
if (!Config.display.alwaysOn && Config.display.timeout != 0) displayToggle(true); if (!Config.display.alwaysOn && Config.display.timeout != 0) displayToggle(true);
if (sendStartTelemetry && Config.battery.sendVoltageAsTelemetry && !Config.wxsensor.active && (Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage)) { if (sendStartTelemetry &&
Config.battery.sendVoltageAsTelemetry &&
!Config.wxsensor.active &&
(Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) &&
(lastBeaconTx > 0)) {
//(!Config.digi.ecoMode || lastBeaconTx > 0)) {
sendInitialTelemetryPackets(); sendInitialTelemetryPackets();
} }
@@ -222,13 +222,10 @@ namespace Utils {
} }
#endif #endif
if (Config.wxsensor.active && wxModuleType != 0) { if (Config.wxsensor.active) {
String sensorData = WX_Utils::readDataSensor(); const char* sensorData = (wxModuleType == 0) ? ".../...g...t..." : WX_Utils::readDataSensor().c_str();
beaconPacket += sensorData; beaconPacket += sensorData;
secondaryBeaconPacket += sensorData; secondaryBeaconPacket += sensorData;
} else if (Config.wxsensor.active && wxModuleType == 0) {
beaconPacket += ".../...g...t...";
secondaryBeaconPacket += ".../...g...t...";
} }
beaconPacket += Config.beacon.comment; beaconPacket += Config.beacon.comment;
secondaryBeaconPacket += Config.beacon.comment; secondaryBeaconPacket += Config.beacon.comment;
@@ -242,11 +239,14 @@ namespace Utils {
shouldSleepLowVoltage = true; shouldSleepLowVoltage = true;
} }
String internalVoltageInfo = String(internalVoltage,2) + "V";
if (Config.battery.sendInternalVoltage) { if (Config.battery.sendInternalVoltage) {
sixthLine = " (Batt="; char internalVoltageInfo[10]; // Enough to hold "xx.xxV\0"
sixthLine += internalVoltageInfo; snprintf(internalVoltageInfo, sizeof(internalVoltageInfo), "%.2fV", internalVoltage);
sixthLine += ")";
char sixthLineBuffer[25]; // Enough to hold " (Batt=xx.xxV)"
snprintf(sixthLineBuffer, sizeof(sixthLineBuffer), " (Batt=%s)", internalVoltageInfo);
sixthLine = sixthLineBuffer;
if (!Config.battery.sendVoltageAsTelemetry) { if (!Config.battery.sendVoltageAsTelemetry) {
beaconPacket += " Batt="; beaconPacket += " Batt=";
beaconPacket += internalVoltageInfo; beaconPacket += internalVoltageInfo;
@@ -266,11 +266,14 @@ namespace Utils {
shouldSleepLowVoltage = true; shouldSleepLowVoltage = true;
} }
String externalVoltageInfo = String(externalVoltage,2) + "V";
if (Config.battery.sendExternalVoltage) { if (Config.battery.sendExternalVoltage) {
sixthLine = " (Ext V="; char externalVoltageInfo[10]; // "xx.xxV\0" (max 7 chars)
sixthLine += externalVoltageInfo; snprintf(externalVoltageInfo, sizeof(externalVoltageInfo), "%.2fV", externalVoltage);
sixthLine += ")";
char sixthLineBuffer[25]; // Ensure enough space
snprintf(sixthLineBuffer, sizeof(sixthLineBuffer), " (Ext V=%s)", externalVoltageInfo);
sixthLine = sixthLineBuffer;
if (!Config.battery.sendVoltageAsTelemetry) { if (!Config.battery.sendVoltageAsTelemetry) {
beaconPacket += " Ext="; beaconPacket += " Ext=";
beaconPacket += externalVoltageInfo; beaconPacket += externalVoltageInfo;
@@ -345,54 +348,45 @@ namespace Utils {
fifthLine = "LoRa Rx ----> LoRa Tx"; fifthLine = "LoRa Rx ----> LoRa Tx";
break; break;
} }
int firstColonIndex = packet.indexOf(":");
char nextChar = packet[firstColonIndex + 1];
for (int i = sender.length(); i < 9; i++) { for (int i = sender.length(); i < 9; i++) {
sender += " "; sender += " ";
} }
sixthLine = sender; sixthLine = sender;
String seventhLineHelper = "RSSI:";
seventhLineHelper += String(rssi);
seventhLineHelper += "dBm SNR: ";
seventhLineHelper += String(snr);
seventhLineHelper += "dBm";
int firstColonIndex = packet.indexOf(":"); if (nextChar == ':') {
if (packet[firstColonIndex + 1] == ':') {
sixthLine += "> MESSAGE"; sixthLine += "> MESSAGE";
seventhLine = seventhLineHelper; } else if (nextChar == '>') {
} else if (packet[firstColonIndex + 1] == '>') {
sixthLine += "> NEW STATUS"; sixthLine += "> NEW STATUS";
seventhLine = seventhLineHelper; } else if (nextChar == '!' || nextChar == '=' || nextChar == '@') {
} else if (packet[firstColonIndex + 1] == '!' || packet[firstColonIndex + 1] == '=' || packet[firstColonIndex + 1] == '@') {
sixthLine += "> GPS BEACON"; sixthLine += "> GPS BEACON";
if (!Config.syslog.active) { if (!Config.syslog.active) GPS_Utils::getDistanceAndComment(packet); // to be checked!!!
GPS_Utils::getDistanceAndComment(packet); // to be checked!!!
}
seventhLine = "RSSI:"; seventhLine = "RSSI:";
seventhLine += String(rssi); seventhLine += String(rssi);
seventhLine += "dBm"; seventhLine += "dBm";
if (rssi <= -100) { seventhLine += (rssi <= -100) ? " " : " ";
seventhLine += " "; if (distance.indexOf(".") == 1) seventhLine += " ";
} else {
seventhLine += " ";
}
if (distance.indexOf(".") == 1) {
seventhLine += " ";
}
seventhLine += "D:"; seventhLine += "D:";
seventhLine += distance; seventhLine += distance;
seventhLine += "km"; seventhLine += "km";
} else if (packet[firstColonIndex + 1] == '`' || packet[firstColonIndex + 1] == '\'') { } else if (nextChar == '`' || nextChar == '\'') {
sixthLine += "> MIC-E"; sixthLine += "> MIC-E";
seventhLine = seventhLineHelper; } else if (nextChar == ';') {
} else if (packet[firstColonIndex + 1] == ';') {
sixthLine += "> OBJECT"; sixthLine += "> OBJECT";
seventhLine = seventhLineHelper;
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) { } else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) {
sixthLine += "> TELEMETRY"; sixthLine += "> TELEMETRY";
seventhLine = seventhLineHelper;
} else { } else {
sixthLine += "> ??????????"; sixthLine += "> ??????????";
seventhLine = seventhLineHelper; }
if (nextChar != '!' && nextChar != '=' && nextChar != '@') { // Common assignment for non-GPS cases
seventhLine = "RSSI:";
seventhLine += String(rssi);
seventhLine += "dBm SNR: ";
seventhLine += String(snr);
seventhLine += "dBm";
} }
} }
+13 -7
View File
@@ -1,4 +1,6 @@
#include <TinyGPS++.h>
#include "configuration.h" #include "configuration.h"
#include "board_pinout.h"
#include "wx_utils.h" #include "wx_utils.h"
#include "display.h" #include "display.h"
@@ -8,6 +10,9 @@
extern Configuration Config; extern Configuration Config;
extern String fifthLine; extern String fifthLine;
#ifdef HAS_GPS
extern TinyGPSPlus gps;
#endif
int wxModuleType = 0; int wxModuleType = 0;
uint8_t wxModuleAddress = 0x00; uint8_t wxModuleAddress = 0x00;
@@ -227,13 +232,14 @@ namespace WX_Utils {
humStr = ".."; humStr = "..";
} }
String presStr; String presStr = (wxModuleAddress == 4)
if (wxModuleAddress == 4) { ? "....."
presStr = "....."; #ifdef HAS_GPS
} else { : generatePresString(newPress + (gps.altitude.meters() / CORRECTION_FACTOR));
presStr = generatePresString(newPress + (Config.wxsensor.heightCorrection/CORRECTION_FACTOR)); #else
} : generatePresString(newPress + (Config.wxsensor.heightCorrection / CORRECTION_FACTOR));
#endif
fifthLine = "BME-> "; fifthLine = "BME-> ";
fifthLine += String(int(newTemp + Config.wxsensor.temperatureCorrection)); fifthLine += String(int(newTemp + Config.wxsensor.temperatureCorrection));
fifthLine += "C "; fifthLine += "C ";
@@ -4,5 +4,7 @@ board_build.mcu = esp32s3
build_flags = build_flags =
${common.build_flags} ${common.build_flags}
-D HELTEC_WP -D HELTEC_WP
-D WIRELESS_PAPER
lib_deps = lib_deps =
${common.lib_deps} ${common.lib_deps}
todd-herbert/heltec-eink-modules@^4.4.0
@@ -0,0 +1,37 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1262
#define RADIO_SCLK_PIN 12
#define RADIO_MISO_PIN 13
#define RADIO_MOSI_PIN 11
#define RADIO_CS_PIN 10
#define RADIO_DIO0_PIN -1
#define RADIO_RST_PIN 5
#define RADIO_DIO1_PIN 1
#define RADIO_BUSY_PIN 4
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 17
#define OLED_SCL 18
#define OLED_RST 16
#define OLED_DISPLAY_HAS_RST_PIN
// Aditional Config
#define HAS_AXP2101
// GPS
#define HAS_GPS
#define GPS_RX 8
#define GPS_TX 9
#define BOARD_HAS_PSRAM
#endif
@@ -0,0 +1,12 @@
[env:ttgo_t_beam_s3_SUPREME_v3]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
${common.usb_flags}
-D TTGO_T_Beam_S3_SUPREME_V3
lib_deps =
${common.lib_deps}
${common.display_libs}
lewisxhe/XPowersLib @ 0.2.4
adafruit/Adafruit SH110X @ 2.1.10