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)
- 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)

Wyświetl plik

@ -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 "<mywifi>"
#define LORAPRS_WIFI_KEY "<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();

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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_;