kopia lustrzana https://github.com/sh123/esp32_loraprs
Added support for TRACEn-n path and changed sync word to 0x3f for compatibility
rodzic
dff45cf9ac
commit
d7f8779d47
|
@ -7,7 +7,7 @@ Can be used in two modes:
|
|||
- **as a LoRa APRS client**, you need to use APRSDroid application (https://aprsdroid.org), connect to the modem using bluetooth, data will be re-transmitted through the LoRa radio, this is similar to APRSDroid micromodem - https://unsigned.io/micromodem/, received data will be sent back to the APRSDroid using bluetooth. By having two clients you can not only send your position, but also send and receive APRS messages.
|
||||
- **as a LoRa APRS iGate server**, which connects to your WiFI and forwards received LoRa APRS positions into the APRS-IS network, it also reports client signal level, by appending it into the APRS comment, so you can see your signal reports in different locations (could be enabled or disabled). It also supports:
|
||||
- **APRS-IS to RF gating**, so it is possible to enable it together with the filter in the config
|
||||
- **RF digirepating** for basic `WIDEn-n` paths, `TRACE` and others are not supported yet
|
||||
- **RF digirepating** for `WIDEn-n`, `TRACEn-n` new style paths, for `TRACE` will insert own callsign before digipeating
|
||||
- Own station periodic beacon announcement to APRS-IS and RF
|
||||
|
||||
# Compatible Boards
|
||||
|
@ -35,7 +35,7 @@ All work was done on ESP32-WROOM with custom made LoRa shield, if your ESP32 boa
|
|||
- lora spread factor `cfg.LoraSf`, 12 (should decode down to -20dB, choosen with the goal for minimum signal decode)
|
||||
- lora coding rate `cfg.LoraCodingRate`, 7
|
||||
- lora output power `cfg.LoraPower`, 20 (max 20 dBm ~ 100mW, change to lower value if needed)
|
||||
- sync word `cfg.LoraSync`, 0xf3
|
||||
- sync word `cfg.LoraSync`, 0x3f
|
||||
- consider minimum decode level based on on BW + SF 
|
||||
- use 80 MHz ESP32 frequency in Arduino SDK, it will prolong battery life when operating portable, higher CPU speed is not required, there are no CPU intensive operations
|
||||
- uses LoRa **built-in checksum** calculation to drop broken packets
|
||||
|
|
|
@ -54,11 +54,11 @@ String Callsign::ToString() const
|
|||
return result;
|
||||
}
|
||||
|
||||
bool Callsign::Digirepeat(const String &ownCallsign)
|
||||
bool Callsign::Digirepeat()
|
||||
{
|
||||
// only WIDE supported
|
||||
if (call_.startsWith("WIDE*")) return false;
|
||||
if (call_.startsWith("WIDE") && call_.length() >= 5) {
|
||||
// only WIDE and TRACE supported
|
||||
if (call_.startsWith("WIDE*") || call_.startsWith("TRACE*")) return false;
|
||||
if ((call_.startsWith("WIDE") || call_.startsWith("TRACE")) && call_.length() >= 5) {
|
||||
char wideLevel = call_.charAt(4);
|
||||
if ((wideLevel == '1' || wideLevel == '2' || wideLevel == '3') && ssid_ > 0) {
|
||||
if (--ssid_ == 0) {
|
||||
|
|
|
@ -16,11 +16,12 @@ public:
|
|||
Callsign(String inputText);
|
||||
|
||||
inline bool IsValid() const { return isValid_; };
|
||||
inline bool IsTrace() const { return call_.startsWith("TRACE"); }
|
||||
|
||||
String ToString() const;
|
||||
bool ToBinary(byte *txPayload, int bufferLength) const;
|
||||
|
||||
bool Digirepeat(const String &ownCallsign);
|
||||
bool Digirepeat();
|
||||
|
||||
private:
|
||||
bool encode(byte *txPtr, int bufferLength) const;
|
||||
|
|
|
@ -86,16 +86,34 @@ String Payload::ToString(String customComment)
|
|||
return txt + String("\n");
|
||||
}
|
||||
|
||||
bool Payload::Digirepeat(const String &ownCallsign)
|
||||
bool Payload::Digirepeat(const Callsign &ownCallsign)
|
||||
{
|
||||
for (int i = 0; i < rptCallsCount_; i++) {
|
||||
if (rptCalls_[i].Digirepeat(ownCallsign)) {
|
||||
if (rptCalls_[i].Digirepeat()) {
|
||||
// if trace was digirepeated insert own callsign
|
||||
if (rptCalls_[i].IsTrace()) {
|
||||
InsertRptCallsign(ownCallsign, i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Payload::InsertRptCallsign(const Callsign &rptCallsign, int index)
|
||||
{
|
||||
if (rptCallsCount_ >= RptMaxCount
|
||||
|| index >= RptMaxCount
|
||||
|| index >= rptCallsCount_) return false;
|
||||
|
||||
for (int i = index; i < rptCallsCount_; i++) {
|
||||
rptCalls_[i + 1] = rptCalls_[i];
|
||||
}
|
||||
rptCalls_[index] = rptCallsign;
|
||||
rptCallsCount_++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Payload::fromBinary(const byte *rxPayload, int payloadLength)
|
||||
{
|
||||
const byte *rxPtr = rxPayload;
|
||||
|
|
|
@ -18,13 +18,15 @@ public:
|
|||
String ToString(String customComment);
|
||||
int ToBinary(byte *txPayload, int bufferLength) const;
|
||||
|
||||
bool Digirepeat(const String &ownCallsign);
|
||||
bool Digirepeat(const Callsign &ownCallsign);
|
||||
void Dump();
|
||||
|
||||
private:
|
||||
bool fromString(String inputText);
|
||||
bool fromBinary(const byte *rxPayload, int payloadLength);
|
||||
|
||||
bool InsertRptCallsign(const Callsign &rptCallsign, int index);
|
||||
|
||||
private:
|
||||
enum AX25Ctrl {
|
||||
UI = 0x03
|
||||
|
|
|
@ -20,7 +20,7 @@ void initializeConfig() {
|
|||
cfg.LoraBw = 125e3;
|
||||
cfg.LoraSf = 12;
|
||||
cfg.LoraCodingRate = 7;
|
||||
cfg.LoraSync = 0xf3;
|
||||
cfg.LoraSync = 0x3f;
|
||||
cfg.LoraPower = 20;
|
||||
|
||||
// aprs configuration
|
||||
|
@ -29,7 +29,7 @@ void initializeConfig() {
|
|||
cfg.AprsLogin = "NOCALL-10";
|
||||
cfg.AprsPass = "12345";
|
||||
cfg.AprsFilter = "r/35.60/139.80/25";
|
||||
cfg.AprsRawBeacon = "NOCALL-10>APZMDM,WIDE1-1:!0000.00N/00000.00E#LoRA 433.775MHz/BW125/SF12/CR7/0xf3";
|
||||
cfg.AprsRawBeacon = "NOCALL-10>APZMDM,WIDE1-1:!0000.00N/00000.00E#LoRa 433.775MHz/BW125/SF12/CR7/0xf3";
|
||||
cfg.AprsRawBeaconPeriodMinutes = 20;
|
||||
|
||||
// bluetooth device name
|
||||
|
|
|
@ -16,7 +16,10 @@ void Service::setup(const Config &conf)
|
|||
// config
|
||||
isClient_ = conf.IsClientMode;
|
||||
loraFreq_ = conf.LoraFreq;
|
||||
ownCallsign_ = conf.AprsLogin;
|
||||
ownCallsign_ = AX25::Callsign(conf.AprsLogin);
|
||||
if (!ownCallsign_.IsValid()) {
|
||||
Serial.println("Own callsign is not valid");
|
||||
}
|
||||
|
||||
aprsLogin_ = String("user ") + conf.AprsLogin + String(" pass ") +
|
||||
conf.AprsPass + String(" vers ") + CfgLoraprsVersion;
|
||||
|
|
|
@ -75,7 +75,7 @@ private:
|
|||
bool isClient_;
|
||||
long loraFreq_;
|
||||
|
||||
String ownCallsign_;
|
||||
AX25::Callsign ownCallsign_;
|
||||
|
||||
String aprsHost_;
|
||||
int aprsPort_;
|
||||
|
|
Ładowanie…
Reference in New Issue