mirror of
https://github.com/richonguzman/LoRa_APRS_iGate.git
synced 2026-07-15 06:11:37 +02:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25ea82737a | |||
| df22b9dbc0 | |||
| 9898e123d2 | |||
| a97757c0b2 | |||
| 305c5b73f7 | |||
| dd3688f23b | |||
| 6f5846c53d | |||
| 5c30e72a88 | |||
| a024b939f5 |
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
|
||||
class LoraModule {
|
||||
public:
|
||||
bool cadActive;
|
||||
bool rxActive;
|
||||
long rxFreq;
|
||||
int rxSpreadingFactor;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user