From 4d236819351eb1937f567cf11707050214086cf9 Mon Sep 17 00:00:00 2001 From: SQ2CPA Date: Fri, 29 Mar 2024 09:55:25 +0100 Subject: [PATCH 1/5] improvement: migrate from lora.h to radiolib --- platformio.ini | 12 ++++ src/lora_utils.cpp | 165 ++++++++++++++++----------------------------- src/pins_config.h | 33 +++++---- 3 files changed, 86 insertions(+), 124 deletions(-) diff --git a/platformio.ini b/platformio.ini index bc18d67..bd40421 100644 --- a/platformio.ini +++ b/platformio.ini @@ -48,6 +48,7 @@ build_flags = -Werror -Wall -DTTGO_T_LORA32_V2_1 -DHAS_SX127X + -DHAS_SX1278 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 [env:heltec-lora32-v2] @@ -56,6 +57,7 @@ build_flags = -Werror -Wall -DHELTEC_V2 -DHAS_SX127X + -DHAS_SX1278 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 [env:heltec_wifi_lora_32_V3] @@ -65,6 +67,7 @@ build_flags = -Werror -Wall -DHELTEC_V3 -DHAS_SX126X + -DHAS_SX1262 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 [env:ESP32_DIY_LoRa] @@ -73,6 +76,7 @@ build_flags = -Werror -Wall -DESP32_DIY_LoRa -DHAS_SX127X + -DHAS_SX1278 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 [env:ESP32_DIY_1W_LoRa] @@ -81,6 +85,7 @@ build_flags = -Werror -Wall -DESP32_DIY_1W_LoRa -DHAS_SX126X + -DHAS_SX1268 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 [env:ttgo-t-beam-v1_2] @@ -89,6 +94,7 @@ build_flags = -Werror -Wall -DTTGO_T_Beam_V1_2 -DHAS_SX127X + -DHAS_SX1278 -DHAS_AXP2101 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 @@ -98,6 +104,7 @@ build_flags = -Werror -Wall -DTTGO_T_Beam_V1_0 -DHAS_SX127X + -DHAS_SX1278 -DHAS_AXP192 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 @@ -107,6 +114,7 @@ build_flags = -Werror -Wall -DTTGO_T_Beam_V1_0_SX1268 -DHAS_SX126X + -DHAS_SX1268 -DHAS_AXP192 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 @@ -116,6 +124,7 @@ build_flags = -Werror -Wall -DTTGO_T_Beam_V1_2_SX1262 -DHAS_SX126X + -DHAS_SX1262 -DHAS_AXP2101 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 @@ -125,6 +134,7 @@ build_flags = -Werror -Wall -DOE5HWN_MeshCom -DHAS_SX126X + -DHAS_SX1268 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 [env:heltec_wireless_stick] @@ -134,6 +144,7 @@ build_flags = -Werror -Wall -DHELTEC_WS -DHAS_SX126X + -DHAS_SX1262 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 [env:heltec_ht-ct62] @@ -143,4 +154,5 @@ build_flags = -Werror -Wall -DHELTEC_HTCT62 -DHAS_SX126X + -DHAS_SX1262 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 \ No newline at end of file diff --git a/src/lora_utils.cpp b/src/lora_utils.cpp index 8849cf5..16bd1d8 100644 --- a/src/lora_utils.cpp +++ b/src/lora_utils.cpp @@ -1,5 +1,4 @@ #include -#include #include #include "configuration.h" #include "aprs_is_utils.h" @@ -10,107 +9,85 @@ extern Configuration Config; -#if defined(HELTEC_V3) || defined(HELTEC_WS) || defined(TTGO_T_Beam_V1_2_SX1262) || defined(HELTEC_HTCT62) +bool transmissionFlag = true; +bool ignorePacket = false; +bool operationDone = true; + +#ifdef HAS_SX1262 SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); -bool transmissionFlag = true; -bool enableInterrupt = true; #endif -#if defined(ESP32_DIY_1W_LoRa) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(OE5HWN_MeshCom) + +#ifdef HAS_SX1268 SX1268 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); -bool transmissionFlag = true; -bool enableInterrupt = true; +#endif + +#ifdef HAS_SX1278 +SX1278 radio = new Module(RADIO_CS_PIN, RADIO_BUSY_PIN, RADIO_RST_PIN); #endif int rssi, freqError; float snr; - namespace LoRa_Utils { void setFlag(void) { -#ifdef HAS_SX126X - transmissionFlag = true; -#endif + operationDone = true; } void setup() { -#ifdef HAS_SX127X - SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS); - LoRa.setPins(LORA_CS, LORA_RST, LORA_IRQ); - long freq = Config.loramodule.rxFreq; - if (!LoRa.begin(freq)) { - Serial.println("Starting LoRa failed!"); - show_display("ERROR", "Starting LoRa failed!"); - while (true) { - delay(1000); - } - } - LoRa.setSpreadingFactor(Config.loramodule.spreadingFactor); - LoRa.setSignalBandwidth(Config.loramodule.signalBandwidth); - LoRa.setCodingRate4(Config.loramodule.codingRate4); - LoRa.enableCrc(); - LoRa.setTxPower(Config.loramodule.power); - Serial.print("init : LoRa Module ... done!"); -#endif -#ifdef HAS_SX126X SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); float freq = (float)Config.loramodule.rxFreq / 1000000; int state = radio.begin(freq); if (state == RADIOLIB_ERR_NONE) { - Serial.print("Initializing SX126X LoRa Module"); - } - else { - Serial.println("Starting LoRa failed!"); + Utils::println("Initializing LoRa Module"); + } else { + Utils::println("Starting LoRa failed!"); while (true); } + #ifdef HAS_SX127X + radio.setDio0Action(setFlag, RISING); + #endif + #ifdef HAS_SX126X if (!Config.lowPowerMode) { radio.setDio1Action(setFlag); } else { radio.setDIOMapping(1, RADIOLIB_SX126X_IRQ_RX_DONE); } + #endif radio.setSpreadingFactor(Config.loramodule.spreadingFactor); float signalBandwidth = Config.loramodule.signalBandwidth/1000; radio.setBandwidth(signalBandwidth); radio.setCodingRate(Config.loramodule.codingRate4); radio.setCRC(true); -#if defined(ESP32_DIY_1W_LoRa) + + #if defined(ESP32_DIY_1W_LoRa) radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN); -#endif -#if defined(HELTEC_V3) || defined(HELTEC_WS) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262) + #endif + + #if defined(HAS_SX127X) || ESP32_DIY_1W_LoRa + state = radio.setOutputPower(Config.loramodule.power); // max value 20dB for 400M30S as it has Low Noise Amp + #endif + #if defined(HELTEC_V3) || defined(HELTEC_WS) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262) state = radio.setOutputPower(Config.loramodule.power + 2); // values available: 10, 17, 22 --> if 20 in tracker_conf.json it will be updated to 22. -#endif -#ifdef ESP32_DIY_1W_LoRa_GPS - state = radio.setOutputPower(Config.loramodule.power); // max value 20 (when 20dB in setup 30dB in output as 400M30S has Low Noise Amp) -#endif + #endif if (state == RADIOLIB_ERR_NONE) { - Serial.println("init : LoRa Module ... done!"); + Utils::println("init : LoRa Module ... done!"); } else { - Serial.println("Starting LoRa failed!"); + Utils::println("Starting LoRa failed!"); while (true); } -#endif } void changeFreqTx() { delay(500); -#ifdef HAS_SX127X - LoRa.setFrequency(Config.loramodule.txFreq); -#endif -#ifdef HAS_SX126X float freq = (float)Config.loramodule.txFreq / 1000000; radio.setFrequency(freq); -#endif } void changeFreqRx() { delay(500); -#ifdef HAS_SX127X - LoRa.setFrequency(Config.loramodule.rxFreq); -#endif -#ifdef HAS_SX126X float freq = (float)Config.loramodule.rxFreq / 1000000; radio.setFrequency(freq); -#endif } void sendNewPacket(const String& typeOfMessage, const String& newPacket) { @@ -123,19 +100,6 @@ namespace LoRa_Utils { #ifdef HAS_INTERNAL_LED digitalWrite(internalLedPin, HIGH); #endif -#ifdef HAS_SX127X - LoRa.beginPacket(); - LoRa.write('<'); - if (typeOfMessage == "APRS") { - LoRa.write(0xFF); - } else if (typeOfMessage == "LoRa") { - LoRa.write(0xF8); - } - LoRa.write(0x01); - LoRa.write((const uint8_t*)newPacket.c_str(), newPacket.length()); - LoRa.endPacket(); -#endif -#ifdef HAS_SX126X int state = radio.transmit("\x3c\xff\x01" + newPacket); if (state == RADIOLIB_ERR_NONE) { if (Config.syslog.active && WiFi.status() == WL_CONNECTED) { @@ -143,22 +107,22 @@ namespace LoRa_Utils { } Utils::print("---> LoRa Packet Tx : "); Utils::println(newPacket); - //Serial.println(F("success!")); } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { - Serial.println(F("too long!")); + Utils::println(F("too long!")); } else if (state == RADIOLIB_ERR_TX_TIMEOUT) { - Serial.println(F("timeout!")); + Utils::println(F("timeout!")); } else { - Serial.print(F("failed, code ")); - Serial.println(state); + Utils::print(F("failed, code ")); + Utils::println(String(state)); } -#endif #ifdef HAS_INTERNAL_LED digitalWrite(internalLedPin, LOW); #endif if (Config.loramodule.txFreq != Config.loramodule.rxFreq) { changeFreqRx(); } + + ignorePacket = true; } String generatePacket(String aprsisPacket) { @@ -183,44 +147,23 @@ namespace LoRa_Utils { } void startReceive() { -#ifdef HAS_SX126X radio.startReceive(); -#endif } String receivePacket() { - String loraPacket = ""; -#ifdef HAS_SX127X - int packetSize = LoRa.parsePacket(); - if (packetSize) { - while (LoRa.available()) { - int inChar = LoRa.read(); - loraPacket += (char)inChar; - } - rssi = LoRa.packetRssi(); - snr = LoRa.packetSnr(); - freqError = LoRa.packetFrequencyError(); - if ((loraPacket.indexOf("\0") != -1) || (loraPacket.indexOf("\r") != -1) || (loraPacket.indexOf("\n") != -1)) { - loraPacket = packetSanitization(loraPacket); - } + if(!operationDone && !Config.lowPowerMode) return ""; + + operationDone = false; - if (loraPacket != "") { - Utils::println("<--- LoRa Packet Rx : " + loraPacket); - Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")"); - if (Config.syslog.active && WiFi.status() == WL_CONNECTED && loraPacket != "") { - SYSLOG_Utils::log("Rx", loraPacket, rssi, snr, freqError); - } - } - } - return loraPacket; -#endif -#ifdef HAS_SX126X - if (transmissionFlag || Config.lowPowerMode) { - transmissionFlag = false; + String loraPacket = ""; + + if (transmissionFlag && !Config.lowPowerMode) { radio.startReceive(); + transmissionFlag = false; + } else { int state = radio.readData(loraPacket); if (state == RADIOLIB_ERR_NONE) { - if (loraPacket != "") { + if (loraPacket != "" && !ignorePacket) { rssi = radio.getRSSI(); snr = radio.getSNR(); freqError = radio.getFrequencyError(); @@ -234,17 +177,25 @@ namespace LoRa_Utils { } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { // timeout occurred while waiting for a packet } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { - Serial.println(F("CRC error!")); + Utils::println(F("CRC error!")); if (Config.syslog.active && WiFi.status() == WL_CONNECTED) { SYSLOG_Utils::log("Rx", "RADIOLIB_ERR_CRC_MISMATCH", 0,0,0); } } else { - Serial.print(F("failed, code ")); - Serial.println(state); + Utils::print(F("failed, code ")); + Utils::println(String(state)); + } + + if (ignorePacket) { + Utils::println("<--- LoRa Packet Rx : " + loraPacket); + Utils::println("Received own packet. Ignoring"); + + ignorePacket = false; + return ""; } } + return loraPacket; -#endif } } \ No newline at end of file diff --git a/src/pins_config.h b/src/pins_config.h index 6598146..2d68049 100644 --- a/src/pins_config.h +++ b/src/pins_config.h @@ -9,14 +9,13 @@ // LORA MODULES -#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(ESP32_DIY_LoRa) -#undef LORA_RST -#define LORA_SCK 5 // GPIO5 - SX1276 SCK -#define LORA_MISO 19 // GPIO19 - SX1276 MISO -#define LORA_MOSI 27 // GPIO27 - SX1276 MOSI -#define LORA_CS 18 // GPIO18 - SX1276 CS ---> NSS -#define LORA_RST 14 // GPIO14 - SX1276 RST -#define LORA_IRQ 26 // GPIO26 - SX1276 IRQ ---->DIO0 +#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(ESP32_DIY_LoRa) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_0) +#define RADIO_SCLK_PIN 5 // GPIO5 - SX1276 SCK +#define RADIO_MISO_PIN 19 // GPIO19 - SX1276 MISO +#define RADIO_MOSI_PIN 27 // GPIO27 - SX1276 MOSI +#define RADIO_CS_PIN 18 // GPIO18 - SX1276 CS ---> NSS +#define RADIO_RST_PIN 14 // GPIO14 - SX1276 RST +#define RADIO_BUSY_PIN 26 // GPIO26 - SX1276 IRQ ---->DIO0 #endif #if defined(HELTEC_V3) || defined(HELTEC_WS) @@ -120,15 +119,15 @@ #ifdef ESP32_C3_DIY_LoRa -#define OLED_SDA 8 -#define OLED_SCL 9 -#define OLED_RST 10 -#define LORA_SCK 4 -#define LORA_MISO 5 -#define LORA_MOSI 6 -#define LORA_CS 7 -#define LORA_RST 3 -#define LORA_IRQ 2 +#define OLED_SDA 8 +#define OLED_SCL 9 +#define OLED_RST 10 +#define RADIO_SCLK_PIN 4 +#define RADIO_MISO_PIN 5 +#define RADIO_MOSI_PIN 6 +#define RADIO_CS 7 +#define RADIO_RST_PIN 3 +#define RADIO_IRQ_PIN 2 #endif /* (Same pins for LILYGO LoRa32 and ESP32 Wroom Dev ) From c1cc7c9ab067c41390cc4ef194a631b2dc79a7c2 Mon Sep 17 00:00:00 2001 From: SQ2CPA Date: Thu, 4 Apr 2024 17:55:20 +0200 Subject: [PATCH 2/5] fix: use battery settings for comment in low power mode --- src/LoRa_APRS_iGate.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 2b74776..0b634b8 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -104,8 +104,8 @@ void setup() { DIGI_Utils::loop(packet); // Send received packet to Digi } - if (packet.indexOf(Config.callsign + ":STOP{") != -1) { - Serial.println("Got STOP message, exiting from low power mode"); + if (packet.indexOf(Config.callsign + ":?APRSELP{") != -1) { // Send `?APRSELP` to exit low power + Serial.println("Got ?APRSELP message, exiting from low power mode"); break; }; } @@ -115,7 +115,17 @@ void setup() { if (lastBeacon == 0 || time - lastBeacon >= Config.beacon.interval * 60) { Serial.println("Sending beacon"); - LoRa_Utils::sendNewPacket("APRS", iGateLoRaBeaconPacket + Config.beacon.comment + " Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V"); + String comment = Config.beacon.comment; + + if (Config.sendBatteryVoltage) { + comment += " Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V"; + } + + if (Config.externalVoltageMeasurement) { + comment += " Ext=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V"; + } + + LoRa_Utils::sendNewPacket("APRS", iGateLoRaBeaconPacket + comment); lastBeacon = time; } From c8cde0a404d6df6afc630544195c4b70a0ca5c75 Mon Sep 17 00:00:00 2001 From: SQ2CPA Date: Thu, 4 Apr 2024 17:56:37 +0200 Subject: [PATCH 3/5] fix: use path from config everywhere --- src/aprs_is_utils.cpp | 2 +- src/query_utils.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aprs_is_utils.cpp b/src/aprs_is_utils.cpp index d9a88fb..b8ca022 100644 --- a/src/aprs_is_utils.cpp +++ b/src/aprs_is_utils.cpp @@ -108,7 +108,7 @@ namespace APRS_IS_Utils { for (int i = sender.length(); i < 9; i++) { sender += ' '; } - LoRa_Utils::sendNewPacket("APRS", Config.callsign + ">APLRG1,RFONLY,WIDE1-1::" + sender + ":" + ackMessage); + LoRa_Utils::sendNewPacket("APRS", Config.callsign + ">APLRG1," + Config.beacon.path + "::" + sender + ":" + ackMessage); receivedMessage = packet.substring(packet.indexOf(":") + 1, packet.indexOf("{")); } else { diff --git a/src/query_utils.cpp b/src/query_utils.cpp index 75f1ca6..9b08cbf 100644 --- a/src/query_utils.cpp +++ b/src/query_utils.cpp @@ -41,7 +41,7 @@ namespace QUERY_Utils { if (queryOrigin == "APRSIS") { return Config.callsign + ">APLRG1,TCPIP,qAC::" + station + ":" + answer;// + "\n"; } else { //} if (queryOrigin == "LoRa") { - return Config.callsign + ">APLRG1,RFONLY,WIDE1-1::" + station + ":" + answer; + return Config.callsign + ">APLRG1," + Config.beacon.path + "::" + station + ":" + answer; } } From d16e40726960e907bad0856bde67f2b834afe432 Mon Sep 17 00:00:00 2001 From: SQ2CPA Date: Thu, 4 Apr 2024 17:58:07 +0200 Subject: [PATCH 4/5] improvement: use LoRa WX icon when using BME --- src/gps_utils.cpp | 1 - src/utils.cpp | 5 +++-- src/web_utils.cpp | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gps_utils.cpp b/src/gps_utils.cpp index b35c4fc..38a562b 100644 --- a/src/gps_utils.cpp +++ b/src/gps_utils.cpp @@ -87,7 +87,6 @@ namespace GPS_Utils { } else {} beaconPacket += ":=" + stationLatitude + Config.beacon.overlay + stationLongitude + Config.beacon.symbol; - beaconPacket += Config.beacon.comment; return beaconPacket; } diff --git a/src/utils.cpp b/src/utils.cpp index 5d9ee65..492903a 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -108,10 +108,11 @@ namespace Utils { if (Config.bme.active) { String sensorData = BME_Utils::readDataSensor(); - beaconPacket = iGateBeaconPacket.substring(0,iGateBeaconPacket.indexOf(":=")+20) + "_" + sensorData + iGateBeaconPacket.substring(iGateBeaconPacket.indexOf(":=")+21); + + beaconPacket = iGateBeaconPacket + sensorData + Config.beacon.comment; secondaryBeaconPacket = iGateLoRaBeaconPacket + sensorData + Config.beacon.comment; } else { - beaconPacket = iGateBeaconPacket; + beaconPacket = iGateBeaconPacket + Config.beacon.comment; secondaryBeaconPacket = iGateLoRaBeaconPacket + Config.beacon.comment; } diff --git a/src/web_utils.cpp b/src/web_utils.cpp index 8a719e8..e71a27c 100644 --- a/src/web_utils.cpp +++ b/src/web_utils.cpp @@ -158,6 +158,10 @@ namespace WEB_Utils { Config.lowPowerMode = request->hasParam("other.lowPowerMode", true); Config.lowVoltageCutOff = request->getParam("other.lowVoltageCutOff", true)->value().toDouble(); + if (Config.bme.active) { + Config.beacon.symbol = "_"; + } + Config.writeFile(); AsyncWebServerResponse *response = request->beginResponse(302, "text/html", ""); From 0d64c65aa510893f5171a17863f3b09714971212 Mon Sep 17 00:00:00 2001 From: SQ2CPA Date: Thu, 4 Apr 2024 18:28:38 +0200 Subject: [PATCH 5/5] feat: add build env and date to web ui footer --- data_embed/index.html | 1 + tools/compress.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/data_embed/index.html b/data_embed/index.html index 59a8ec9..838409b 100644 --- a/data_embed/index.html +++ b/data_embed/index.html @@ -1307,6 +1307,7 @@