kopia lustrzana https://github.com/sh123/esp32_loraprs
Add support for automatic frequency calibration on server side
rodzic
13e7013605
commit
79e712095c
|
@ -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 
|
- consider minimum decode level based on on BW + SF 
|
||||||
- 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
|
||||||

|

|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
19
loraprs.cpp
19
loraprs.cpp
|
@ -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) {
|
||||||
|
|
13
loraprs.h
13
loraprs.h
|
@ -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_;
|
||||||
|
|
Ładowanie…
Reference in New Issue