Compare commits

..

4 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
8 changed files with 55 additions and 21 deletions
+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-04-21";
String versionNumber = "3.2.4";
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;
+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 -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) {