Add support for automatic frequency calibration on server side

pull/5/head
sh123 2020-06-01 10:43:13 +03:00
rodzic 13e7013605
commit 79e712095c
4 zmienionych plików z 27 dodań i 15 usunięć

Wyświetl plik

@ -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) - 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 - 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 - 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 # Test Results
![alt text](images/setup.png) ![alt text](images/setup.png)

Wyświetl plik

@ -21,12 +21,14 @@
#define LORAPRS_WIFI_KEY "" #define LORAPRS_WIFI_KEY ""
#define LORAPRS_LOGIN "NOCALL-0" #define LORAPRS_LOGIN "NOCALL-0"
#define LORAPRS_PASS "00000" #define LORAPRS_PASS "00000"
#define LORAPRS_FREQ_CORR false
#else #else
#define LORAPRS_BT_NAME "" #define LORAPRS_BT_NAME ""
#define LORAPRS_WIFI_SSID "<mywifi>" #define LORAPRS_WIFI_SSID "<mywifi>"
#define LORAPRS_WIFI_KEY "<key>" #define LORAPRS_WIFI_KEY "<key>"
#define LORAPRS_LOGIN "NOCALL-0" #define LORAPRS_LOGIN "NOCALL-0"
#define LORAPRS_PASS "00000" #define LORAPRS_PASS "00000"
#define LORAPRS_FREQ_CORR false
#endif #endif
LoraPrs loraPrs( LoraPrs loraPrs(
@ -35,7 +37,8 @@ LoraPrs loraPrs(
LORAPRS_WIFI_SSID, LORAPRS_WIFI_SSID,
LORAPRS_WIFI_KEY, LORAPRS_WIFI_KEY,
LORAPRS_LOGIN, LORAPRS_LOGIN,
LORAPRS_PASS); LORAPRS_PASS,
LORAPRS_FREQ_CORR);
auto watchdogLedTimer = timer_create_default(); auto watchdogLedTimer = timer_create_default();

Wyświetl plik

@ -1,9 +1,10 @@
#include "loraprs.h" #include "loraprs.h"
LoraPrs::LoraPrs(int loraFreq, const String & btName, const String & wifiName, LoraPrs::LoraPrs(long loraFreq, const String &btName, const String &wifiName, const String &wifiKey,
const String & wifiKey, const String & aprsLoginCallsign, const String & aprsPass) const String &aprsLoginCallsign, const String &aprsPass, bool autoCorrectFreq)
: serialBt_() : serialBt_()
, loraFreq_(loraFreq) , loraFreq_(loraFreq)
, autoCorrectFreq_(autoCorrectFreq)
, btName_(btName) , btName_(btName)
, wifiName_(wifiName) , wifiName_(wifiName)
, wifiKey_(wifiKey) , wifiKey_(wifiKey)
@ -27,7 +28,7 @@ void LoraPrs::setup()
setupBt(btName_); setupBt(btName_);
} }
void LoraPrs::setupWifi(const String & wifiName, const String & wifiKey) void LoraPrs::setupWifi(const String &wifiName, const String &wifiKey)
{ {
if (wifiName.length() != 0) { if (wifiName.length() != 0) {
Serial.print("WIFI connecting to " + wifiName); Serial.print("WIFI connecting to " + wifiName);
@ -78,7 +79,7 @@ void LoraPrs::setupLora(int loraFreq)
Serial.println("ok"); Serial.println("ok");
} }
void LoraPrs::setupBt(const String & btName) void LoraPrs::setupBt(const String &btName)
{ {
if (btName.length() != 0) { if (btName.length() != 0) {
Serial.print("BT init " + btName + "..."); Serial.print("BT init " + btName + "...");
@ -107,7 +108,7 @@ void LoraPrs::loop()
delay(10); delay(10);
} }
void LoraPrs::onAprsReceived(const String & aprsMessage) void LoraPrs::onAprsReceived(const String &aprsMessage)
{ {
if (WiFi.status() == WL_CONNECTED) { if (WiFi.status() == WL_CONNECTED) {
WiFiClient wifiClient; WiFiClient wifiClient;
@ -149,7 +150,7 @@ String LoraPrs::decodeCall(byte *rxPtr)
return result; 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; byte *rxPtr = rxPayload;
String srcCall, dstCall, rptFirst, rptSecond, result; String srcCall, dstCall, rptFirst, rptSecond, result;
@ -228,6 +229,7 @@ void LoraPrs::onLoraReceived(int packetSize)
float snr = LoRa.packetSnr(); float snr = LoRa.packetSnr();
float rssi = LoRa.packetRssi(); float rssi = LoRa.packetRssi();
long frequencyError = LoRa.packetFrequencyError();
String signalReport = String(" ") + String signalReport = String(" ") +
String("rssi: ") + String("rssi: ") +
@ -237,9 +239,12 @@ void LoraPrs::onLoraReceived(int packetSize)
String(snr) + String(snr) +
String("dB, ") + String("dB, ") +
String("err: ") + String("err: ") +
String(LoRa.packetFrequencyError()) + String(frequencyError) +
String("Hz"); String("Hz");
if (autoCorrectFreq_)
loraFreq_ -= frequencyError;
String aprsMsg = convertAX25ToAprs(rxBuf, rxBufIndex, signalReport); String aprsMsg = convertAX25ToAprs(rxBuf, rxBufIndex, signalReport);
if (aprsMsg.length() != 0) { if (aprsMsg.length() != 0) {

Wyświetl plik

@ -11,16 +11,16 @@
class LoraPrs class LoraPrs
{ {
public: public:
LoraPrs(int loraFreq, const String & btName, const String & wifiName, LoraPrs(long loraFreq, const String &btName, const String &wifiName, const String &wifiKey,
const String & wifiKey, const String & aprsLoginCallsign, const String & aprsPass); const String &aprsLoginCallsign, const String& aprsPass, bool autoCorrectFreq);
void setup(); void setup();
void loop(); void loop();
private: private:
void setupWifi(const String & wifiName, const String & wifiKey); void setupWifi(const String &wifiName, const String &wifiKey);
void setupLora(int loraFreq); void setupLora(int loraFreq);
void setupBt(const String & btName); void setupBt(const String &btName);
void reconnectWifi(); void reconnectWifi();
@ -30,7 +30,7 @@ private:
void kissResetState(); void kissResetState();
String convertAX25ToAprs(byte *rxPayload, int payloadLength, const String & signalReport); String convertAX25ToAprs(byte *rxPayload, int payloadLength, const String &signalReport);
String decodeCall(byte *rxPtr); String decodeCall(byte *rxPtr);
private: private:
@ -77,7 +77,8 @@ private:
const String CfgAprsHost = "rotate.aprs2.net"; const String CfgAprsHost = "rotate.aprs2.net";
private: private:
int loraFreq_; long loraFreq_;
bool autoCorrectFreq_;
String btName_; String btName_;
String wifiName_; String wifiName_;
String wifiKey_; String wifiKey_;