Compare commits

...

21 Commits

Author SHA1 Message Date
Ricardo Guzman (Richonguzman) e593b2c670 version number update 2025-11-08 21:16:03 -03:00
Ricardo Guzman (Richonguzman) 08a7e0aac1 T-Beam Supreme Screen Fix 2025-11-08 21:13:57 -03:00
Ricardo Guzman (Richonguzman) 9b258c42ab checkValidCallsign update 2025-11-06 10:11:55 -03:00
richonguzman 8712122d33 raw images 2025-10-29 10:34:43 -03:00
richonguzman 9e34684627 update pdf y blob 2025-10-29 10:28:25 -03:00
richonguzman e4aa52241d sin gitattributes ahora 2025-10-29 10:11:18 -03:00
richonguzman c840ef01fa sin manual en github 2025-10-29 10:10:58 -03:00
richonguzman 98f85725f8 test con Vista Previa 2025-10-29 09:13:48 -03:00
richonguzman 10bde884b1 new gitattributes 2025-10-28 22:54:22 -03:00
richonguzman 546e4f63a4 update pdf to v1.4 2025-10-28 22:46:44 -03:00
Ricardo Guzman (Richonguzman) 87f2ec2b7b test new version pdf 20250128 2025-10-28 22:40:15 -03:00
Ricardo Guzman (Richonguzman) c9c7e24aae Merge pull request #356 from richonguzman/richonguzman-patch-15
Delete manual/LoRa_APRS_iGate_CA2RXU_Firmware_Manual.pdf
2025-10-28 22:38:23 -03:00
Ricardo Guzman (Richonguzman) b86133223d Delete manual/LoRa_APRS_iGate_CA2RXU_Firmware_Manual.pdf 2025-10-28 22:38:02 -03:00
richonguzman 880a41bfd8 update manual 20251028 2025-10-28 22:34:06 -03:00
richonguzman d610b3a90f mqtt beacon fix 2025-10-21 14:33:58 -03:00
richonguzman 23a33ed27c new message warning 2025-10-19 14:20:11 -03:00
richonguzman 72ef827900 new update pdf manual v314 2025-10-18 11:42:18 -03:00
richonguzman b756f97f55 v314 manual update 2025-10-18 10:50:54 -03:00
richonguzman 2625e7b91d update readme v314 2025-10-15 17:29:26 -03:00
richonguzman 75337d6c29 update to Tnc strip bytes 2025-10-15 17:12:38 -03:00
richonguzman a618383617 APRS Bridge for TNC 2025-10-15 15:11:07 -03:00
14 changed files with 76 additions and 42 deletions
+5 -4
View File
@@ -2,7 +2,7 @@
This firmware is for using ESP32 based boards with LoRa Modules and GPS to live in the APRS world. This firmware is for using ESP32 based boards with LoRa Modules and GPS to live in the APRS world.
![Screenshot](https://github.com/richonguzman/LoRa_APRS_iGate/blob/main/images/iGateOledScreen.jpeg) ![Screenshot](https://github.com/richonguzman/LoRa_APRS_iGate/raw/main/images/iGateOledScreen.jpeg)
__(This iGate Firmware works with all LoRa Tracker Firmwares (specially this <a href="https://github.com/richonguzman/LoRa_APRS_Tracker" target="_blank">LoRa APRS Tracker Firmware</a>))__ __(This iGate Firmware works with all LoRa Tracker Firmwares (specially this <a href="https://github.com/richonguzman/LoRa_APRS_Tracker" target="_blank">LoRa APRS Tracker Firmware</a>))__
<br /> <br />
@@ -12,13 +12,13 @@ ____________________________________________________
# <a href="https://richonguzman.github.io/lora-igate-web-flasher/installer.html" target="_blank">WEB FLASHER/INSTALLER</a> # <a href="https://richonguzman.github.io/lora-igate-web-flasher/installer.html" target="_blank">WEB FLASHER/INSTALLER</a>
# <a href="https://github.com/richonguzman/LoRa_APRS_iGate/blob/main/manual/LoRa_APRS_iGate_CA2RXU_Firmware_Manual.pdf" target="_blank">LoRa APRS iGate CA2RXU Firmware Manual</a> # <a href="https://drive.google.com/file/d/1-jafzOWis_qOaNUl4WGVcFKjh_uCJtB6/view?usp=share_link" target="_blank">LoRa APRS iGate CA2RXU Firmware Manual</a>
____________________________________________________ ____________________________________________________
## You can support this project to continue to grow: ## You can support this project to continue to grow:
[<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/github-sponsors.png">](https://github.com/sponsors/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/paypalme.png">](http://paypal.me/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/raw/main/images/github-sponsors.png">](https://github.com/sponsors/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/raw/main/images/paypalme.png">](http://paypal.me/richonguzman)
____________________________________________________ ____________________________________________________
@@ -51,9 +51,10 @@ ____________________________________________________
<br /> <br />
# Timeline (Versions): # Timeline (Versions):
- 2025-10-15 APRS Bridge for TNC added.
- 2025-10-13 Rx and Tx Frequencies are now with fully configurable. - 2025-10-13 Rx and Tx Frequencies are now with fully configurable.
- 2025-10-13 Startup Delay to allow the Router/Modem to start WiFiAP before connecting. - 2025-10-13 Startup Delay to allow the Router/Modem to start WiFiAP before connecting.
- 2025-10-12 Choose to send Beacon on Rx or Tx frequency in Digipeater Mode. - 2025-10-12 Choose to send Beacon on Rx or Tx frequency.
- 2025-10-11 User defined NTP server and send beacon over MQTT added. - 2025-10-11 User defined NTP server and send beacon over MQTT added.
- 2025-10-10 Converted the Wiki into a PDF manual. - 2025-10-10 Converted the Wiki into a PDF manual.
- 2025-09-26 Heltec Wireless Bridge support added. - 2025-09-26 Heltec Wireless Bridge support added.
+2 -1
View File
@@ -82,7 +82,8 @@
"tnc": { "tnc": {
"enableServer": false, "enableServer": false,
"enableSerial": false, "enableSerial": false,
"acceptOwn": false "acceptOwn": false,
"aprsBrigdeActive": false
}, },
"mqtt": { "mqtt": {
"active": false, "active": false,
+34 -20
View File
@@ -1511,25 +1511,7 @@
</div> </div>
<div class="col-lg-9 col-sm-12"> <div class="col-lg-9 col-sm-12">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-6">
<div class="form-check form-switch">
<div class="form-text">
Server will be available at port <strong>8001</strong>
</div>
<input
type="checkbox"
name="tnc.enableServer"
id="tnc.enableServer"
class="form-check-input"
/>
<label
for="tnc.enableServer"
class="form-label"
>Enable TNC server</label
>
</div>
</div>
<div class="col-12">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input <input
type="checkbox" type="checkbox"
@@ -1544,7 +1526,24 @@
> >
</div> </div>
</div> </div>
<div class="col-12"> <div class="col-6">
<div class="form-check form-switch">
<input
type="checkbox"
name="tnc.enableServer"
id="tnc.enableServer"
class="form-check-input"
/>
<label
for="tnc.enableServer"
class="form-label"
>Enable TNC server <small><strong>(Port 8001)</strong></small></label
>
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-6">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input <input
type="checkbox" type="checkbox"
@@ -1559,6 +1558,21 @@
> >
</div> </div>
</div> </div>
<div class="col-6">
<div class="form-check form-switch">
<input
type="checkbox"
name="tnc.aprsBridgeActive"
id="tnc.aprsBridgeActive"
class="form-check-input"
/>
<label
for="tnc.aprsBridgeActive"
class="form-label"
>Enable APRS Bridge</label
>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
+2 -1
View File
@@ -206,6 +206,7 @@ function loadSettings(settings) {
document.getElementById("tnc.enableServer").checked = settings.tnc.enableServer; document.getElementById("tnc.enableServer").checked = settings.tnc.enableServer;
document.getElementById("tnc.enableSerial").checked = settings.tnc.enableSerial; document.getElementById("tnc.enableSerial").checked = settings.tnc.enableSerial;
document.getElementById("tnc.acceptOwn").checked = settings.tnc.acceptOwn; document.getElementById("tnc.acceptOwn").checked = settings.tnc.acceptOwn;
document.getElementById("tnc.aprsBridgeActive").checked = settings.tnc.aprsBridgeActive;
} }
// MQTT // MQTT
@@ -215,7 +216,7 @@ function loadSettings(settings) {
document.getElementById("mqtt.username").value = settings.mqtt.username; document.getElementById("mqtt.username").value = settings.mqtt.username;
document.getElementById("mqtt.password").value = settings.mqtt.password; document.getElementById("mqtt.password").value = settings.mqtt.password;
document.getElementById("mqtt.port").value = settings.mqtt.port; document.getElementById("mqtt.port").value = settings.mqtt.port;
document.getElementById("mqtt.beaconOverMqtt").value = settings.mqtt.beaconOverMqtt; document.getElementById("mqtt.beaconOverMqtt").checked = settings.mqtt.beaconOverMqtt;
MqttCheckbox.checked = settings.mqtt.active; MqttCheckbox.checked = settings.mqtt.active;
MqttServer.disabled = !MqttCheckbox.check; MqttServer.disabled = !MqttCheckbox.check;
MqttTopic.disabled = !MqttCheckbox.check; MqttTopic.disabled = !MqttCheckbox.check;
+1
View File
@@ -127,6 +127,7 @@ public:
bool enableServer; bool enableServer;
bool enableSerial; bool enableSerial;
bool acceptOwn; bool acceptOwn;
bool aprsBridgeActive;
}; };
class OTA { class OTA {
+2 -2
View File
@@ -27,8 +27,8 @@ namespace TNC_Utils {
void setup(); void setup();
void loop(); void loop();
void sendToClients(const String& packet); void sendToClients(const String& packet, bool stripBytes = false);
void sendToSerial(const String& packet); void sendToSerial(const String& packet, bool stripBytes = false);
} }
Binary file not shown.
+5 -5
View File
@@ -67,8 +67,8 @@ ___________________________________________________________________*/
#endif #endif
String versionDate = "2025-10-15"; String versionDate = "2025-11-08";
String versionNumber = "3.1.4"; String versionNumber = "3.1.4.1";
Configuration Config; Configuration Config;
WiFiClient aprsIsClient; WiFiClient aprsIsClient;
WiFiClient mqttClient; WiFiClient mqttClient;
@@ -192,9 +192,9 @@ void loop() {
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi
} }
if (Config.tnc.enableServer) TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS if (Config.tnc.enableServer) TNC_Utils::sendToClients(packet, true); // Send received packet to TNC KISS
if (Config.tnc.enableSerial) TNC_Utils::sendToSerial(packet); // Send received packet to Serial KISS if (Config.tnc.enableSerial) TNC_Utils::sendToSerial(packet, true); // Send received packet to Serial KISS
if (Config.mqtt.active) MQTT_Utils::sendToMqtt(packet); // Send received packet to MQTT if (Config.mqtt.active) MQTT_Utils::sendToMqtt(packet); // Send received packet to MQTT
} }
if (Config.aprs_is.active) APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS if (Config.aprs_is.active) APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS
+5
View File
@@ -25,6 +25,7 @@
#include "query_utils.h" #include "query_utils.h"
#include "A7670_utils.h" #include "A7670_utils.h"
#include "digi_utils.h" #include "digi_utils.h"
#include "tnc_utils.h"
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
@@ -367,6 +368,10 @@ namespace APRS_IS_Utils {
Serial.println(" ---> Rejected (Time): No Tx"); Serial.println(" ---> Rejected (Time): No Tx");
} }
} }
if (Config.tnc.aprsBridgeActive) {
if (Config.tnc.enableServer) TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS
if (Config.tnc.enableSerial) TNC_Utils::sendToSerial(packet); // Send received packet to Serial KISS
}
} }
} }
+6 -2
View File
@@ -131,6 +131,7 @@ bool Configuration::writeFile() {
data["tnc"]["enableServer"] = tnc.enableServer; data["tnc"]["enableServer"] = tnc.enableServer;
data["tnc"]["enableSerial"] = tnc.enableSerial; data["tnc"]["enableSerial"] = tnc.enableSerial;
data["tnc"]["acceptOwn"] = tnc.acceptOwn; data["tnc"]["acceptOwn"] = tnc.acceptOwn;
data["tnc"]["aprsBridgeActive"] = tnc.aprsBridgeActive;
data["mqtt"]["active"] = mqtt.active; data["mqtt"]["active"] = mqtt.active;
data["mqtt"]["server"] = mqtt.server; data["mqtt"]["server"] = mqtt.server;
@@ -331,10 +332,12 @@ bool Configuration::readFile() {
if (!data["tnc"].containsKey("enableServer") || if (!data["tnc"].containsKey("enableServer") ||
!data["tnc"].containsKey("enableSerial") || !data["tnc"].containsKey("enableSerial") ||
!data["tnc"].containsKey("acceptOwn")) needsRewrite = true; !data["tnc"].containsKey("acceptOwn") ||
!data["tnc"].containsKey("aprsBridgeActive")) needsRewrite = true;
tnc.enableServer = data["tnc"]["enableServer"] | false; tnc.enableServer = data["tnc"]["enableServer"] | false;
tnc.enableSerial = data["tnc"]["enableSerial"] | false; tnc.enableSerial = data["tnc"]["enableSerial"] | false;
tnc.acceptOwn = data["tnc"]["acceptOwn"] | false; tnc.acceptOwn = data["tnc"]["acceptOwn"] | false;
tnc.aprsBridgeActive = data["tnc"]["aprsBridgeActive"] | false;
if (!data["mqtt"].containsKey("active") || if (!data["mqtt"].containsKey("active") ||
!data["mqtt"].containsKey("server") || !data["mqtt"].containsKey("server") ||
@@ -496,6 +499,7 @@ void Configuration::setDefaultValues() {
tnc.enableServer = false; tnc.enableServer = false;
tnc.enableSerial = false; tnc.enableSerial = false;
tnc.acceptOwn = false; tnc.acceptOwn = false;
tnc.aprsBridgeActive = false;
mqtt.active = false; mqtt.active = false;
mqtt.server = ""; mqtt.server = "";
@@ -525,7 +529,7 @@ void Configuration::setDefaultValues() {
backupDigiMode = false; backupDigiMode = false;
Serial.println("All is Written!"); Serial.println("New Data Created... All is Written!");
} }
Configuration::Configuration() { Configuration::Configuration() {
+2 -1
View File
@@ -96,6 +96,7 @@ void displaySetup() {
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
display.landscape(); display.landscape();
display.printCenter("LoRa APRS iGate Initialising..."); display.printCenter("LoRa APRS iGate Initialising...");
if (Config.display.turn180) display.setRotation(2);
display.update(); display.update();
#else #else
#ifdef OLED_DISPLAY_HAS_RST_PIN #ifdef OLED_DISPLAY_HAS_RST_PIN
@@ -106,7 +107,7 @@ void displaySetup() {
#endif #endif
#if defined(TTGO_T_Beam_S3_SUPREME_V3) #if defined(TTGO_T_Beam_S3_SUPREME_V3)
if (!display.begin(0x3c, false)) { if (display.begin(0x3c, false)) {
displayFound = true; displayFound = true;
if (Config.display.turn180) display.setRotation(2); if (Config.display.turn180) display.setRotation(2);
display.clearDisplay(); display.clearDisplay();
+10 -6
View File
@@ -21,12 +21,15 @@
#include "configuration.h" #include "configuration.h"
#include "station_utils.h" #include "station_utils.h"
#include "kiss_protocol.h" #include "kiss_protocol.h"
#include "aprs_is_utils.h"
#include "kiss_utils.h" #include "kiss_utils.h"
#include "tnc_utils.h" #include "tnc_utils.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern WiFiClient aprsIsClient;
extern bool passcodeValid;
#define MAX_CLIENTS 4 #define MAX_CLIENTS 4
#define INPUT_BUFFER_SIZE (2 + MAX_CLIENTS) #define INPUT_BUFFER_SIZE (2 + MAX_CLIENTS)
@@ -94,7 +97,8 @@ namespace TNC_Utils {
String sender = frame.substring(0,frame.indexOf(">")); String sender = frame.substring(0,frame.indexOf(">"));
if (Config.tnc.acceptOwn || sender != Config.callsign) { if (Config.tnc.acceptOwn || sender != Config.callsign) {
STATION_Utils::addToOutputPacketBuffer(frame); if (Config.loramodule.txActive) STATION_Utils::addToOutputPacketBuffer(frame);
if (Config.tnc.aprsBridgeActive && Config.aprs_is.active && passcodeValid && aprsIsClient.connected()) APRS_IS_Utils::upload(frame);
} else { } else {
Utils::println("Ignored own frame from KISS"); Utils::println("Ignored own frame from KISS");
} }
@@ -131,8 +135,8 @@ namespace TNC_Utils {
} }
} }
void sendToClients(const String& packet) { void sendToClients(const String& packet, bool stripBytes) {
String cleanPacket = packet.substring(3); String cleanPacket = stripBytes ? packet.substring(3): packet;
const String kissEncoded = encodeKISS(cleanPacket); const String kissEncoded = encodeKISS(cleanPacket);
@@ -152,8 +156,8 @@ namespace TNC_Utils {
Utils::println(cleanPacket); Utils::println(cleanPacket);
} }
void sendToSerial(const String& packet) { void sendToSerial(const String& packet, bool stripBytes) {
String cleanPacket = packet.substring(3); String cleanPacket = stripBytes ? packet.substring(3): packet;
Serial.print(encodeKISS(cleanPacket)); Serial.print(encodeKISS(cleanPacket));
Serial.flush(); Serial.flush();
} }
+1
View File
@@ -402,6 +402,7 @@ namespace Utils {
cleanCallsign = callsign.substring(0, callsign.indexOf("-")); cleanCallsign = callsign.substring(0, callsign.indexOf("-"));
String ssid = callsign.substring(callsign.indexOf("-") + 1); String ssid = callsign.substring(callsign.indexOf("-") + 1);
if (ssid.indexOf("-") != -1 || ssid.length() > 2) return false; if (ssid.indexOf("-") != -1 || ssid.length() > 2) return false;
if (ssid.length() == 2 && ssid[0] == '0') return false;
for (int i = 0; i < ssid.length(); i++) { for (int i = 0; i < ssid.length(); i++) {
if (!isAlphaNumeric(ssid[i])) return false; if (!isAlphaNumeric(ssid[i])) return false;
} }
+1
View File
@@ -259,6 +259,7 @@ namespace WEB_Utils {
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true); Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true); Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true);
Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true); Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true);
Config.tnc.aprsBridgeActive = request->hasParam("tnc.aprsBridgeActive", true);
Config.mqtt.active = request->hasParam("mqtt.active", true); Config.mqtt.active = request->hasParam("mqtt.active", true);