From 79e712095cdfc927f5118b36f4ade7adf64c10f4 Mon Sep 17 00:00:00 2001 From: sh123 Date: Mon, 1 Jun 2020 10:43:13 +0300 Subject: [PATCH] Add support for automatic frequency calibration on server side --- README.md | 5 ++++- esp32_loraprs.ino | 5 ++++- loraprs.cpp | 19 ++++++++++++------- loraprs.h | 13 +++++++------ 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 8c9cf0a..c0569fa 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,10 @@ All work was done on ESP32-WROOM with custom made LoRa shield, if your ESP32 boa - consider minimum decode level based on on BW + SF ![alt text](images/bandwidth_vs_sf.jpg) - use 80 MHz ESP32 frequency in Arduino, 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 -- note, that there a is **significant frequency drift** on temperature changes for different modules, you need to use **external TCXO** if you are planning to use modules for narrow bandwidths less than 125 kHz or calibrate clients based on server frequency drift report by changing **LORAPRS_FREQ**, for example, let client and server run for an 30-60 minutes and if server reports err: -1500, then set client frequency to about 1000 kHz less, e.g. instead of 433.775 set it to 433.774, this will give couple of additional dB +- note, that there a is **significant frequency drift** on temperature changes for different modules + - you need to use **external TCXO** if you are planning to use modules for narrow bandwidths less than 125 kHz + - or calibrate clients based on server frequency drift report by changing **LORAPRS_FREQ**, for example, let client and server run for an 30-60 minutes and if server reports err: -1500, then set client frequency to about 1000 kHz less, e.g. instead of 433.775 set it to 433.774, this will give couple of additional dB + - alternatively automatic calibration could be done on server side by enabling automatic frequency correction by setting **LORAPRS_FREQ_CORR** to **true**, might be suitable for experiments where only one client is operating # Test Results ![alt text](images/setup.png) diff --git a/esp32_loraprs.ino b/esp32_loraprs.ino index 7e7209e..bf36e25 100644 --- a/esp32_loraprs.ino +++ b/esp32_loraprs.ino @@ -21,12 +21,14 @@ #define LORAPRS_WIFI_KEY "" #define LORAPRS_LOGIN "NOCALL-0" #define LORAPRS_PASS "00000" +#define LORAPRS_FREQ_CORR false #else #define LORAPRS_BT_NAME "" #define LORAPRS_WIFI_SSID "" #define LORAPRS_WIFI_KEY "" #define LORAPRS_LOGIN "NOCALL-0" #define LORAPRS_PASS "00000" +#define LORAPRS_FREQ_CORR false #endif LoraPrs loraPrs( @@ -35,7 +37,8 @@ LoraPrs loraPrs( LORAPRS_WIFI_SSID, LORAPRS_WIFI_KEY, LORAPRS_LOGIN, - LORAPRS_PASS); + LORAPRS_PASS, + LORAPRS_FREQ_CORR); auto watchdogLedTimer = timer_create_default(); diff --git a/loraprs.cpp b/loraprs.cpp index 72e83d6..08eb8f6 100644 --- a/loraprs.cpp +++ b/loraprs.cpp @@ -1,9 +1,10 @@ #include "loraprs.h" -LoraPrs::LoraPrs(int loraFreq, const String & btName, const String & wifiName, - const String & wifiKey, const String & aprsLoginCallsign, const String & aprsPass) +LoraPrs::LoraPrs(long loraFreq, const String &btName, const String &wifiName, const String &wifiKey, + const String &aprsLoginCallsign, const String &aprsPass, bool autoCorrectFreq) : serialBt_() , loraFreq_(loraFreq) + , autoCorrectFreq_(autoCorrectFreq) , btName_(btName) , wifiName_(wifiName) , wifiKey_(wifiKey) @@ -27,7 +28,7 @@ void LoraPrs::setup() setupBt(btName_); } -void LoraPrs::setupWifi(const String & wifiName, const String & wifiKey) +void LoraPrs::setupWifi(const String &wifiName, const String &wifiKey) { if (wifiName.length() != 0) { Serial.print("WIFI connecting to " + wifiName); @@ -78,7 +79,7 @@ void LoraPrs::setupLora(int loraFreq) Serial.println("ok"); } -void LoraPrs::setupBt(const String & btName) +void LoraPrs::setupBt(const String &btName) { if (btName.length() != 0) { Serial.print("BT init " + btName + "..."); @@ -107,7 +108,7 @@ void LoraPrs::loop() delay(10); } -void LoraPrs::onAprsReceived(const String & aprsMessage) +void LoraPrs::onAprsReceived(const String &aprsMessage) { if (WiFi.status() == WL_CONNECTED) { WiFiClient wifiClient; @@ -149,7 +150,7 @@ String LoraPrs::decodeCall(byte *rxPtr) return result; } -String LoraPrs::convertAX25ToAprs(byte *rxPayload, int payloadLength, const String & signalReport) +String LoraPrs::convertAX25ToAprs(byte *rxPayload, int payloadLength, const String &signalReport) { byte *rxPtr = rxPayload; String srcCall, dstCall, rptFirst, rptSecond, result; @@ -228,6 +229,7 @@ void LoraPrs::onLoraReceived(int packetSize) float snr = LoRa.packetSnr(); float rssi = LoRa.packetRssi(); + long frequencyError = LoRa.packetFrequencyError(); String signalReport = String(" ") + String("rssi: ") + @@ -237,9 +239,12 @@ void LoraPrs::onLoraReceived(int packetSize) String(snr) + String("dB, ") + String("err: ") + - String(LoRa.packetFrequencyError()) + + String(frequencyError) + String("Hz"); + if (autoCorrectFreq_) + loraFreq_ -= frequencyError; + String aprsMsg = convertAX25ToAprs(rxBuf, rxBufIndex, signalReport); if (aprsMsg.length() != 0) { diff --git a/loraprs.h b/loraprs.h index 412a90d..c2744a7 100644 --- a/loraprs.h +++ b/loraprs.h @@ -11,16 +11,16 @@ class LoraPrs { public: - LoraPrs(int loraFreq, const String & btName, const String & wifiName, - const String & wifiKey, const String & aprsLoginCallsign, const String & aprsPass); + LoraPrs(long loraFreq, const String &btName, const String &wifiName, const String &wifiKey, + const String &aprsLoginCallsign, const String& aprsPass, bool autoCorrectFreq); void setup(); void loop(); private: - void setupWifi(const String & wifiName, const String & wifiKey); + void setupWifi(const String &wifiName, const String &wifiKey); void setupLora(int loraFreq); - void setupBt(const String & btName); + void setupBt(const String &btName); void reconnectWifi(); @@ -30,7 +30,7 @@ private: void kissResetState(); - String convertAX25ToAprs(byte *rxPayload, int payloadLength, const String & signalReport); + String convertAX25ToAprs(byte *rxPayload, int payloadLength, const String &signalReport); String decodeCall(byte *rxPtr); private: @@ -77,7 +77,8 @@ private: const String CfgAprsHost = "rotate.aprs2.net"; private: - int loraFreq_; + long loraFreq_; + bool autoCorrectFreq_; String btName_; String wifiName_; String wifiKey_;