Compare commits

...

15 Commits

Author SHA1 Message Date
Ricardo Guzman (Richonguzman) 25ea82737a cad test 3 2026-06-10 10:46:07 -04:00
Ricardo Guzman (Richonguzman) df22b9dbc0 readme and date update 2026-06-10 00:27:15 -04:00
Ricardo Guzman (Richonguzman) 9898e123d2 CAD with backoff process 2026-06-10 00:25:27 -04:00
Ricardo Guzman (Richonguzman) a97757c0b2 test CAD 2026-06-09 22:46:41 -04:00
Ricardo Guzman (Richonguzman) 305c5b73f7 mayusculas a RPC 2026-04-21 11:16:02 -04:00
Ricardo Guzman (Richonguzman) dd3688f23b fake name 2026-04-21 11:12:00 -04:00
Ricardo Guzman (Richonguzman) 6f5846c53d test algo dos 2026-04-21 11:05:52 -04:00
Ricardo Guzman (Richonguzman) 5c30e72a88 test algo 2026-04-21 11:05:27 -04:00
Ricardo Guzman (Richonguzman) a024b939f5 Merge pull request #423 from richonguzman/richonguzman-patch-19
Add RPC_LORA_DIGIGATE_1W to build workflow
2026-04-21 10:42:19 -04:00
Ricardo Guzman (Richonguzman) 96c52c042e Add RPC_LORA_DIGIGATE_1W to build workflow 2026-04-21 10:40:33 -04:00
Ricardo Guzman (Richonguzman) 236ae65485 ElegantOta fix 2026-04-21 10:34:20 -04:00
Ricardo Guzman (Richonguzman) 4263d55839 screen height fix 2026-04-20 12:56:03 -04:00
Ricardo Guzman (Richonguzman) ba96bb135e test new screen 2026-04-20 12:37:52 -04:00
Ricardo Guzman (Richonguzman) 944d1fceaf cleaning code again 2026-04-13 15:24:55 -04:00
Ricardo Guzman (Richonguzman) 005abb3593 Merge pull request #412 from richonguzman/richonguzman-patch-18
Add 2 new target configurations for GPS variants
2026-03-25 12:22:03 -03:00
14 changed files with 138 additions and 25 deletions
+2
View File
@@ -101,6 +101,8 @@ jobs:
chip: esp32s3
- name: QRPLabs_LightGateway_Plus_1_0
chip: esp32s3
- name: RPC_LORA_DIGIGATE_1W
chip: esp32
- name: XIAO_ESP32S3_WIO_SX1262
chip: esp32s3
- name: TROY_LoRa_APRS
+1
View File
@@ -51,6 +51,7 @@ ____________________________________________________
<br />
# Timeline (Versions):
- 2026-06-10 CAD (Channel Activity Detection) and DIFS (Distributed Inter-Frame Space) added.
- 2026-03-25 More Boards, SDK update, OTA fix, GPS process update.
- 2026-02-26 9M2IBR ESP32 1W (400M30S) + GPS board added.
- 2026-02-25 Code Improvements: reduced String comparisons and improved logic for faster code execution.
+3 -2
View File
@@ -28,9 +28,9 @@
"messagesToRF": false,
"objectsToRF": false,
"server": "rotate.aprs2.net",
"passcode": "XYZVW",
"passcode": "XYZVW",
"port": 14580,
"filter": "m/10"
"filter": "m/10"
},
"personalNote": "",
"blacklist": "",
@@ -40,6 +40,7 @@
"backupDigiMode": false
},
"lora": {
"cadActive": true,
"rxActive": true,
"rxFreq": 433775000,
"rxSpreadingFactor": 12,
+1
View File
@@ -75,6 +75,7 @@ public:
class LoraModule {
public:
bool cadActive;
bool rxActive;
long rxFreq;
int rxSpreadingFactor;
+2 -2
View File
@@ -68,8 +68,8 @@ ___________________________________________________________________*/
#endif
String versionDate = "2026-03-25";
String versionNumber = "3.2.3";
String versionDate = "2026-06-10";
String versionNumber = "3.3.0";
Configuration Config;
WiFiClient aprsIsClient;
WiFiClient mqttClient;
+1 -3
View File
@@ -16,7 +16,7 @@
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
*/
#include <APRSPacketLib.h>
#include <APRSPacketLib.h>
#include <WiFiClient.h>
#include "configuration.h"
#include "network_manager.h"
@@ -47,7 +47,6 @@ extern bool modemLoggedToAPRSIS;
extern bool backupDigiMode;
extern String versionNumber;
uint32_t lastRxTime = millis();
bool passcodeValid = false;
uint32_t lastServerCheck = 0;
@@ -403,7 +402,6 @@ namespace APRS_IS_Utils {
String aprsisPacket = aprsIsClient.readStringUntil('\r');
aprsisPacket.trim(); // Serial.println(aprsisPacket);
processAPRSISPacket(aprsisPacket);
lastRxTime = millis();
}
}
#endif
+5 -1
View File
@@ -97,6 +97,7 @@ bool Configuration::writeFile() {
#endif
data["digi"]["backupDigiMode"] = digi.backupDigiMode;
data["lora"]["cadActive"] = loramodule.cadActive;
data["lora"]["rxActive"] = loramodule.rxActive;
data["lora"]["rxFreq"] = loramodule.rxFreq;
data["lora"]["rxCodingRate4"] = loramodule.rxCodingRate4;
@@ -291,7 +292,8 @@ bool Configuration::readFile() {
digi.backupDigiMode = data["digi"]["backupDigiMode"] | false;
if (data["lora"]["rxActive"].isNull() ||
if (data["lora"]["cadActive"].isNull() ||
data["lora"]["rxActive"].isNull() ||
data["lora"]["rxFreq"].isNull() ||
data["lora"]["rxSpreadingFactor"].isNull() ||
data["lora"]["rxCodingRate4"].isNull() ||
@@ -302,6 +304,7 @@ bool Configuration::readFile() {
data["lora"]["txCodingRate4"].isNull() ||
data["lora"]["txSignalBandwidth"].isNull() ||
data["lora"]["power"].isNull()) needsRewrite = true;
loramodule.cadActive = data["lora"]["cadActive"] | true;
loramodule.rxActive = data["lora"]["rxActive"] | true;
loramodule.rxFreq = data["lora"]["rxFreq"] | 433775000;
loramodule.rxSpreadingFactor = data["lora"]["rxSpreadingFactor"] | 12;
@@ -492,6 +495,7 @@ void Configuration::setDefaultValues() {
digi.ecoMode = 0;
digi.backupDigiMode = false;
loramodule.cadActive = true;
loramodule.rxActive = true;
loramodule.rxFreq = 433775000;
loramodule.rxSpreadingFactor = 12;
-1
View File
@@ -23,7 +23,6 @@
#include "digi_utils.h"
#include "wifi_utils.h"
#include "lora_utils.h"
#include "gps_utils.h"
#include "display.h"
#include "utils.h"
+13 -2
View File
@@ -65,7 +65,12 @@
#ifdef HELTEC_WSL_V3_DISPLAY
Adafruit_SSD1306 display(128, 64, &Wire1, OLED_RST);
#else
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);
#if defined RPC_LORA_DIGIGATE_1W
#define SCREEN_HEIGHT 32
#else
#define SCREEN_HEIGHT 64
#endif
Adafruit_SSD1306 display(128, SCREEN_HEIGHT, &Wire, OLED_RST);
#endif
#endif
#endif
@@ -75,6 +80,7 @@
extern Configuration Config;
bool displayFound = false;
int maxLines;
void displaySetup() {
#ifdef HAS_DISPLAY
@@ -97,6 +103,11 @@ void displaySetup() {
sprite.createSprite(160, 80);
#endif
#else
#if (SCREEN_HEIGHT == 64)
maxLines = 6;
#elif (SCREEN_HEIGHT == 32)
maxLines = 3;
#endif
#ifdef HAS_EPAPER
display.landscape();
display.printCenter("LoRa APRS iGate Initialising...");
@@ -297,7 +308,7 @@ void displayShow(const String& header, const String& line1, const String& line2,
display.setCursor(0, 0);
display.println(header);
display.setTextSize(1);
for (int i = 0; i < 6; i++) {
for (int i = 0; i < maxLines; i++) {
display.setCursor(0, 16 + (8 * i));
display.println(*lines[i]);
}
+41 -4
View File
@@ -28,15 +28,19 @@
#include "utils.h"
extern Configuration Config;
extern NetworkManager *networkManager;
extern uint32_t lastRxTime;
extern bool packetIsBeacon;
extern std::vector<ReceivedPacket> receivedPackets;
bool operationDone = true;
bool transmitFlag = true;
bool operationDone = true;
bool transmitFlag = true;
#define DIFS_SLOTS 2 // Number of secuential CAD slots to consider a free channel to Tx
int backoffMax = 4; // Max Backoff value (number of CAD slots to wait before Tx)
#ifdef HAS_SX1262
SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
@@ -167,6 +171,34 @@ namespace LoRa_Utils {
radio.setBandwidth(signalBandwidth);
}
bool doCAD() { // CAD (Channel Activity Detection)
return radio.scanChannel() != RADIOLIB_CHANNEL_FREE; // false=channel free | true=RADIOLIB_LORA_DETECTED or CAD failed
}
bool doDIFS() {
for (uint8_t i = DIFS_SLOTS; i > 0; i--) {
if (doCAD()) return false;
}
return true;
}
void waitForDIFS() {
while (!doDIFS()) {
Serial.println("CAD/DIFS failed, retry...");
}
}
void doBEB() {
int backoffCounter = random(1, backoffMax + 1);
while (backoffCounter > 0) {
if (doCAD()) {
waitForDIFS(); // busy channel: freeze backoff and restart DIFS
} else {
backoffCounter--;
}
}
}
void sendNewPacket(const String& newPacket) {
if (!Config.loramodule.txActive) return;
@@ -179,6 +211,12 @@ namespace LoRa_Utils {
#ifdef INTERNAL_LED_PIN
if (Config.digi.ecoMode != 1) digitalWrite(INTERNAL_LED_PIN, HIGH); // disabled in Ultra Eco Mode
#endif
if (Config.loramodule.cadActive) {
waitForDIFS(); // DIFS (Distributed Inter-Frame Space)
doBEB(); // BEB (Binary Exponential Backoff)
}
int state = radio.transmit("\x3c\xff\x01" + newPacket);
transmitFlag = true;
if (state == RADIOLIB_ERR_NONE) {
@@ -250,7 +288,6 @@ namespace LoRa_Utils {
} else {
packet = "";
}
lastRxTime = millis();
return packet;
}
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
+1 -1
View File
@@ -74,7 +74,7 @@ namespace OTA_Utils {
Serial.println(success ? "OTA update finished successfully!" : "There was an error during OTA update!");
displayShow("", "", statusMessage, "", rebootMessage, "", "", 4000);
isUpdatingOTA = false;
if (!success) isUpdatingOTA = false;
}
}
+1 -9
View File
@@ -25,15 +25,11 @@
#include "utils.h"
#include <vector>
#define SECS_TO_WAIT 3 // soon to be deleted...
extern Configuration Config;
extern uint32_t lastRxTime;
extern String fourthLine;
extern bool shouldSleepLowVoltage;
uint32_t lastTxTime = millis();
std::vector<LastHeardStation> lastHeardStations;
std::vector<String> blacklist;
std::vector<String> managers;
@@ -214,15 +210,11 @@ namespace STATION_Utils {
}
void processOutputPacketBuffer() {
int timeToWait = SECS_TO_WAIT * 1000; // 3 segs between packet Tx and also Rx ???
uint32_t lastRx = millis() - lastRxTime;
uint32_t lastTx = millis() - lastTxTime;
if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) {
if (outputPacketBuffer.size() > 0) {
if (outputPacketBuffer[0].isBeacon) packetIsBeacon = true;
LoRa_Utils::sendNewPacket(outputPacketBuffer[0].packet);
if (outputPacketBuffer[0].isBeacon) packetIsBeacon = false;
outputPacketBuffer.erase(outputPacketBuffer.begin());
lastTxTime = millis();
}
if (shouldSleepLowVoltage) {
while (outputPacketBuffer.size() > 0) {
@@ -0,0 +1,56 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
*
* This file is part of LoRa APRS iGate.
*
* LoRa APRS iGate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1268
#define HAS_1W_LORA
#define HAS_TCXO
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 12
#define RADIO_BUSY_PIN 14
#define RADIO_RXEN 32
#define RADIO_TXEN 25
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
#define GPIO_WAKEUP_PIN GPIO_SEL_12
// I2C
#define USE_WIRE_WITH_OLED_PINS
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// Aditional Config
#define INTERNAL_LED_PIN 2
#define BATTERY_PIN 35
#endif
@@ -0,0 +1,11 @@
[env:RPC_LORA_DIGIGATE_1W]
board = esp32dev
build_flags =
${common.build_flags}
-D RADIOLIB_EXCLUDE_LR11X0=1
-D RADIOLIB_EXCLUDE_SX127X=1
-D RADIOLIB_EXCLUDE_SX128X=1
-D RPC_LORA_DIGIGATE_1W
lib_deps =
${common.lib_deps}
${common.display_libs}