kopia lustrzana https://github.com/sh123/esp32_loraprs
Porównaj commity
8 Commity
Autor | SHA1 | Data |
---|---|---|
sh123 | 8a6427f088 | |
sh123 | e78e0e8513 | |
sh123 | cf99eb014d | |
sh123 | b89a13680e | |
sh123 | 0a43429b1c | |
sh123 | 2083f946d9 | |
sh123 | 3e90abd47f | |
sh123 | 127ccbe072 |
|
@ -1,7 +1,7 @@
|
||||||
# ESP32 LoRa APRS Modem
|
# ESP32 LoRa APRS Modem
|
||||||
![Modes of operation](extras/images/diagram.png)
|
![Modes of operation](extras/images/diagram.png)
|
||||||
|
|
||||||
This project is amateur radio ESP32 based LoRa **KISS Bluetooth/BLE/USB/TCPIP** modem + LoRa **APRS-IS RX/TX iGate** server over WiFI + LoRa **APRS digipeater** + **Codec2 DV modem** (with Codec2 Talkie Android application).
|
This project is amateur radio ESP32 based LoRa/FSK **KISS Bluetooth/BLE/USB/TCPIP** modem + LoRa **APRS-IS RX/TX iGate** server over WiFI + LoRa/FSK **APRS digipeater** + **Codec2 DV modem** (with Codec2 Talkie Android application).
|
||||||
|
|
||||||
⚠ **To configure sketch modify default parameters in config.h file.**
|
⚠ **To configure sketch modify default parameters in config.h file.**
|
||||||
|
|
||||||
|
|
|
@ -59,18 +59,30 @@
|
||||||
#define CFG_LORA_USE_CAD true // set to true to utilize carrier detection
|
#define CFG_LORA_USE_CAD true // set to true to utilize carrier detection
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// LoRa protocol default parameters (they need to match between devices!!!)
|
// modulation
|
||||||
|
#define CFG_MOD_TYPE_LORA 0
|
||||||
|
#define CFG_MOD_TYPE_FSK 1
|
||||||
|
#define CFG_MOD_TYPE CFG_MOD_TYPE_LORA
|
||||||
|
|
||||||
|
// general radio parameters
|
||||||
#define CFG_LORA_FREQ_RX 433.775e6 // RX frequency in MHz
|
#define CFG_LORA_FREQ_RX 433.775e6 // RX frequency in MHz
|
||||||
#define CFG_LORA_FREQ_TX 433.775e6 // TX frequency in MHz
|
#define CFG_LORA_FREQ_TX 433.775e6 // TX frequency in MHz
|
||||||
|
#define CFG_LORA_PWR 20 // output power in dBm
|
||||||
|
|
||||||
|
// LoRa protocol default parameters (they need to match between devices!!!)
|
||||||
#define CFG_LORA_BW 125e3 // bandwidth (from 7.8 kHz up to 500 kHz)
|
#define CFG_LORA_BW 125e3 // bandwidth (from 7.8 kHz up to 500 kHz)
|
||||||
#define CFG_LORA_SF 12 // spreading factor (6 - 12), 6 requires implicit header mode
|
#define CFG_LORA_SF 12 // spreading factor (6 - 12), 6 requires implicit header mode
|
||||||
#define CFG_LORA_CR 7 // coding rate (5 - 8)
|
#define CFG_LORA_CR 7 // coding rate (5 - 8)
|
||||||
#define CFG_LORA_CRC 1 // 0 - disabled, 1 - 1 byte, 2 - 2 bytes
|
#define CFG_LORA_CRC 1 // 0 - disabled, 1 - 1 byte, 2 - 2 bytes
|
||||||
#define CFG_LORA_EXPLICIT true // header mode, true - explicit, false - implicit
|
#define CFG_LORA_EXPLICIT true // header mode, true - explicit, false - implicit
|
||||||
#define CFG_LORA_SYNC 0x12 // sync word (0x12 - private used by other trackers, 0x34 - public used by LoRaWAN)
|
#define CFG_LORA_SYNC 0x12 // sync word (0x12 - private used by other trackers, 0x34 - public used by LoRaWAN)
|
||||||
#define CFG_LORA_PWR 20 // output power in dBm
|
|
||||||
#define CFG_LORA_PREAMBLE 8 // preamble length from 6 to 65535
|
#define CFG_LORA_PREAMBLE 8 // preamble length from 6 to 65535
|
||||||
|
|
||||||
|
// fsk modem default parameters (they need to match between devices!!!)
|
||||||
|
#define CFG_FSK_BIT_RATE 4.8 // bit rate in Kbps from 0.6 to 300.0
|
||||||
|
#define CFG_FSK_FREQ_DEV 1.2 // frequency deviation in kHz from 0.6 to 200.0
|
||||||
|
#define CFG_FSK_RX_BW 9.7 // rx bandwidth in kHz !!discrete!! from 4.8 to 467.0
|
||||||
|
|
||||||
// WiFi client and AP options
|
// WiFi client and AP options
|
||||||
#define CFG_WIFI_ENABLE_AP false // run as wifi access point (for CFG_KISS_TCP_IP mode)
|
#define CFG_WIFI_ENABLE_AP false // run as wifi access point (for CFG_KISS_TCP_IP mode)
|
||||||
#define CFG_WIFI_SSID "<ssid>" // connect to SSID or run as this SSID in AP mode
|
#define CFG_WIFI_SSID "<ssid>" // connect to SSID or run as this SSID in AP mode
|
||||||
|
|
|
@ -50,6 +50,7 @@ protected:
|
||||||
None = 0x80
|
None = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const int CfgToSerialDelayMs = 10;
|
||||||
static const int CfgSerialToRigQueueSize = 4096;
|
static const int CfgSerialToRigQueueSize = 4096;
|
||||||
static const int CfgRigToSerialQueueSize = 4096;
|
static const int CfgRigToSerialQueueSize = 4096;
|
||||||
|
|
||||||
|
|
|
@ -11,18 +11,28 @@ struct Config
|
||||||
DebugLogLevel LogLevel; // log level
|
DebugLogLevel LogLevel; // log level
|
||||||
bool IsClientMode; // false - server mode, true - client mode (disables wifi and aprsis)
|
bool IsClientMode; // false - server mode, true - client mode (disables wifi and aprsis)
|
||||||
|
|
||||||
// lora protocol parameters
|
// modulation type
|
||||||
|
int ModType; // 0 - lora, 1 - fsk
|
||||||
|
|
||||||
|
// general radio parameters
|
||||||
long LoraFreqRx; // lora RX frequency, e.g. 433.775e6
|
long LoraFreqRx; // lora RX frequency, e.g. 433.775e6
|
||||||
long LoraFreqTx; // lora TX frequency, e.g. 433.775e6
|
long LoraFreqTx; // lora TX frequency, e.g. 433.775e6
|
||||||
|
int LoraPower; // lora power level in dbm, 20
|
||||||
|
|
||||||
|
// lora protocol parameters
|
||||||
long LoraBw; // lora bandwidth, e.g. 125e3
|
long LoraBw; // lora bandwidth, e.g. 125e3
|
||||||
int LoraSf; // lora spreading factor, e.g. 12
|
int LoraSf; // lora spreading factor, e.g. 12
|
||||||
int LoraCodingRate; // lora coding rate, e.g. 7
|
int LoraCodingRate; // lora coding rate, e.g. 7
|
||||||
int LoraPower; // lora power level in dbm, 20
|
|
||||||
int LoraSync; // lora sync word/packet id, 0x34
|
int LoraSync; // lora sync word/packet id, 0x34
|
||||||
int LoraCrc; // lora crc mode, 0 - disabled, 1 - 1 byte, 2 - 2 bytes
|
int LoraCrc; // lora crc mode, 0 - disabled, 1 - 1 byte, 2 - 2 bytes
|
||||||
bool LoraExplicit; // lora header mode, true - explicit, false - implicit
|
bool LoraExplicit; // lora header mode, true - explicit, false - implicit
|
||||||
int LoraPreamble; // lora preamble length from 6 to 65535
|
int LoraPreamble; // lora preamble length from 6 to 65535
|
||||||
|
|
||||||
|
// fsk modulation parameters
|
||||||
|
float FskBitRate; // fsk bit rate, 0.6 - 300.0 Kbps
|
||||||
|
float FskFreqDev; // fsk frequency deviation 0.6 - 200 kHz
|
||||||
|
float FskRxBw; // fsk rx bandwidth, discrete from 4.8 to 467 kHz
|
||||||
|
|
||||||
// lora hardware pinouts and isr
|
// lora hardware pinouts and isr
|
||||||
byte LoraPinSs; // lora ss pin
|
byte LoraPinSs; // lora ss pin
|
||||||
byte LoraPinRst; // lora rst pin
|
byte LoraPinRst; // lora rst pin
|
||||||
|
|
|
@ -39,9 +39,11 @@ private:
|
||||||
|
|
||||||
void setupWifi(const String &wifiName, const String &wifiKey);
|
void setupWifi(const String &wifiName, const String &wifiKey);
|
||||||
void setupRig(long freq, long bw, int sf, int cr, int pwr, int sync, int crcBytes, bool isExplicit);
|
void setupRig(long freq, long bw, int sf, int cr, int pwr, int sync, int crcBytes, bool isExplicit);
|
||||||
void setFreq(long freq) const;
|
void setupRigFsk(long freq, float bitRate, float freqDev, float rxBw, int pwr);
|
||||||
void setupBt(const String &btName);
|
void setupBt(const String &btName);
|
||||||
|
|
||||||
|
void setFreq(long freq) const;
|
||||||
|
|
||||||
void reconnectWifi() const;
|
void reconnectWifi() const;
|
||||||
bool reconnectAprsis();
|
bool reconnectAprsis();
|
||||||
void attachKissNetworkClient();
|
void attachKissNetworkClient();
|
||||||
|
@ -50,9 +52,14 @@ private:
|
||||||
|
|
||||||
void onRigTaskRxPacket();
|
void onRigTaskRxPacket();
|
||||||
void onRigTaskTxPacket();
|
void onRigTaskTxPacket();
|
||||||
|
void onRigTaskStartRx();
|
||||||
|
void onRigTaskStartTx();
|
||||||
static void rigTask(void *self);
|
static void rigTask(void *self);
|
||||||
static ICACHE_RAM_ATTR void onRigIsrRxPacket();
|
static ICACHE_RAM_ATTR void onRigIsrRxPacket();
|
||||||
|
|
||||||
|
void startRx();
|
||||||
|
static bool startRxTimer(void *param);
|
||||||
|
|
||||||
void onAprsisDataAvailable();
|
void onAprsisDataAvailable();
|
||||||
|
|
||||||
void sendSignalReportEvent(int rssi, float snr);
|
void sendSignalReportEvent(int rssi, float snr);
|
||||||
|
@ -104,13 +111,18 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SetHardware {
|
struct SetHardware {
|
||||||
uint32_t freq;
|
uint32_t freqRx;
|
||||||
|
uint32_t freqTx;
|
||||||
|
uint8_t modType;
|
||||||
|
int16_t pwr;
|
||||||
uint32_t bw;
|
uint32_t bw;
|
||||||
uint16_t sf;
|
uint16_t sf;
|
||||||
uint16_t cr;
|
uint16_t cr;
|
||||||
uint16_t pwr;
|
|
||||||
uint16_t sync;
|
uint16_t sync;
|
||||||
uint8_t crc;
|
uint8_t crc;
|
||||||
|
uint32_t fskBitRate;
|
||||||
|
uint32_t fskFreqDev;
|
||||||
|
uint32_t fskRxBw;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct SignalReport {
|
struct SignalReport {
|
||||||
|
@ -123,7 +135,7 @@ private:
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const String CfgLoraprsVersion = "LoRAPRS 1.0.13";
|
const String CfgLoraprsVersion = "LoRAPRS 1.0.15";
|
||||||
|
|
||||||
// processor config
|
// processor config
|
||||||
const int CfgConnRetryMs = 500; // connection retry delay, e.g. wifi
|
const int CfgConnRetryMs = 500; // connection retry delay, e.g. wifi
|
||||||
|
@ -143,7 +155,9 @@ private:
|
||||||
// radio task commands
|
// radio task commands
|
||||||
enum RadioTaskBits {
|
enum RadioTaskBits {
|
||||||
Receive = 0x01,
|
Receive = 0x01,
|
||||||
Transmit = 0x02
|
Transmit = 0x02,
|
||||||
|
StartReceive = 0x04,
|
||||||
|
StartTransmit = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -162,6 +176,7 @@ private:
|
||||||
|
|
||||||
// peripherals, radio
|
// peripherals, radio
|
||||||
static TaskHandle_t rigTaskHandle_;
|
static TaskHandle_t rigTaskHandle_;
|
||||||
|
Timer<1> startRxTimer_;
|
||||||
static volatile bool rigIsRxActive_;
|
static volatile bool rigIsRxActive_;
|
||||||
static volatile bool rigIsRxIsrEnabled_;
|
static volatile bool rigIsRxIsrEnabled_;
|
||||||
bool rigIsImplicitMode_;
|
bool rigIsImplicitMode_;
|
||||||
|
|
|
@ -134,7 +134,7 @@ bool Processor::processRigToSerial()
|
||||||
onRigPacket(&buf, rxPacketSize);
|
onRigPacket(&buf, rxPacketSize);
|
||||||
|
|
||||||
isProcessed = true;
|
isProcessed = true;
|
||||||
yield();
|
if (!rigToSerialQueueIndex_.isEmpty()) delay(CfgToSerialDelayMs);
|
||||||
}
|
}
|
||||||
return isProcessed;
|
return isProcessed;
|
||||||
}
|
}
|
||||||
|
@ -280,11 +280,19 @@ bool Processor::receiveByteKiss(byte rxByte)
|
||||||
break;
|
break;
|
||||||
case State::Escape:
|
case State::Escape:
|
||||||
if (rxByte == Marker::Tfend) {
|
if (rxByte == Marker::Tfend) {
|
||||||
onRigTx((byte)Marker::Fend);
|
if (dataType_ == DataType::Raw) {
|
||||||
|
onRigTx((byte)Marker::Fend);
|
||||||
|
} else if (dataType_ == DataType::Control) {
|
||||||
|
cmdBuffer_.push_back((byte)Marker::Fend);
|
||||||
|
}
|
||||||
state_ = State::GetData;
|
state_ = State::GetData;
|
||||||
}
|
}
|
||||||
else if (rxByte == Marker::Tfesc) {
|
else if (rxByte == Marker::Tfesc) {
|
||||||
onRigTx((byte)Marker::Fesc);
|
if (dataType_ == DataType::Raw) {
|
||||||
|
onRigTx((byte)Marker::Fesc);
|
||||||
|
} else if (dataType_ == DataType::Control) {
|
||||||
|
cmdBuffer_.push_back((byte)Marker::Fesc);
|
||||||
|
}
|
||||||
state_ = State::GetData;
|
state_ = State::GetData;
|
||||||
}
|
}
|
||||||
else if (rxByte != Marker::Fend) {
|
else if (rxByte != Marker::Fend) {
|
||||||
|
|
|
@ -61,9 +61,14 @@ void Service::setup(const Config &conf)
|
||||||
}
|
}
|
||||||
aprsLoginCommand_ += String("\n");
|
aprsLoginCommand_ += String("\n");
|
||||||
|
|
||||||
// peripherals, LoRa
|
// radio module, FSK/LoRa
|
||||||
setupRig(config_.LoraFreqRx, config_.LoraBw, config_.LoraSf,
|
if (config_.ModType == CFG_MOD_TYPE_FSK) {
|
||||||
config_.LoraCodingRate, config_.LoraPower, config_.LoraSync, config_.LoraCrc, config_.LoraExplicit);
|
setupRigFsk(config_.LoraFreqRx, config_.FskBitRate, config_.FskFreqDev, config_.FskRxBw, config_.LoraPower);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setupRig(config_.LoraFreqRx, config_.LoraBw, config_.LoraSf,
|
||||||
|
config_.LoraCodingRate, config_.LoraPower, config_.LoraSync, config_.LoraCrc, config_.LoraExplicit);
|
||||||
|
}
|
||||||
|
|
||||||
// start radio task
|
// start radio task
|
||||||
xTaskCreate(rigTask, "rigTask", 4096, this, 5, &rigTaskHandle_);
|
xTaskCreate(rigTask, "rigTask", 4096, this, 5, &rigTaskHandle_);
|
||||||
|
@ -251,7 +256,7 @@ void Service::setupRig(long loraFreq, long bw, int sf, int cr, int pwr, int sync
|
||||||
#pragma message("Using SX127X")
|
#pragma message("Using SX127X")
|
||||||
LOG_INFO("Using SX127X module");
|
LOG_INFO("Using SX127X module");
|
||||||
if (isIsrInstalled_) rig_->clearDio0Action();
|
if (isIsrInstalled_) rig_->clearDio0Action();
|
||||||
rig_->setDio0Action(onRigIsrRxPacket);
|
rig_->setDio0Action(onRigIsrRxPacket, RISING);
|
||||||
isIsrInstalled_ = true;
|
isIsrInstalled_ = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -269,6 +274,43 @@ void Service::setupRig(long loraFreq, long bw, int sf, int cr, int pwr, int sync
|
||||||
LOG_INFO("LoRa initialized");
|
LOG_INFO("LoRa initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Service::setupRigFsk(long freq, float bitRate, float freqDev, float rxBw, int pwr)
|
||||||
|
{
|
||||||
|
LOG_INFO("Initializing FSK");
|
||||||
|
LOG_INFO("Frequency:", freq, "Hz");
|
||||||
|
LOG_INFO("Bit rate:", bitRate, "kbps");
|
||||||
|
LOG_INFO("Deviation:", freqDev, "kHz");
|
||||||
|
LOG_INFO("Bandwidth:", rxBw, "kHz");
|
||||||
|
LOG_INFO("Power:", pwr, "dBm");
|
||||||
|
rig_ = std::make_shared<MODULE_NAME>(new Module(config_.LoraPinSs, config_.LoraPinA, config_.LoraPinRst, config_.LoraPinB));
|
||||||
|
int state = rig_->beginFSK((float)freq / 1e6, bitRate, freqDev, rxBw, pwr);
|
||||||
|
if (state != RADIOLIB_ERR_NONE) {
|
||||||
|
LOG_ERROR("Radio start error:", state);
|
||||||
|
}
|
||||||
|
rig_->disableAddressFiltering();
|
||||||
|
#ifdef USE_SX126X
|
||||||
|
#pragma message("Using SX126X")
|
||||||
|
LOG_INFO("Using SX126X module");
|
||||||
|
rig_->setRfSwitchPins(config_.LoraPinSwitchRx, config_.LoraPinSwitchTx);
|
||||||
|
if (isIsrInstalled_) rig_->clearDio1Action();
|
||||||
|
rig_->setDio1Action(onRigIsrRxPacket);
|
||||||
|
isIsrInstalled_ = true;
|
||||||
|
#else
|
||||||
|
#pragma message("Using SX127X")
|
||||||
|
LOG_INFO("Using SX127X module");
|
||||||
|
if (isIsrInstalled_) rig_->clearDio0Action();
|
||||||
|
rig_->setDio0Action(onRigIsrRxPacket, RISING);
|
||||||
|
isIsrInstalled_ = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
state = rig_->startReceive();
|
||||||
|
if (state != RADIOLIB_ERR_NONE) {
|
||||||
|
LOG_ERROR("Receive start error:", state);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO("FSK initialized");
|
||||||
|
}
|
||||||
|
|
||||||
void Service::setupBt(const String &btName)
|
void Service::setupBt(const String &btName)
|
||||||
{
|
{
|
||||||
String btType = config_.BtEnableBle ? "BLE" : "BT";
|
String btType = config_.BtEnableBle ? "BLE" : "BT";
|
||||||
|
@ -325,6 +367,7 @@ void Service::loop()
|
||||||
if (config_.TlmEnable) {
|
if (config_.TlmEnable) {
|
||||||
telemetryTimer_.tick();
|
telemetryTimer_.tick();
|
||||||
}
|
}
|
||||||
|
startRxTimer_.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
ICACHE_RAM_ATTR void Service::onRigIsrRxPacket() {
|
ICACHE_RAM_ATTR void Service::onRigIsrRxPacket() {
|
||||||
|
@ -346,9 +389,30 @@ void Service::rigTask(void *self) {
|
||||||
else if (commandBits & RadioTaskBits::Transmit) {
|
else if (commandBits & RadioTaskBits::Transmit) {
|
||||||
static_cast<Service*>(self)->onRigTaskTxPacket();
|
static_cast<Service*>(self)->onRigTaskTxPacket();
|
||||||
}
|
}
|
||||||
|
if (commandBits & RadioTaskBits::StartReceive) {
|
||||||
|
static_cast<Service*>(self)->onRigTaskStartRx();
|
||||||
|
}
|
||||||
|
else if (commandBits & RadioTaskBits::StartTransmit) {
|
||||||
|
static_cast<Service*>(self)->onRigTaskStartTx();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Service::onRigTaskStartRx() {
|
||||||
|
LOG_TRACE("onRigTaskStartRx");
|
||||||
|
if (config_.PttEnable) {
|
||||||
|
digitalWrite(config_.PttPin, LOW);
|
||||||
|
}
|
||||||
|
if (isHalfDuplex()) {
|
||||||
|
setFreq(config_.LoraFreqRx);
|
||||||
|
}
|
||||||
|
int state = rig_->startReceive();
|
||||||
|
if (state != RADIOLIB_ERR_NONE) {
|
||||||
|
LOG_ERROR("Start receive error: ", state);
|
||||||
|
}
|
||||||
|
rigIsRxIsrEnabled_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Service::onRigTaskRxPacket() {
|
void Service::onRigTaskRxPacket() {
|
||||||
int packetSize = rig_->getPacketLength();
|
int packetSize = rig_->getPacketLength();
|
||||||
LOG_TRACE("onRigTaskRxPacket", packetSize);
|
LOG_TRACE("onRigTaskRxPacket", packetSize);
|
||||||
|
@ -369,15 +433,21 @@ void Service::onRigTaskRxPacket() {
|
||||||
rigIsRxActive_ = false;
|
rigIsRxActive_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Service::onRigTaskTxPacket() {
|
void Service::onRigTaskStartTx() {
|
||||||
rigIsRxIsrEnabled_ = false;
|
LOG_TRACE("onRigTaskStartTx");
|
||||||
if (isHalfDuplex()) {
|
if (rigIsRxIsrEnabled_) {
|
||||||
setFreq(config_.LoraFreqTx);
|
rigIsRxIsrEnabled_ = false;
|
||||||
}
|
if (isHalfDuplex()) {
|
||||||
if (config_.PttEnable) {
|
setFreq(config_.LoraFreqTx);
|
||||||
digitalWrite(config_.PttPin, HIGH);
|
}
|
||||||
|
if (config_.PttEnable) {
|
||||||
|
digitalWrite(config_.PttPin, HIGH);
|
||||||
|
}
|
||||||
delay(config_.PttTxDelayMs);
|
delay(config_.PttTxDelayMs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Service::onRigTaskTxPacket() {
|
||||||
while (rigTxQueueIndex_.size() > 0) {
|
while (rigTxQueueIndex_.size() > 0) {
|
||||||
int txPacketSize = rigTxQueueIndex_.shift();
|
int txPacketSize = rigTxQueueIndex_.shift();
|
||||||
LOG_TRACE("onRigTaskTxPacket", txPacketSize);
|
LOG_TRACE("onRigTaskTxPacket", txPacketSize);
|
||||||
|
@ -393,18 +463,7 @@ void Service::onRigTaskTxPacket() {
|
||||||
}
|
}
|
||||||
vTaskDelay(1);
|
vTaskDelay(1);
|
||||||
}
|
}
|
||||||
if (config_.PttEnable) {
|
startRxTimer_.in(config_.PttTxTailMs, &startRxTimer);
|
||||||
delay(config_.PttTxTailMs);
|
|
||||||
digitalWrite(config_.PttPin, LOW);
|
|
||||||
}
|
|
||||||
if (isHalfDuplex()) {
|
|
||||||
setFreq(config_.LoraFreqRx);
|
|
||||||
}
|
|
||||||
int state = rig_->startReceive();
|
|
||||||
if (state != RADIOLIB_ERR_NONE) {
|
|
||||||
LOG_ERROR("Start receive error: ", state);
|
|
||||||
}
|
|
||||||
rigIsRxIsrEnabled_ = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Service::sendPeriodicBeacon()
|
void Service::sendPeriodicBeacon()
|
||||||
|
@ -486,6 +545,16 @@ bool Service::sendModemTelemetryTimer(void *param)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Service::startRxTimer(void *param)
|
||||||
|
{
|
||||||
|
static_cast<Service*>(param)->startRx();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Service::startRx() {
|
||||||
|
xTaskNotify(rigTaskHandle_, RadioTaskBits::StartReceive, eSetBits);
|
||||||
|
}
|
||||||
|
|
||||||
void Service::sendModemTelemetry()
|
void Service::sendModemTelemetry()
|
||||||
{
|
{
|
||||||
float batVoltage = 2 * analogRead(config_.TlmBatMonPin) * (3.3 / 4096.0) + config_.TlmBatMonCal;
|
float batVoltage = 2 * analogRead(config_.TlmBatMonPin) * (3.3 / 4096.0) + config_.TlmBatMonCal;
|
||||||
|
@ -549,10 +618,6 @@ void Service::performFrequencyCorrection() {
|
||||||
|
|
||||||
void Service::setFreq(long loraFreq) const {
|
void Service::setFreq(long loraFreq) const {
|
||||||
rig_->setFrequency((float)loraFreq / 1e6);
|
rig_->setFrequency((float)loraFreq / 1e6);
|
||||||
int state = rig_->startReceive();
|
|
||||||
if (state != RADIOLIB_ERR_NONE) {
|
|
||||||
LOG_ERROR("Start receive error:", state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Service::processIncomingRawPacketAsServer(const byte *packet, int packetLength) {
|
void Service::processIncomingRawPacketAsServer(const byte *packet, int packetLength) {
|
||||||
|
@ -608,6 +673,8 @@ void Service::processIncomingRawPacketAsServer(const byte *packet, int packetLen
|
||||||
bool Service::onRigTxBegin()
|
bool Service::onRigTxBegin()
|
||||||
{
|
{
|
||||||
LOG_TRACE("onRigTxBegin");
|
LOG_TRACE("onRigTxBegin");
|
||||||
|
startRxTimer_.cancel();
|
||||||
|
xTaskNotify(rigTaskHandle_, RadioTaskBits::StartTransmit, eSetBits);
|
||||||
rigCurrentTxPacketSize_ = 0;
|
rigCurrentTxPacketSize_ = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -739,21 +806,29 @@ void Service::onRadioControlCommand(const std::vector<byte> &rawCommand) {
|
||||||
if (config_.KissEnableExtensions && rawCommand.size() == sizeof(SetHardware)) {
|
if (config_.KissEnableExtensions && rawCommand.size() == sizeof(SetHardware)) {
|
||||||
LOG_INFO("Setting new radio parameters");
|
LOG_INFO("Setting new radio parameters");
|
||||||
const struct SetHardware * setHardware = reinterpret_cast<const struct SetHardware*>(rawCommand.data());
|
const struct SetHardware * setHardware = reinterpret_cast<const struct SetHardware*>(rawCommand.data());
|
||||||
|
|
||||||
// TODO, add support for split set hardware
|
config_.LoraFreqRx = be32toh(setHardware->freqRx);
|
||||||
config_.LoraFreqRx = be32toh(setHardware->freq);
|
config_.LoraFreqTx = be32toh(setHardware->freqTx);
|
||||||
config_.LoraFreqTx = be32toh(setHardware->freq);
|
config_.ModType = setHardware->modType;
|
||||||
config_.LoraBw = be32toh(setHardware->bw);
|
config_.LoraBw = be32toh(setHardware->bw);
|
||||||
config_.LoraSf = be16toh(setHardware->sf);
|
config_.LoraSf = be16toh(setHardware->sf);
|
||||||
config_.LoraCodingRate = be16toh(setHardware->cr);
|
config_.LoraCodingRate = be16toh(setHardware->cr);
|
||||||
config_.LoraPower = be16toh(setHardware->pwr);
|
config_.LoraPower = (int16_t)be16toh(setHardware->pwr);
|
||||||
config_.LoraSync = be16toh(setHardware->sync);
|
config_.LoraSync = be16toh(setHardware->sync);
|
||||||
|
config_.FskBitRate = (float)be32toh(setHardware->fskBitRate) / 1e3;
|
||||||
|
config_.FskFreqDev = (float)be32toh(setHardware->fskFreqDev) / 1e3;
|
||||||
|
config_.FskRxBw = (float)be32toh(setHardware->fskRxBw) / 1e3;
|
||||||
int crcType = setHardware->crc ? config_.LoraCrc : 0;
|
int crcType = setHardware->crc ? config_.LoraCrc : 0;
|
||||||
|
|
||||||
setupRig(config_.LoraFreqRx, config_.LoraBw, config_.LoraSf,
|
if (config_.ModType == CFG_MOD_TYPE_FSK) {
|
||||||
config_.LoraCodingRate, config_.LoraPower, config_.LoraSync, crcType, config_.LoraExplicit);
|
setupRigFsk(config_.LoraFreqRx, config_.FskBitRate, config_.FskFreqDev, config_.FskRxBw, config_.LoraPower);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setupRig(config_.LoraFreqRx, config_.LoraBw, config_.LoraSf,
|
||||||
|
config_.LoraCodingRate, config_.LoraPower, config_.LoraSync, crcType, config_.LoraExplicit);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Radio control command of wrong size");
|
LOG_ERROR("Radio control command of wrong size", rawCommand.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
src/main.cpp
16
src/main.cpp
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include "loraprs_service.h"
|
#include "loraprs_service.h"
|
||||||
|
|
||||||
const int CfgPollDelayMs = 20; // main loop delay
|
const int CfgPollDelayMs = 10; // main loop delay
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize config from config.h options.
|
* Initialize config from config.h options.
|
||||||
|
@ -31,18 +31,28 @@ void initializeConfig(LoraPrs::Config &cfg) {
|
||||||
// client/server mode switch
|
// client/server mode switch
|
||||||
cfg.IsClientMode = CFG_IS_CLIENT_MODE;
|
cfg.IsClientMode = CFG_IS_CLIENT_MODE;
|
||||||
|
|
||||||
// lora parameters, must match on devices
|
// modulation
|
||||||
|
cfg.ModType = CFG_MOD_TYPE;
|
||||||
|
|
||||||
|
// generic module parameters
|
||||||
cfg.LoraFreqRx = CFG_LORA_FREQ_RX;
|
cfg.LoraFreqRx = CFG_LORA_FREQ_RX;
|
||||||
cfg.LoraFreqTx = CFG_LORA_FREQ_TX;
|
cfg.LoraFreqTx = CFG_LORA_FREQ_TX;
|
||||||
|
cfg.LoraPower = CFG_LORA_PWR;
|
||||||
|
|
||||||
|
// lora parameters, must match on devices
|
||||||
cfg.LoraBw = CFG_LORA_BW;
|
cfg.LoraBw = CFG_LORA_BW;
|
||||||
cfg.LoraSf = CFG_LORA_SF;
|
cfg.LoraSf = CFG_LORA_SF;
|
||||||
cfg.LoraCodingRate = CFG_LORA_CR;
|
cfg.LoraCodingRate = CFG_LORA_CR;
|
||||||
cfg.LoraSync = CFG_LORA_SYNC;
|
cfg.LoraSync = CFG_LORA_SYNC;
|
||||||
cfg.LoraCrc = CFG_LORA_CRC; // set to 0 to disable
|
cfg.LoraCrc = CFG_LORA_CRC; // set to 0 to disable
|
||||||
cfg.LoraExplicit = CFG_LORA_EXPLICIT;
|
cfg.LoraExplicit = CFG_LORA_EXPLICIT;
|
||||||
cfg.LoraPower = CFG_LORA_PWR;
|
|
||||||
cfg.LoraPreamble = CFG_LORA_PREAMBLE;
|
cfg.LoraPreamble = CFG_LORA_PREAMBLE;
|
||||||
|
|
||||||
|
// fsk parameters
|
||||||
|
cfg.FskBitRate = CFG_FSK_BIT_RATE;
|
||||||
|
cfg.FskFreqDev = CFG_FSK_FREQ_DEV;
|
||||||
|
cfg.FskRxBw = CFG_FSK_RX_BW;
|
||||||
|
|
||||||
// lora pinouts
|
// lora pinouts
|
||||||
cfg.LoraPinSs = CFG_LORA_PIN_SS;
|
cfg.LoraPinSs = CFG_LORA_PIN_SS;
|
||||||
cfg.LoraPinRst = CFG_LORA_PIN_RST;
|
cfg.LoraPinRst = CFG_LORA_PIN_RST;
|
||||||
|
|
Ładowanie…
Reference in New Issue