Compare commits
124 Commits
sleeperSys
...
decodingFi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff8c7581fa | ||
|
|
449a8557d2 | ||
|
|
4419c98920 | ||
|
|
45bf90817b | ||
|
|
ef30a1bf58 | ||
|
|
9a705d3dfa | ||
|
|
63f74396d2 | ||
|
|
400b77c2d3 | ||
|
|
31daddf917 | ||
|
|
529a44018f | ||
|
|
5ba9c5b382 | ||
|
|
c7a0e3773b | ||
|
|
a5f9e5b844 | ||
|
|
24f407d51c | ||
|
|
2c6665b557 | ||
|
|
38f52564f1 | ||
|
|
49e92c622f | ||
|
|
5370850ae1 | ||
|
|
984e9f9561 | ||
|
|
f60252ef94 | ||
|
|
63257d6329 | ||
|
|
18929ad379 | ||
|
|
cda901142d | ||
|
|
8008143267 | ||
|
|
3416e21a8c | ||
|
|
5882b54c62 | ||
|
|
6a4c0ef01a | ||
|
|
0bd3201ef7 | ||
|
|
b5d9103ea5 | ||
|
|
20a5029da8 | ||
|
|
b3cc8af180 | ||
|
|
ca16761f68 | ||
|
|
e593b2c670 | ||
|
|
08a7e0aac1 | ||
|
|
9b258c42ab | ||
|
|
8712122d33 | ||
|
|
9e34684627 | ||
|
|
e4aa52241d | ||
|
|
c840ef01fa | ||
|
|
98f85725f8 | ||
|
|
10bde884b1 | ||
|
|
546e4f63a4 | ||
|
|
87f2ec2b7b | ||
|
|
c9c7e24aae | ||
|
|
b86133223d | ||
|
|
880a41bfd8 | ||
|
|
d610b3a90f | ||
|
|
23a33ed27c | ||
|
|
72ef827900 | ||
|
|
b756f97f55 | ||
|
|
2625e7b91d | ||
|
|
75337d6c29 | ||
|
|
a618383617 | ||
|
|
8add599838 | ||
|
|
83ec2265c6 | ||
|
|
bec4f4f473 | ||
|
|
87a67cd2c9 | ||
|
|
4e48b2d02d | ||
|
|
607277bfe9 | ||
|
|
c2f8596667 | ||
|
|
ba7ff2a2d9 | ||
|
|
b44eb1028d | ||
|
|
d7602268f2 | ||
|
|
2f6f9be28e | ||
|
|
92572245cd | ||
|
|
152217e71c | ||
|
|
d334164b6f | ||
|
|
61409ce683 | ||
|
|
742a6b6477 | ||
|
|
dd2fce3908 | ||
|
|
90b29b66d5 | ||
|
|
2a86cdb0d8 | ||
|
|
1abaa299e0 | ||
|
|
9cbd7c22fd | ||
|
|
e15e6def91 | ||
|
|
33c8be4f48 | ||
|
|
c2a7c26d78 | ||
|
|
387e8a988a | ||
|
|
48b075a554 | ||
|
|
7e76e43817 | ||
|
|
9b7b4e1838 | ||
|
|
5b9d56843b | ||
|
|
30eb1023dc | ||
|
|
1ba86af61b | ||
|
|
1d475bc8a2 | ||
|
|
70f9a6fa04 | ||
|
|
6747511850 | ||
|
|
96a4394e89 | ||
|
|
4e009bc14c | ||
|
|
4c11c66a1c | ||
|
|
a89181b5df | ||
|
|
9a94a193f9 | ||
|
|
9c7f6c7934 | ||
|
|
53e8941262 | ||
|
|
60a148d362 | ||
|
|
36cd1578cc | ||
|
|
c3036f290f | ||
|
|
8eb4ef1dc2 | ||
|
|
d5930380b4 | ||
|
|
e42f4b59ed | ||
|
|
2697f2a5f2 | ||
|
|
36c970aed9 | ||
|
|
10e1581bc2 | ||
|
|
bc57d1609a | ||
|
|
37380c6b9d | ||
|
|
855c84c079 | ||
|
|
bb4df08f06 | ||
|
|
6d0e98f4a2 | ||
|
|
c5dcc4c7ab | ||
|
|
5c5c940d71 | ||
|
|
57decd2ac7 | ||
|
|
26a9d1fa99 | ||
|
|
bf1ab1bfb4 | ||
|
|
d32f35ced1 | ||
|
|
db37567538 | ||
|
|
dc1bdbb703 | ||
|
|
74a8fa7969 | ||
|
|
b65a6de018 | ||
|
|
1840ce2338 | ||
|
|
b8ef262cc7 | ||
|
|
bb795816e1 | ||
|
|
a046791722 | ||
|
|
88eda7b3fd | ||
|
|
03991e245d |
8
.github/workflows/build.yml
vendored
@@ -29,6 +29,8 @@ jobs:
|
|||||||
chip: esp32s3
|
chip: esp32s3
|
||||||
- name: heltec_wireless_stick_lite_v3_display
|
- name: heltec_wireless_stick_lite_v3_display
|
||||||
chip: esp32s3
|
chip: esp32s3
|
||||||
|
- name: heltec_wireless_bridge
|
||||||
|
chip: esp32
|
||||||
- name: ESP32_DIY_LoRa
|
- name: ESP32_DIY_LoRa
|
||||||
chip: esp32
|
chip: esp32
|
||||||
- name: ESP32_DIY_LoRa_915
|
- name: ESP32_DIY_LoRa_915
|
||||||
@@ -67,7 +69,11 @@ jobs:
|
|||||||
chip: esp32s3
|
chip: esp32s3
|
||||||
- name: heltec_ht-ct62
|
- name: heltec_ht-ct62
|
||||||
chip: esp32c3
|
chip: esp32c3
|
||||||
- name: heltec_wireless_paper
|
- name: heltec_wireless_paper_v1
|
||||||
|
chip: esp32s3
|
||||||
|
- name: heltec_wireless_paper_v1_2
|
||||||
|
chip: esp32s3
|
||||||
|
- name: heltec_vision_master_e290
|
||||||
chip: esp32s3
|
chip: esp32s3
|
||||||
- name: OE5HWN_MeshCom
|
- name: OE5HWN_MeshCom
|
||||||
chip: esp32
|
chip: esp32
|
||||||
|
|||||||
46
README.md
@@ -2,53 +2,45 @@
|
|||||||
|
|
||||||
This firmware is for using ESP32 based boards with LoRa Modules and GPS to live in the APRS world.
|
This firmware is for using ESP32 based boards with LoRa Modules and GPS to live in the APRS world.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
__(This iGate Firmware works with all LoRa Tracker Firmwares (specially this <a href="https://github.com/richonguzman/LoRa_APRS_Tracker" target="_blank">LoRa APRS Tracker Firmware</a>))__
|
__(This iGate Firmware works with all LoRa Tracker Firmwares (specially this <a href="https://github.com/richonguzman/LoRa_APRS_Tracker" target="_blank">LoRa APRS Tracker Firmware</a>))__
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
____________________________________________________
|
____________________________________________________
|
||||||
|
|
||||||
## You can support this project to continue to grow:
|
# <a href="https://richonguzman.github.io/lora-igate-web-flasher/installer.html" target="_blank">WEB FLASHER/INSTALLER</a>
|
||||||
|
|
||||||
[<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/github-sponsors.png">](https://github.com/sponsors/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/paypalme.png">](http://paypal.me/richonguzman)
|
|
||||||
|
|
||||||
<br />
|
# <a href="https://drive.google.com/file/d/1Hff_Szd7ks8RC7_RiV6POxPJlclbO05M/view?usp=sharing" target="_blank">LoRa APRS iGate CA2RXU Firmware Manual</a>
|
||||||
|
|
||||||
# WEB FLASHER/INSTALLER is <a href="https://richonguzman.github.io/lora-igate-web-flasher/installer.html" target="_blank">here</a>
|
|
||||||
|
|
||||||
____________________________________________________
|
____________________________________________________
|
||||||
|
|
||||||
# WIKI
|
## You can support this project to continue to grow:
|
||||||
|
|
||||||
### FAQ, BME280, TNC and more --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/00.-FAQ-(frequently-asked-questions)" target="_blank">here</a>.
|
[<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/raw/main/images/github-sponsors.png">](https://github.com/sponsors/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/raw/main/images/paypalme.png">](http://paypal.me/richonguzman)
|
||||||
|
|
||||||
### Installation Guide --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/01.-Installation-Guide" target="_blank">here</a>.
|
____________________________________________________
|
||||||
<br />
|
|
||||||
|
|
||||||
# SUPPORTED BOARDS
|
## SUPPORTED BOARDS (<a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/Supported-Boards-and-Buying-Links" target="_blank">Buying links</a>).
|
||||||
|
|
||||||
### Buying links --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/108.-Supported-Boards-and-Buying-Links" target="_blank">here</a>.
|
|
||||||
|
|
||||||
(NOTE: all boards with 433-868-915 MHz versions)
|
(NOTE: all boards with 433-868-915 MHz versions)
|
||||||
|
|
||||||
- TTGO Lilygo LoRa32 T3S3 V1.2 and LoRa32 V2.1 (V1.6 is the same).
|
- TTGO Lilygo LoRa32 T3S3 V1.2 and LoRa32 V2.1 (V1.6 is the same).
|
||||||
|
|
||||||
- TTGO T-Beam V1.0 , V1.1, V1.2 (also variations with SX1262 and SX1268 LoRa Modules).
|
- TTGO T-Beam V1.0 , V1.1, V1.2 (also variations with SX1262 and SX1268 LoRa Modules) and Supreme V3.
|
||||||
|
|
||||||
- T-Deck Plus (and also regular T-Deck with/without GPS).
|
- T-Deck Plus (and also regular T-Deck with/without GPS).
|
||||||
|
|
||||||
- HELTEC V2, V3, V3.2, T114, Wireless Stick, Wireless Stick Lite, HT-CT62, Wireless Tracker, Wireless Paper.
|
- HELTEC V2, V3, V3.2, T114, Wireless Stick, Wireless Stick Lite V3/V3.2, HT-CT62, Wireless Tracker, Wireless Paper.
|
||||||
|
|
||||||
- RAK Wireless 4631 + 19007(19003)
|
- RAK Wireless 4631 + 19007(or 19003)
|
||||||
|
|
||||||
- Faketec (NRF52840 + Heltec HTRA62(SX1262))
|
- Faketec V3 (NRF52840 + Heltec HTRA62(SX1262))
|
||||||
|
|
||||||
- QRP Labs LightGateway 1.0 and Plus 1.0.
|
- QRP Labs LightGateway 1.0 and Plus 1.0.
|
||||||
|
|
||||||
- Faketec V3 (NRF52840 + Heltec HTRA62 SX1262)
|
- ESP32 + SX1278 LoRa Module or Ebyte 400M30S (or 900M30S) 1W LoRa Module for a DIY Versions.
|
||||||
|
|
||||||
- ESP32 Wroom + SX1278 LoRa Module or Ebyte 400M30S (or 900M30S) 1W LoRa Module for a DIY Versions.
|
|
||||||
|
|
||||||
- ESP32C3 + Ebyte 400M30S(or 900M30S) 1W LoRa Module for another DIY version.
|
- ESP32C3 + Ebyte 400M30S(or 900M30S) 1W LoRa Module for another DIY version.
|
||||||
|
|
||||||
@@ -58,8 +50,18 @@ ____________________________________________________
|
|||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
## Timeline (Versions):
|
# Timeline (Versions):
|
||||||
|
- 2025-12-22 Heltec Wireless Paper V1.2 and VisionMaster E290 Added. Thanks HA5SZI.
|
||||||
|
- 2025-12-18 TCXO and packet decoding updates.
|
||||||
|
- 2025-12-01 APRSPacketLib updates, AHT20 sensor added, INA219 support added.
|
||||||
|
- 2025-10-15 APRS Bridge for TNC added.
|
||||||
|
- 2025-10-13 Rx and Tx Frequencies are now with fully configurable.
|
||||||
|
- 2025-10-13 Startup Delay to allow the Router/Modem to start WiFiAP before connecting.
|
||||||
|
- 2025-10-12 Choose to send Beacon on Rx or Tx frequency.
|
||||||
|
- 2025-10-11 User defined NTP server and send beacon over MQTT added.
|
||||||
|
- 2025-10-10 Converted the Wiki into a PDF manual.
|
||||||
|
- 2025-09-26 Heltec Wireless Bridge support added.
|
||||||
|
- 2025-09-09 MQTT added (pub+sub), Status defined by Op now and many fixes more.
|
||||||
- 2025-06-20 Digipeaters now with updated EcoMode (Board Sleeps until packet Rx reducing current consumption to almost 10% at idle).
|
- 2025-06-20 Digipeaters now with updated EcoMode (Board Sleeps until packet Rx reducing current consumption to almost 10% at idle).
|
||||||
- 2025-06-20 New Boards Added: Heltec T114 MeshNode, Faketec V3 as Digipeaters and QRP Labs LightGateway Plus 1.0.
|
- 2025-06-20 New Boards Added: Heltec T114 MeshNode, Faketec V3 as Digipeaters and QRP Labs LightGateway Plus 1.0.
|
||||||
- 2025-06-19 DateVersion format Change. Licence changed into GNU GPLv3.
|
- 2025-06-19 DateVersion format Change. Licence changed into GNU GPLv3.
|
||||||
|
|||||||
@@ -3,40 +3,42 @@ build_flags =
|
|||||||
-Werror -Wall
|
-Werror -Wall
|
||||||
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
|
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
|
||||||
-D RADIOLIB_EXCLUDE_CC1101=1
|
-D RADIOLIB_EXCLUDE_CC1101=1
|
||||||
-DRADIOLIB_EXCLUDE_NRF24=1
|
|
||||||
-D RADIOLIB_EXCLUDE_RF69=1
|
-D RADIOLIB_EXCLUDE_RF69=1
|
||||||
|
-D RADIOLIB_EXCLUDE_RFM2X=1
|
||||||
-D RADIOLIB_EXCLUDE_SX1231=1
|
-D RADIOLIB_EXCLUDE_SX1231=1
|
||||||
-D RADIOLIB_EXCLUDE_SX1233=1
|
-D RADIOLIB_EXCLUDE_SX1233=1
|
||||||
-D RADIOLIB_EXCLUDE_SI443X=1
|
-D RADIOLIB_EXCLUDE_SI443X=1
|
||||||
-DRADIOLIB_EXCLUDE_RFM2X=1
|
-D RADIOLIB_EXCLUDE_NRF24=1
|
||||||
-D RADIOLIB_EXCLUDE_AFSK=1
|
-D RADIOLIB_EXCLUDE_AFSK=1
|
||||||
|
-D RADIOLIB_EXCLUDE_APRS=1
|
||||||
|
-D RADIOLIB_EXCLUDE_AX25=1
|
||||||
-D RADIOLIB_EXCLUDE_BELL=1
|
-D RADIOLIB_EXCLUDE_BELL=1
|
||||||
|
-D RADIOLIB_EXCLUDE_FSK4=1
|
||||||
-D RADIOLIB_EXCLUDE_HELLSCHREIBER=1
|
-D RADIOLIB_EXCLUDE_HELLSCHREIBER=1
|
||||||
|
-D RADIOLIB_EXCLUDE_LORAWAN=1
|
||||||
-D RADIOLIB_EXCLUDE_MORSE=1
|
-D RADIOLIB_EXCLUDE_MORSE=1
|
||||||
|
-D RADIOLIB_EXCLUDE_PAGER=1
|
||||||
|
-D RADIOLIB_EXCLUDE_DIRECT_RECEIVE=1
|
||||||
-D RADIOLIB_EXCLUDE_RTTY=1
|
-D RADIOLIB_EXCLUDE_RTTY=1
|
||||||
-D RADIOLIB_EXCLUDE_SSTV=1
|
-D RADIOLIB_EXCLUDE_SSTV=1
|
||||||
-DRADIOLIB_EXCLUDE_AX25=1
|
|
||||||
-DRADIOLIB_EXCLUDE_DIRECT_RECEIVE=1
|
|
||||||
-DRADIOLIB_EXCLUDE_BELL=1
|
|
||||||
-DRADIOLIB_EXCLUDE_PAGER=1
|
|
||||||
-DRADIOLIB_EXCLUDE_FSK4=1
|
|
||||||
-DRADIOLIB_EXCLUDE_APRS=1
|
|
||||||
-DRADIOLIB_EXCLUDE_LORAWAN=1
|
|
||||||
-I variants/${PIOENV}
|
-I variants/${PIOENV}
|
||||||
lib_deps =
|
lib_deps =
|
||||||
adafruit/Adafruit Unified Sensor @ 1.1.14
|
adafruit/Adafruit Unified Sensor @ 1.1.14
|
||||||
|
adafruit/Adafruit AHTX0 @ 2.0.5
|
||||||
adafruit/Adafruit BME280 Library @ 2.2.4
|
adafruit/Adafruit BME280 Library @ 2.2.4
|
||||||
adafruit/Adafruit BMP280 Library @ 2.6.8
|
adafruit/Adafruit BMP280 Library @ 2.6.8
|
||||||
adafruit/Adafruit BME680 Library @ 2.0.4
|
adafruit/Adafruit BME680 Library @ 2.0.4
|
||||||
|
adafruit/Adafruit INA219 @ 1.2.3
|
||||||
adafruit/Adafruit Si7021 Library @ 1.5.3
|
adafruit/Adafruit Si7021 Library @ 1.5.3
|
||||||
arduino-libraries/NTPClient @ 3.2.1
|
arduino-libraries/NTPClient @ 3.2.1
|
||||||
ayushsharma82/ElegantOTA @ 3.1.5
|
ayushsharma82/ElegantOTA @ 3.1.5
|
||||||
bblanchon/ArduinoJson @ 6.21.3
|
bblanchon/ArduinoJson @ 6.21.3
|
||||||
jgromes/RadioLib @ 7.1.0
|
jgromes/RadioLib @ 7.1.0
|
||||||
|
knolleary/PubSubClient @ 2.8
|
||||||
mathieucarbou/AsyncTCP @ 3.2.5
|
mathieucarbou/AsyncTCP @ 3.2.5
|
||||||
mathieucarbou/ESPAsyncWebServer @ 3.2.3
|
mathieucarbou/ESPAsyncWebServer @ 3.2.3
|
||||||
mikalhart/TinyGPSPlus @ 1.0.3
|
mikalhart/TinyGPSPlus @ 1.0.3
|
||||||
richonguzman/APRSPacketLib @1.0.0
|
richonguzman/APRSPacketLib @ 1.0.4
|
||||||
display_libs =
|
display_libs =
|
||||||
adafruit/Adafruit GFX Library @ 1.11.9
|
adafruit/Adafruit GFX Library @ 1.11.9
|
||||||
adafruit/Adafruit SSD1306 @ 2.5.10
|
adafruit/Adafruit SSD1306 @ 2.5.10
|
||||||
|
|||||||
@@ -17,31 +17,39 @@
|
|||||||
"path": "WIDE1-1",
|
"path": "WIDE1-1",
|
||||||
"sendViaAPRSIS": false,
|
"sendViaAPRSIS": false,
|
||||||
"sendViaRF": false,
|
"sendViaRF": false,
|
||||||
|
"beaconFreq": 1,
|
||||||
"statusActive": false,
|
"statusActive": false,
|
||||||
"statusPacket": ""
|
"statusPacket": "",
|
||||||
|
"gpsActive": false,
|
||||||
|
"ambiguityLevel": 0
|
||||||
},
|
},
|
||||||
"aprs_is": {
|
"aprs_is": {
|
||||||
"active": false,
|
"active": false,
|
||||||
"passcode": "XYZVW",
|
|
||||||
"server": "rotate.aprs2.net",
|
|
||||||
"port": 14580,
|
|
||||||
"filter": "m/10",
|
|
||||||
"messagesToRF": false,
|
"messagesToRF": false,
|
||||||
"objectsToRF": false
|
"objectsToRF": false,
|
||||||
|
"server": "rotate.aprs2.net",
|
||||||
|
"passcode": "XYZVW",
|
||||||
|
"port": 14580,
|
||||||
|
"filter": "m/10"
|
||||||
},
|
},
|
||||||
|
"personalNote": "",
|
||||||
|
"blacklist": "",
|
||||||
"digi": {
|
"digi": {
|
||||||
"mode": 0,
|
"mode": 0,
|
||||||
"ecoMode": 0
|
"ecoMode": 0
|
||||||
},
|
},
|
||||||
"lora": {
|
"lora": {
|
||||||
"txFreq": 433775000,
|
"rxActive": true,
|
||||||
"rxFreq": 433775000,
|
"rxFreq": 433775000,
|
||||||
"spreadingFactor": 12,
|
"rxSpreadingFactor": 12,
|
||||||
"signalBandwidth": 125000,
|
"rxCodingRate4": 5,
|
||||||
"codingRate4": 5,
|
"rxSignalBandwidth": 125000,
|
||||||
"power": 20,
|
|
||||||
"txActive": false,
|
"txActive": false,
|
||||||
"rxActive": true
|
"txFreq": 433775000,
|
||||||
|
"txSpreadingFactor": 12,
|
||||||
|
"txCodingRate4": 5,
|
||||||
|
"txSignalBandwidth": 125000,
|
||||||
|
"power": 20
|
||||||
},
|
},
|
||||||
"display": {
|
"display": {
|
||||||
"alwaysOn": true,
|
"alwaysOn": true,
|
||||||
@@ -53,11 +61,12 @@
|
|||||||
"monitorInternalVoltage": false,
|
"monitorInternalVoltage": false,
|
||||||
"internalSleepVoltage": 2.9,
|
"internalSleepVoltage": 2.9,
|
||||||
"sendExternalVoltage": false,
|
"sendExternalVoltage": false,
|
||||||
"externalVoltagePin": 34,
|
|
||||||
"monitorExternalVoltage": false,
|
"monitorExternalVoltage": false,
|
||||||
"externalSleepVoltage": 10.9,
|
"externalSleepVoltage": 10.9,
|
||||||
|
"useExternalI2CSensor": false,
|
||||||
"voltageDividerR1": 100.0,
|
"voltageDividerR1": 100.0,
|
||||||
"voltageDividerR2": 27.0,
|
"voltageDividerR2": 27.0,
|
||||||
|
"externalVoltagePin": 34,
|
||||||
"sendVoltageAsTelemetry": false
|
"sendVoltageAsTelemetry": false
|
||||||
},
|
},
|
||||||
"wxsensor": {
|
"wxsensor": {
|
||||||
@@ -74,7 +83,17 @@
|
|||||||
"tnc": {
|
"tnc": {
|
||||||
"enableServer": false,
|
"enableServer": false,
|
||||||
"enableSerial": false,
|
"enableSerial": false,
|
||||||
"acceptOwn": false
|
"acceptOwn": false,
|
||||||
|
"aprsBrigdeActive": false
|
||||||
|
},
|
||||||
|
"mqtt": {
|
||||||
|
"active": false,
|
||||||
|
"server": "",
|
||||||
|
"topic": "",
|
||||||
|
"username": "",
|
||||||
|
"password": "",
|
||||||
|
"port": 1883,
|
||||||
|
"beaconOverMqtt": false
|
||||||
},
|
},
|
||||||
"ota": {
|
"ota": {
|
||||||
"username": "",
|
"username": "",
|
||||||
@@ -84,19 +103,19 @@
|
|||||||
"username": "admin",
|
"username": "admin",
|
||||||
"password": ""
|
"password": ""
|
||||||
},
|
},
|
||||||
"ntp": {
|
|
||||||
"gmtCorrection": 0.0
|
|
||||||
},
|
|
||||||
"remoteManagement": {
|
"remoteManagement": {
|
||||||
"managers": "",
|
"managers": "",
|
||||||
"rfOnly": true
|
"rfOnly": true
|
||||||
},
|
},
|
||||||
|
"ntp": {
|
||||||
|
"server": "pool.ntp.org",
|
||||||
|
"gmtCorrection": 0.0
|
||||||
|
},
|
||||||
"other": {
|
"other": {
|
||||||
"rememberStationTime": 30,
|
"rememberStationTime": 30,
|
||||||
"backupDigiMode": false,
|
"backupDigiMode": false,
|
||||||
"rebootMode": false,
|
"rebootMode": false,
|
||||||
"rebootModeTime": 6
|
"rebootModeTime": 6,
|
||||||
},
|
"startupDelay": 0
|
||||||
"personalNote": "",
|
}
|
||||||
"blacklist": ""
|
|
||||||
}
|
}
|
||||||
@@ -49,29 +49,6 @@ function fetchSettings() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const alwaysOnCheckbox = document.querySelector(
|
|
||||||
'input[name="display.alwaysOn"]'
|
|
||||||
);
|
|
||||||
const timeoutInput = document.querySelector('input[name="display.timeout"]');
|
|
||||||
|
|
||||||
alwaysOnCheckbox.addEventListener("change", function () {
|
|
||||||
timeoutInput.disabled = this.checked;
|
|
||||||
});
|
|
||||||
|
|
||||||
// timeoutInput.addEventListener("change", function () {
|
|
||||||
// alwaysOnCheckbox.disabled = this.value !== "";
|
|
||||||
// });
|
|
||||||
|
|
||||||
const logCheckbox = document.querySelector('input[name="syslog.active"]');
|
|
||||||
const serverField = document.querySelector('input[name="syslog.server"]');
|
|
||||||
const portField = document.querySelector('input[name="syslog.port"]');
|
|
||||||
const logBeaconOverTCPIPField = document.querySelector('input[name="syslog.logBeaconOverTCPIP"]');
|
|
||||||
|
|
||||||
logCheckbox.addEventListener("change", function () {
|
|
||||||
serverField.disabled = !this.checked;
|
|
||||||
portField.disabled = !this.checked;
|
|
||||||
logBeaconOverTCPIPField.disabled = !this.checked
|
|
||||||
});
|
|
||||||
|
|
||||||
function loadSettings(settings) {
|
function loadSettings(settings) {
|
||||||
currentSettings = settings;
|
currentSettings = settings;
|
||||||
@@ -118,6 +95,7 @@ function loadSettings(settings) {
|
|||||||
networksContainer.appendChild(networkElement);
|
networksContainer.appendChild(networkElement);
|
||||||
networkCount++;
|
networkCount++;
|
||||||
});
|
});
|
||||||
|
document.getElementById("startupDelay").value = settings.startupDelay;
|
||||||
|
|
||||||
// APRS-IS
|
// APRS-IS
|
||||||
document.getElementById("aprs_is.active").checked = settings.aprs_is.active;
|
document.getElementById("aprs_is.active").checked = settings.aprs_is.active;
|
||||||
@@ -127,6 +105,13 @@ function loadSettings(settings) {
|
|||||||
document.getElementById("aprs_is.port").value = settings.aprs_is.port;
|
document.getElementById("aprs_is.port").value = settings.aprs_is.port;
|
||||||
document.getElementById("aprs_is.filter").value = settings.aprs_is.filter;
|
document.getElementById("aprs_is.filter").value = settings.aprs_is.filter;
|
||||||
document.getElementById("aprs_is.passcode").value = settings.aprs_is.passcode;
|
document.getElementById("aprs_is.passcode").value = settings.aprs_is.passcode;
|
||||||
|
APRSISCheckbox.checked = settings.aprs_is.active;
|
||||||
|
APRSISGateMessages.disabled = !APRSISCheckbox.checked;
|
||||||
|
APRSISGateObjects.disabled = !APRSISCheckbox.checked;
|
||||||
|
APRSISServer.disabled = !APRSISCheckbox.checked;
|
||||||
|
APRSISPort.disabled = !APRSISCheckbox.checked;
|
||||||
|
APRSISPasscode.disabled = !APRSISCheckbox.checked;
|
||||||
|
APRSISFilter.disabled = !APRSISCheckbox.checked;
|
||||||
|
|
||||||
// Beacon
|
// Beacon
|
||||||
document.getElementById("beacon.latitude").value = settings.beacon.latitude;
|
document.getElementById("beacon.latitude").value = settings.beacon.latitude;
|
||||||
@@ -134,79 +119,120 @@ function loadSettings(settings) {
|
|||||||
document.getElementById("beacon.interval").value = settings.beacon.interval;
|
document.getElementById("beacon.interval").value = settings.beacon.interval;
|
||||||
document.getElementById("other.rememberStationTime").value = settings.other.rememberStationTime;
|
document.getElementById("other.rememberStationTime").value = settings.other.rememberStationTime;
|
||||||
document.getElementById("beacon.sendViaAPRSIS").checked = settings.beacon.sendViaAPRSIS;
|
document.getElementById("beacon.sendViaAPRSIS").checked = settings.beacon.sendViaAPRSIS;
|
||||||
|
|
||||||
document.getElementById("beacon.sendViaRF").checked = settings.beacon.sendViaRF;
|
document.getElementById("beacon.sendViaRF").checked = settings.beacon.sendViaRF;
|
||||||
|
document.getElementById("beacon.beaconFreq").value = settings.beacon.beaconFreq;
|
||||||
|
BeaconingViaRFCheckbox.checked = settings.beacon.sendViaRF;
|
||||||
|
BeaconingFrequency.disabled = !BeaconingViaRFCheckbox.checked;
|
||||||
|
|
||||||
document.getElementById("beacon.statusActive").checked = settings.beacon.statusActive;
|
document.getElementById("beacon.statusActive").checked = settings.beacon.statusActive;
|
||||||
document.getElementById("beacon.statusPacket").value = settings.beacon.statusPacket;
|
document.getElementById("beacon.statusPacket").value = settings.beacon.statusPacket;
|
||||||
|
StatusCheckbox.checked = settings.beacon.statusActive;
|
||||||
|
StatusPacket.disabled = !StatusCheckbox.checked;
|
||||||
|
|
||||||
document.getElementById("beacon.gpsActive").checked = settings.beacon.gpsActive;
|
document.getElementById("beacon.gpsActive").checked = settings.beacon.gpsActive;
|
||||||
document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity;
|
document.getElementById("beacon.ambiguityLevel").value = settings.beacon.ambiguityLevel;
|
||||||
|
|
||||||
// Black List
|
// Black List
|
||||||
document.getElementById("blacklist").value = settings.blacklist;
|
document.getElementById("blacklist").value = settings.blacklist;
|
||||||
|
|
||||||
// Digi
|
// Digi
|
||||||
document.getElementById("digi.mode").value = settings.digi.mode;
|
document.getElementById("digi.mode").value = settings.digi.mode;
|
||||||
document.getElementById("digi.ecoMode").checked = settings.digi.ecoMode;
|
document.getElementById("digi.ecoMode").value = settings.digi.ecoMode;
|
||||||
|
|
||||||
// LoRa
|
// LoRa
|
||||||
document.getElementById("lora.txFreq").value = settings.lora.txFreq;
|
|
||||||
document.getElementById("lora.rxFreq").value = settings.lora.rxFreq;
|
|
||||||
document.getElementById("lora.txActive").checked = settings.lora.txActive;
|
|
||||||
document.getElementById("lora.rxActive").checked = settings.lora.rxActive;
|
document.getElementById("lora.rxActive").checked = settings.lora.rxActive;
|
||||||
document.getElementById("lora.spreadingFactor").value = settings.lora.spreadingFactor;
|
document.getElementById("lora.rxFreq").value = settings.lora.rxFreq;
|
||||||
document.getElementById("lora.signalBandwidth").value = settings.lora.signalBandwidth;
|
document.getElementById("lora.rxSpreadingFactor").value = settings.lora.rxSpreadingFactor;
|
||||||
document.getElementById("lora.codingRate4").value = settings.lora.codingRate4;
|
document.getElementById("lora.rxCodingRate4").value = settings.lora.rxCodingRate4;
|
||||||
|
document.getElementById("lora.rxSignalBandwidth").value = settings.lora.rxSignalBandwidth;
|
||||||
|
document.getElementById("lora.txActive").checked = settings.lora.txActive;
|
||||||
|
document.getElementById("lora.txFreq").value = settings.lora.txFreq;
|
||||||
|
document.getElementById("lora.txSpreadingFactor").value = settings.lora.txSpreadingFactor;
|
||||||
|
document.getElementById("lora.txCodingRate4").value = settings.lora.txCodingRate4;
|
||||||
|
document.getElementById("lora.txSignalBandwidth").value = settings.lora.txSignalBandwidth;
|
||||||
document.getElementById("lora.power").value = settings.lora.power;
|
document.getElementById("lora.power").value = settings.lora.power;
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
document.getElementById("display.alwaysOn").checked = settings.display.alwaysOn;
|
document.getElementById("display.alwaysOn").checked = settings.display.alwaysOn;
|
||||||
document.getElementById("display.turn180").checked = settings.display.turn180;
|
document.getElementById("display.turn180").checked = settings.display.turn180;
|
||||||
document.getElementById("display.timeout").value = settings.display.timeout;
|
document.getElementById("display.timeout").value = settings.display.timeout;
|
||||||
|
DisplayAlwaysOnCheckbox.checked = settings.display.alwaysOn;
|
||||||
if (settings.display.alwaysOn) {
|
DisplayTimeout.disabled = DisplayAlwaysOnCheckbox.checked;
|
||||||
timeoutInput.disabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BATTERY
|
// BATTERY
|
||||||
document.getElementById("battery.sendInternalVoltage").checked = settings.battery.sendInternalVoltage;
|
document.getElementById("battery.sendInternalVoltage").checked = settings.battery.sendInternalVoltage;
|
||||||
document.getElementById("battery.monitorInternalVoltage").checked = settings.battery.monitorInternalVoltage;
|
document.getElementById("battery.monitorInternalVoltage").checked = settings.battery.monitorInternalVoltage;
|
||||||
document.getElementById("battery.internalSleepVoltage").value = settings.battery.internalSleepVoltage.toFixed(1);
|
document.getElementById("battery.internalSleepVoltage").value = settings.battery.internalSleepVoltage.toFixed(1);
|
||||||
|
MonitorInternalVoltageCheckbox.checked = settings.battery.monitorInternalVoltage;
|
||||||
|
MonitorInternalSleepVoltage.disabled = !MonitorInternalVoltageCheckbox.checked;
|
||||||
|
|
||||||
document.getElementById("battery.sendExternalVoltage").checked = settings.battery.sendExternalVoltage;
|
document.getElementById("battery.sendExternalVoltage").checked = settings.battery.sendExternalVoltage;
|
||||||
|
document.getElementById("battery.useExternalI2CSensor").checked = settings.battery.useExternalI2CSensor;
|
||||||
document.getElementById("battery.externalVoltagePin").value = settings.battery.externalVoltagePin;
|
document.getElementById("battery.externalVoltagePin").value = settings.battery.externalVoltagePin;
|
||||||
document.getElementById("battery.voltageDividerR1").value = settings.battery.voltageDividerR1.toFixed(1);
|
document.getElementById("battery.voltageDividerR1").value = settings.battery.voltageDividerR1.toFixed(1);
|
||||||
document.getElementById("battery.voltageDividerR2").value = settings.battery.voltageDividerR2.toFixed(1);
|
document.getElementById("battery.voltageDividerR2").value = settings.battery.voltageDividerR2.toFixed(1);
|
||||||
|
SendExternalVoltageCheckbox.checked = settings.battery.sendExternalVoltage;
|
||||||
|
UseExternalI2CSensorCheckbox.disabled = !SendExternalVoltageCheckbox.checked;
|
||||||
|
ExternalVoltagePin.disabled = !SendExternalVoltageCheckbox.checked || UseExternalI2CSensorCheckbox.checked;
|
||||||
|
ExternalVoltageDividerR1.disabled = !SendExternalVoltageCheckbox.checked || UseExternalI2CSensorCheckbox.checked;
|
||||||
|
ExternalVoltageDividerR2.disabled = !SendExternalVoltageCheckbox.checked || UseExternalI2CSensorCheckbox.checked;
|
||||||
|
|
||||||
|
|
||||||
document.getElementById("battery.monitorExternalVoltage").checked = settings.battery.monitorExternalVoltage;
|
document.getElementById("battery.monitorExternalVoltage").checked = settings.battery.monitorExternalVoltage;
|
||||||
document.getElementById("battery.externalSleepVoltage").value = settings.battery.externalSleepVoltage.toFixed(1);
|
document.getElementById("battery.externalSleepVoltage").value = settings.battery.externalSleepVoltage.toFixed(1);
|
||||||
|
MonitorExternalVoltageCheckbox.checked = settings.battery.monitorExternalVoltage;
|
||||||
|
MonitorExternalSleepVoltage.disabled = !MonitorExternalVoltageCheckbox.checked;
|
||||||
|
|
||||||
document.getElementById("battery.sendVoltageAsTelemetry").checked = settings.battery.sendVoltageAsTelemetry;
|
document.getElementById("battery.sendVoltageAsTelemetry").checked = settings.battery.sendVoltageAsTelemetry;
|
||||||
|
|
||||||
// TELEMETRY WX SENSOR
|
// TELEMETRY WX SENSOR
|
||||||
document.getElementById("wxsensor.active").checked = settings.wxsensor.active;
|
document.getElementById("wxsensor.active").checked = settings.wxsensor.active;
|
||||||
document.getElementById("wxsensor.heightCorrection").value = settings.wxsensor.heightCorrection;
|
document.getElementById("wxsensor.heightCorrection").value = settings.wxsensor.heightCorrection;
|
||||||
document.getElementById("wxsensor.temperatureCorrection").value = settings.wxsensor.temperatureCorrection.toFixed(1);
|
document.getElementById("wxsensor.temperatureCorrection").value = settings.wxsensor.temperatureCorrection.toFixed(1);
|
||||||
|
TelemetryCheckbox.checked = settings.wxsensor.active;
|
||||||
|
TelemetryHeightCorrection.disabled = !TelemetryCheckbox.checked;
|
||||||
|
TelemetryTempCorrection.disabled = !TelemetryCheckbox.checked;
|
||||||
|
|
||||||
// SYSLOG
|
// SYSLOG
|
||||||
document.getElementById("syslog.active").checked = settings.syslog.active;
|
document.getElementById("syslog.active").checked = settings.syslog.active;
|
||||||
document.getElementById("syslog.server").value = settings.syslog.server;
|
document.getElementById("syslog.server").value = settings.syslog.server;
|
||||||
document.getElementById("syslog.port").value = settings.syslog.port;
|
document.getElementById("syslog.port").value = settings.syslog.port;
|
||||||
document.getElementById("syslog.logBeaconOverTCPIP").checked = settings.syslog.logBeaconOverTCPIP;
|
document.getElementById("syslog.logBeaconOverTCPIP").checked = settings.syslog.logBeaconOverTCPIP;
|
||||||
|
SyslogCheckbox.checked = settings.syslog.active;
|
||||||
if (settings.syslog.active) {
|
SyslogServer.disabled = !SyslogCheckbox.checked;
|
||||||
serverField.disabled = false;
|
SyslogPort.disabled = !SyslogCheckbox.checked;
|
||||||
portField.disabled = false;
|
SyslogBeaconOverTCPIP.disabled = !SyslogCheckbox.checked;
|
||||||
logBeaconOverTCPIPField.disabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TNC
|
// TNC
|
||||||
if (settings.tnc) {
|
if (settings.tnc) {
|
||||||
document.getElementById("tnc.enableServer").checked = settings.tnc.enableServer;
|
document.getElementById("tnc.enableServer").checked = settings.tnc.enableServer;
|
||||||
document.getElementById("tnc.enableSerial").checked = settings.tnc.enableSerial;
|
document.getElementById("tnc.enableSerial").checked = settings.tnc.enableSerial;
|
||||||
document.getElementById("tnc.acceptOwn").checked = settings.tnc.acceptOwn;
|
document.getElementById("tnc.acceptOwn").checked = settings.tnc.acceptOwn;
|
||||||
|
document.getElementById("tnc.aprsBridgeActive").checked = settings.tnc.aprsBridgeActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MQTT
|
||||||
|
document.getElementById("mqtt.active").checked = settings.mqtt.active;
|
||||||
|
document.getElementById("mqtt.server").value = settings.mqtt.server;
|
||||||
|
document.getElementById("mqtt.topic").value = settings.mqtt.topic;
|
||||||
|
document.getElementById("mqtt.username").value = settings.mqtt.username;
|
||||||
|
document.getElementById("mqtt.password").value = settings.mqtt.password;
|
||||||
|
document.getElementById("mqtt.port").value = settings.mqtt.port;
|
||||||
|
document.getElementById("mqtt.beaconOverMqtt").checked = settings.mqtt.beaconOverMqtt;
|
||||||
|
MqttCheckbox.checked = settings.mqtt.active;
|
||||||
|
MqttServer.disabled = !MqttCheckbox.checked;
|
||||||
|
MqttTopic.disabled = !MqttCheckbox.checked;
|
||||||
|
MqttUsername.disabled = !MqttCheckbox.checked;
|
||||||
|
MqttPassword.disabled = !MqttCheckbox.checked;
|
||||||
|
MqttPort.disabled = !MqttCheckbox.checked;
|
||||||
|
MqttBeaconOverMqtt.disabled = !MqttCheckbox.checked;
|
||||||
|
|
||||||
// Reboot
|
// Reboot
|
||||||
document.getElementById("other.rebootMode").checked = settings.other.rebootMode;
|
document.getElementById("other.rebootMode").checked = settings.other.rebootMode;
|
||||||
document.getElementById("other.rebootModeTime").value = settings.other.rebootModeTime;
|
document.getElementById("other.rebootModeTime").value = settings.other.rebootModeTime;
|
||||||
|
RebootModeCheckbox.checked = settings.other.rebootMode;
|
||||||
|
RebootModeTime.disabled = !RebootModeCheckbox.check;
|
||||||
|
|
||||||
// WiFi Auto AP
|
// WiFi Auto AP
|
||||||
document.getElementById("wifi.autoAP.password").value = settings.wifi.autoAP.password;
|
document.getElementById("wifi.autoAP.password").value = settings.wifi.autoAP.password;
|
||||||
@@ -220,20 +246,22 @@ function loadSettings(settings) {
|
|||||||
document.getElementById("webadmin.active").checked = settings.webadmin.active;
|
document.getElementById("webadmin.active").checked = settings.webadmin.active;
|
||||||
document.getElementById("webadmin.username").value = settings.webadmin.username;
|
document.getElementById("webadmin.username").value = settings.webadmin.username;
|
||||||
document.getElementById("webadmin.password").value = settings.webadmin.password;
|
document.getElementById("webadmin.password").value = settings.webadmin.password;
|
||||||
|
WebadminCheckbox.checked = settings.webadmin.active;
|
||||||
// NTP
|
WebadminUsername.disabled = !WebadminCheckbox.check;
|
||||||
document.getElementById("ntp.gmtCorrection").value = settings.ntp.gmtCorrection;
|
WebadminPassword.disabled = !WebadminCheckbox.check;
|
||||||
|
|
||||||
// Experimental
|
|
||||||
document.getElementById("other.backupDigiMode").checked = settings.other.backupDigiMode;
|
|
||||||
|
|
||||||
// Management over APRS
|
// Management over APRS
|
||||||
document.getElementById("remoteManagement.managers").value = settings.remoteManagement.managers;
|
document.getElementById("remoteManagement.managers").value = settings.remoteManagement.managers;
|
||||||
document.getElementById("remoteManagement.rfOnly").checked = settings.remoteManagement.rfOnly;
|
document.getElementById("remoteManagement.rfOnly").checked = settings.remoteManagement.rfOnly;
|
||||||
|
|
||||||
|
// NTP
|
||||||
|
document.getElementById("ntp.server").value = settings.ntp.server;
|
||||||
|
document.getElementById("ntp.gmtCorrection").value = settings.ntp.gmtCorrection;
|
||||||
|
|
||||||
|
// Experimental
|
||||||
|
document.getElementById("other.backupDigiMode").checked = settings.other.backupDigiMode;
|
||||||
|
|
||||||
updateImage();
|
updateImage();
|
||||||
refreshSpeedStandard();
|
|
||||||
toggleFields();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showToast(message) {
|
function showToast(message) {
|
||||||
@@ -260,8 +288,6 @@ document.getElementById('reboot').addEventListener('click', function (e) {
|
|||||||
showToast("Your device will be rebooted in a while");
|
showToast("Your device will be rebooted in a while");
|
||||||
});
|
});
|
||||||
|
|
||||||
const wxsensorCheckbox = document.querySelector("input[name='wxsensor.active']");
|
|
||||||
|
|
||||||
function updateImage() {
|
function updateImage() {
|
||||||
const value = document.getElementById("beacon.overlay").value + document.getElementById("beacon.symbol").value;
|
const value = document.getElementById("beacon.overlay").value + document.getElementById("beacon.symbol").value;
|
||||||
|
|
||||||
@@ -287,70 +313,127 @@ function updateImage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleFields() {
|
// Beaconing Switches
|
||||||
const sendExternalVoltageCheckbox = document.querySelector(
|
const BeaconingViaRFCheckbox = document.querySelector('input[name="beacon.sendViaRF"]');
|
||||||
'input[name="battery.sendExternalVoltage"]'
|
const BeaconingFrequency = document.querySelector('select[name="beacon.beaconFreq"]');
|
||||||
);
|
BeaconingViaRFCheckbox.addEventListener("change", function() {
|
||||||
const externalVoltagePinInput = document.querySelector(
|
BeaconingFrequency.disabled = !this.checked;
|
||||||
'input[name="battery.externalVoltagePin"]'
|
|
||||||
);
|
|
||||||
|
|
||||||
externalVoltagePinInput.disabled = !sendExternalVoltageCheckbox.checked;
|
|
||||||
voltageDividerR1.disabled = !sendExternalVoltageCheckbox.checked;
|
|
||||||
voltageDividerR2.disabled = !sendExternalVoltageCheckbox.checked;
|
|
||||||
|
|
||||||
const WebadminCheckbox = document.querySelector(
|
|
||||||
'input[name="webadmin.active"]'
|
|
||||||
);
|
|
||||||
|
|
||||||
const WebadminUsername = document.querySelector(
|
|
||||||
'input[name="webadmin.username"]'
|
|
||||||
);
|
|
||||||
|
|
||||||
const WebadminPassword = document.querySelector(
|
|
||||||
'input[name="webadmin.password"]'
|
|
||||||
);
|
|
||||||
WebadminUsername.disabled = !WebadminCheckbox.checked;
|
|
||||||
WebadminPassword.disabled = !WebadminCheckbox.checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sendExternalVoltageCheckbox = document.querySelector(
|
|
||||||
'input[name="battery.sendExternalVoltage"]'
|
|
||||||
);
|
|
||||||
const externalVoltagePinInput = document.querySelector(
|
|
||||||
'input[name="battery.externalVoltagePin"]'
|
|
||||||
);
|
|
||||||
|
|
||||||
const voltageDividerR1 = document.querySelector(
|
|
||||||
'input[name="battery.voltageDividerR1"]'
|
|
||||||
);
|
|
||||||
|
|
||||||
const voltageDividerR2 = document.querySelector(
|
|
||||||
'input[name="battery.voltageDividerR2"]'
|
|
||||||
);
|
|
||||||
|
|
||||||
sendExternalVoltageCheckbox.addEventListener("change", function () {
|
|
||||||
externalVoltagePinInput.disabled = !this.checked;
|
|
||||||
voltageDividerR1.disabled = !this.checked;
|
|
||||||
voltageDividerR2.disabled = !this.checked;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const WebadminCheckbox = document.querySelector(
|
// Status Switch
|
||||||
'input[name="webadmin.active"]'
|
const StatusCheckbox = document.querySelector('input[name="beacon.statusActive"]');
|
||||||
);
|
const StatusPacket = document.querySelector('input[name="beacon.statusPacket"]');
|
||||||
|
StatusCheckbox.addEventListener("change", function() {
|
||||||
|
StatusPacket.disabled = !this.checked;
|
||||||
|
});
|
||||||
|
|
||||||
const WebadminUsername = document.querySelector(
|
// APRS-IS Switches
|
||||||
'input[name="webadmin.username"]'
|
const APRSISCheckbox = document.querySelector('input[name="aprs_is.active"]');
|
||||||
);
|
const APRSISGateMessages = document.querySelector('input[name="aprs_is.messagesToRF"]');
|
||||||
|
const APRSISGateObjects = document.querySelector('input[name="aprs_is.objectsToRF"]');
|
||||||
|
const APRSISServer = document.querySelector('input[name="aprs_is.server"]');
|
||||||
|
const APRSISPort = document.querySelector('input[name="aprs_is.port"]');
|
||||||
|
const APRSISPasscode = document.querySelector('input[name="aprs_is.passcode"]');
|
||||||
|
const APRSISFilter = document.querySelector('input[name="aprs_is.filter"]');
|
||||||
|
APRSISCheckbox.addEventListener("change", function() {
|
||||||
|
APRSISGateMessages.disabled = !this.checked;
|
||||||
|
APRSISGateObjects.disabled = !this.checked;
|
||||||
|
APRSISServer.disabled = !this.checked;
|
||||||
|
APRSISPort.disabled = !this.checked;
|
||||||
|
APRSISPasscode.disabled = !this.checked;
|
||||||
|
APRSISFilter.disabled = !this.checked;
|
||||||
|
});
|
||||||
|
|
||||||
const WebadminPassword = document.querySelector(
|
// Display Switches
|
||||||
'input[name="webadmin.password"]'
|
const DisplayAlwaysOnCheckbox = document.querySelector('input[name="display.alwaysOn"]');
|
||||||
);
|
const DisplayTimeout = document.querySelector('input[name="display.timeout"]');
|
||||||
|
DisplayAlwaysOnCheckbox.addEventListener("change", function () {
|
||||||
|
DisplayTimeout.disabled = this.checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Battery Switches
|
||||||
|
const MonitorInternalVoltageCheckbox = document.querySelector('input[name="battery.monitorInternalVoltage"]');
|
||||||
|
const MonitorInternalSleepVoltage = document.querySelector('input[name="battery.internalSleepVoltage"]');
|
||||||
|
MonitorInternalVoltageCheckbox.addEventListener("change", function () {
|
||||||
|
MonitorInternalSleepVoltage.disabled = !this.checked;
|
||||||
|
});
|
||||||
|
const MonitorExternalVoltageCheckbox = document.querySelector('input[name="battery.monitorExternalVoltage"]');
|
||||||
|
const MonitorExternalSleepVoltage = document.querySelector('input[name="battery.externalSleepVoltage"]');
|
||||||
|
MonitorExternalVoltageCheckbox.addEventListener("change", function () {
|
||||||
|
MonitorExternalSleepVoltage.disabled = !this.checked;
|
||||||
|
});
|
||||||
|
const SendExternalVoltageCheckbox = document.querySelector('input[name="battery.sendExternalVoltage"]');
|
||||||
|
const UseExternalI2CSensorCheckbox = document.querySelector('input[name="battery.useExternalI2CSensor"]');
|
||||||
|
const ExternalVoltagePin = document.querySelector('input[name="battery.externalVoltagePin"]');
|
||||||
|
const ExternalVoltageDividerR1 = document.querySelector('input[name="battery.voltageDividerR1"]');
|
||||||
|
const ExternalVoltageDividerR2 = document.querySelector('input[name="battery.voltageDividerR2"]');
|
||||||
|
SendExternalVoltageCheckbox.addEventListener("change", function () {
|
||||||
|
UseExternalI2CSensorCheckbox.disabled = !this.checked;
|
||||||
|
ExternalVoltagePin.disabled = !this.checked || UseExternalI2CSensorCheckbox.checked;
|
||||||
|
ExternalVoltageDividerR1.disabled = !this.checked || UseExternalI2CSensorCheckbox.checked;
|
||||||
|
ExternalVoltageDividerR2.disabled = !this.checked || UseExternalI2CSensorCheckbox.checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
UseExternalI2CSensorCheckbox.addEventListener("change", function () {
|
||||||
|
ExternalVoltagePin.disabled = this.checked;
|
||||||
|
ExternalVoltageDividerR1.disabled = this.checked;
|
||||||
|
ExternalVoltageDividerR2.disabled = this.checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Telemetry Switches
|
||||||
|
const TelemetryCheckbox = document.querySelector('input[name="wxsensor.active"]');
|
||||||
|
const TelemetryHeightCorrection = document.querySelector('input[name="wxsensor.heightCorrection"]');
|
||||||
|
const TelemetryTempCorrection = document.querySelector('input[name="wxsensor.temperatureCorrection"]');
|
||||||
|
TelemetryCheckbox.addEventListener("change", function () {
|
||||||
|
TelemetryHeightCorrection.disabled = !this.checked;
|
||||||
|
TelemetryTempCorrection.disabled = !this.checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Syslog Switches
|
||||||
|
const SyslogCheckbox = document.querySelector('input[name="syslog.active"]');
|
||||||
|
const SyslogServer = document.querySelector('input[name="syslog.server"]');
|
||||||
|
const SyslogPort = document.querySelector('input[name="syslog.port"]');
|
||||||
|
const SyslogBeaconOverTCPIP = document.querySelector('input[name="syslog.logBeaconOverTCPIP"]');
|
||||||
|
SyslogCheckbox.addEventListener("change", function () {
|
||||||
|
SyslogServer.disabled = !this.checked;
|
||||||
|
SyslogPort.disabled = !this.checked;
|
||||||
|
SyslogBeaconOverTCPIP.disabled = !this.checked
|
||||||
|
});
|
||||||
|
|
||||||
|
// MQTT Switches
|
||||||
|
const MqttCheckbox = document.querySelector('input[name="mqtt.active"]');
|
||||||
|
const MqttServer = document.querySelector('input[name="mqtt.server"]');
|
||||||
|
const MqttTopic = document.querySelector('input[name="mqtt.topic"]');
|
||||||
|
const MqttUsername = document.querySelector('input[name="mqtt.username"]');
|
||||||
|
const MqttPassword = document.querySelector('input[name="mqtt.password"]');
|
||||||
|
const MqttPort = document.querySelector('input[name="mqtt.port"]');
|
||||||
|
const MqttBeaconOverMqtt = document.querySelector('input[name="mqtt.beaconOverMqtt"]');
|
||||||
|
MqttCheckbox.addEventListener("change", function () {
|
||||||
|
MqttServer.disabled = !this.checked;
|
||||||
|
MqttTopic.disabled = !this.checked;
|
||||||
|
MqttUsername.disabled = !this.checked;
|
||||||
|
MqttPassword.disabled = !this.checked;
|
||||||
|
MqttPort.disabled = !this.checked;
|
||||||
|
MqttBeaconOverMqtt.disabled = !this.checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reboot Switches
|
||||||
|
const RebootModeCheckbox = document.querySelector('input[name="other.rebootMode"]');
|
||||||
|
const RebootModeTime = document.querySelector('input[name="other.rebootModeTime"]');
|
||||||
|
RebootModeCheckbox.addEventListener("change", function() {
|
||||||
|
RebootModeTime.disabled = !this.checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Web Admin Switches
|
||||||
|
const WebadminCheckbox = document.querySelector('input[name="webadmin.active"]');
|
||||||
|
const WebadminUsername = document.querySelector('input[name="webadmin.username"]');
|
||||||
|
const WebadminPassword = document.querySelector('input[name="webadmin.password"]');
|
||||||
WebadminCheckbox.addEventListener("change", function () {
|
WebadminCheckbox.addEventListener("change", function () {
|
||||||
WebadminUsername.disabled = !this.checked;
|
WebadminUsername.disabled = !this.checked;
|
||||||
WebadminPassword.disabled = !this.checked;
|
WebadminPassword.disabled = !this.checked;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
document.querySelector(".new button").addEventListener("click", function () {
|
document.querySelector(".new button").addEventListener("click", function () {
|
||||||
const networksContainer = document.querySelector(".list-networks");
|
const networksContainer = document.querySelector(".list-networks");
|
||||||
|
|
||||||
@@ -398,65 +481,6 @@ document
|
|||||||
updateImage();
|
updateImage();
|
||||||
});
|
});
|
||||||
|
|
||||||
const speedStandards = {
|
|
||||||
300: [125, 5, 12],
|
|
||||||
244: [125, 6, 12],
|
|
||||||
209: [125, 7, 12],
|
|
||||||
183: [125, 8, 12],
|
|
||||||
610: [125, 8, 10],
|
|
||||||
1200: [125, 7, 9],
|
|
||||||
};
|
|
||||||
|
|
||||||
function refreshSpeedStandard() {
|
|
||||||
const bw = Number(document.getElementById("lora.signalBandwidth").value);
|
|
||||||
const cr4 = Number(document.getElementById("lora.codingRate4").value);
|
|
||||||
const sf = Number(document.getElementById("lora.spreadingFactor").value);
|
|
||||||
|
|
||||||
let found = false;
|
|
||||||
|
|
||||||
for (const speed in speedStandards) {
|
|
||||||
const standard = speedStandards[speed];
|
|
||||||
|
|
||||||
if (standard[0] !== bw / 1000) continue;
|
|
||||||
if (standard[1] !== cr4) continue;
|
|
||||||
if (standard[2] !== sf) continue;
|
|
||||||
|
|
||||||
document.getElementById("action.speed").value = speed;
|
|
||||||
found = true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
document.getElementById("action.speed").value = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document
|
|
||||||
.getElementById("lora.signalBandwidth")
|
|
||||||
.addEventListener("focusout", refreshSpeedStandard);
|
|
||||||
document
|
|
||||||
.getElementById("lora.codingRate4")
|
|
||||||
.addEventListener("focusout", refreshSpeedStandard);
|
|
||||||
document
|
|
||||||
.getElementById("lora.spreadingFactor")
|
|
||||||
.addEventListener("focusout", refreshSpeedStandard);
|
|
||||||
|
|
||||||
document.getElementById("action.speed").addEventListener("change", function () {
|
|
||||||
const speed = document.getElementById("action.speed").value;
|
|
||||||
|
|
||||||
if (speed !== "") {
|
|
||||||
const value = speedStandards[Number(speed)];
|
|
||||||
|
|
||||||
const bw = value[0];
|
|
||||||
const cr4 = value[1];
|
|
||||||
const sf = value[2];
|
|
||||||
|
|
||||||
document.getElementById("lora.signalBandwidth").value = bw * 1000;
|
|
||||||
document.getElementById("lora.codingRate4").value = cr4;
|
|
||||||
document.getElementById("lora.spreadingFactor").value = sf;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const form = document.querySelector("form");
|
const form = document.querySelector("form");
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 711 KiB |
@@ -45,12 +45,13 @@ public:
|
|||||||
String overlay;
|
String overlay;
|
||||||
String symbol;
|
String symbol;
|
||||||
String path;
|
String path;
|
||||||
bool sendViaRF;
|
|
||||||
bool sendViaAPRSIS;
|
bool sendViaAPRSIS;
|
||||||
bool gpsActive;
|
bool sendViaRF;
|
||||||
bool gpsAmbiguity;
|
int beaconFreq;
|
||||||
bool statusActive;
|
bool statusActive;
|
||||||
String statusPacket;
|
String statusPacket;
|
||||||
|
bool gpsActive;
|
||||||
|
int ambiguityLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
class APRS_IS {
|
class APRS_IS {
|
||||||
@@ -72,13 +73,16 @@ public:
|
|||||||
|
|
||||||
class LoraModule {
|
class LoraModule {
|
||||||
public:
|
public:
|
||||||
long txFreq;
|
|
||||||
long rxFreq;
|
|
||||||
bool txActive;
|
|
||||||
bool rxActive;
|
bool rxActive;
|
||||||
int spreadingFactor;
|
long rxFreq;
|
||||||
long signalBandwidth;
|
int rxSpreadingFactor;
|
||||||
int codingRate4;
|
int rxCodingRate4;
|
||||||
|
long rxSignalBandwidth;
|
||||||
|
bool txActive;
|
||||||
|
long txFreq;
|
||||||
|
int txSpreadingFactor;
|
||||||
|
int txCodingRate4;
|
||||||
|
long txSignalBandwidth;
|
||||||
int power;
|
int power;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -98,6 +102,7 @@ public:
|
|||||||
int externalVoltagePin;
|
int externalVoltagePin;
|
||||||
bool monitorExternalVoltage;
|
bool monitorExternalVoltage;
|
||||||
float externalSleepVoltage;
|
float externalSleepVoltage;
|
||||||
|
bool useExternalI2CSensor;
|
||||||
float voltageDividerR1;
|
float voltageDividerR1;
|
||||||
float voltageDividerR2;
|
float voltageDividerR2;
|
||||||
bool sendVoltageAsTelemetry;
|
bool sendVoltageAsTelemetry;
|
||||||
@@ -123,6 +128,7 @@ public:
|
|||||||
bool enableServer;
|
bool enableServer;
|
||||||
bool enableSerial;
|
bool enableSerial;
|
||||||
bool acceptOwn;
|
bool acceptOwn;
|
||||||
|
bool aprsBridgeActive;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OTA {
|
class OTA {
|
||||||
@@ -140,6 +146,7 @@ public:
|
|||||||
|
|
||||||
class NTP {
|
class NTP {
|
||||||
public:
|
public:
|
||||||
|
String server;
|
||||||
float gmtCorrection;
|
float gmtCorrection;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -149,6 +156,17 @@ public:
|
|||||||
bool rfOnly;
|
bool rfOnly;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MQTT {
|
||||||
|
public:
|
||||||
|
bool active;
|
||||||
|
String server;
|
||||||
|
String topic;
|
||||||
|
String username;
|
||||||
|
String password;
|
||||||
|
int port;
|
||||||
|
bool beaconOverMqtt;
|
||||||
|
};
|
||||||
|
|
||||||
class Configuration {
|
class Configuration {
|
||||||
public:
|
public:
|
||||||
String callsign;
|
String callsign;
|
||||||
@@ -156,6 +174,7 @@ public:
|
|||||||
bool backupDigiMode;
|
bool backupDigiMode;
|
||||||
bool rebootMode;
|
bool rebootMode;
|
||||||
int rebootModeTime;
|
int rebootModeTime;
|
||||||
|
int startupDelay;
|
||||||
String personalNote;
|
String personalNote;
|
||||||
String blacklist;
|
String blacklist;
|
||||||
std::vector<WiFi_AP> wifiAPs;
|
std::vector<WiFi_AP> wifiAPs;
|
||||||
@@ -173,9 +192,10 @@ public:
|
|||||||
WEBADMIN webadmin;
|
WEBADMIN webadmin;
|
||||||
NTP ntp;
|
NTP ntp;
|
||||||
REMOTE_MANAGEMENT remoteManagement;
|
REMOTE_MANAGEMENT remoteManagement;
|
||||||
|
MQTT mqtt;
|
||||||
|
|
||||||
void init();
|
void setDefaultValues();
|
||||||
void writeFile();
|
bool writeFile();
|
||||||
Configuration();
|
Configuration();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
34
include/mqtt_utils.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
|
*
|
||||||
|
* This file is part of LoRa APRS iGate.
|
||||||
|
*
|
||||||
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MQTT_UTILS_H_
|
||||||
|
#define MQTT_UTILS_H_
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace MQTT_Utils {
|
||||||
|
|
||||||
|
void sendToMqtt(const String& packet);
|
||||||
|
void connect();
|
||||||
|
void loop();
|
||||||
|
void setup();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -23,12 +23,6 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
struct Packet25SegBuffer {
|
|
||||||
uint32_t receivedTime;
|
|
||||||
String station;
|
|
||||||
String payload;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LastHeardStation {
|
struct LastHeardStation {
|
||||||
uint32_t lastHeardTime;
|
uint32_t lastHeardTime;
|
||||||
String station;
|
String station;
|
||||||
@@ -47,7 +41,7 @@ namespace STATION_Utils {
|
|||||||
bool check25SegBuffer(const String& station, const String& textMessage);
|
bool check25SegBuffer(const String& station, const String& textMessage);
|
||||||
void processOutputPacketBufferUltraEcoMode();
|
void processOutputPacketBufferUltraEcoMode();
|
||||||
void processOutputPacketBuffer();
|
void processOutputPacketBuffer();
|
||||||
void addToOutputPacketBuffer(const String& packet);
|
void addToOutputPacketBuffer(const String& packet, bool flag = false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ namespace TNC_Utils {
|
|||||||
void setup();
|
void setup();
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
void sendToClients(const String& packet);
|
void sendToClients(const String& packet, bool stripBytes = false);
|
||||||
void sendToSerial(const String& packet);
|
void sendToSerial(const String& packet, bool stripBytes = false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace Utils {
|
|||||||
void processStatus();
|
void processStatus();
|
||||||
String getLocalIP();
|
String getLocalIP();
|
||||||
void setupDisplay();
|
void setupDisplay();
|
||||||
void activeStations();
|
void showActiveStations();
|
||||||
void checkBeaconInterval();
|
void checkBeaconInterval();
|
||||||
void checkDisplayInterval();
|
void checkDisplayInterval();
|
||||||
void validateFreqs();
|
void validateFreqs();
|
||||||
@@ -46,6 +46,7 @@ namespace Utils {
|
|||||||
void checkRebootTime();
|
void checkRebootTime();
|
||||||
void checkSleepByLowBatteryVoltage(uint8_t mode);
|
void checkSleepByLowBatteryVoltage(uint8_t mode);
|
||||||
bool checkValidCallsign(const String& callsign);
|
bool checkValidCallsign(const String& callsign);
|
||||||
|
void startupDelay();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#define WX_UTILS_H_
|
#define WX_UTILS_H_
|
||||||
|
|
||||||
#include <Adafruit_Sensor.h>
|
#include <Adafruit_Sensor.h>
|
||||||
|
#include <Adafruit_AHTX0.h>
|
||||||
#include <Adafruit_BME280.h>
|
#include <Adafruit_BME280.h>
|
||||||
#include <Adafruit_BMP280.h>
|
#include <Adafruit_BMP280.h>
|
||||||
#include <Adafruit_BME680.h>
|
#include <Adafruit_BME680.h>
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ ___________________________________________________________________*/
|
|||||||
#include "syslog_utils.h"
|
#include "syslog_utils.h"
|
||||||
#include "power_utils.h"
|
#include "power_utils.h"
|
||||||
#include "sleep_utils.h"
|
#include "sleep_utils.h"
|
||||||
|
#include "mqtt_utils.h"
|
||||||
#include "lora_utils.h"
|
#include "lora_utils.h"
|
||||||
#include "wifi_utils.h"
|
#include "wifi_utils.h"
|
||||||
#include "digi_utils.h"
|
#include "digi_utils.h"
|
||||||
@@ -66,9 +67,11 @@ ___________________________________________________________________*/
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
String versionDate = "2025-08-26";
|
String versionDate = "2025-12-28";
|
||||||
|
String versionNumber = "3.1.6.3";
|
||||||
Configuration Config;
|
Configuration Config;
|
||||||
WiFiClient espClient;
|
WiFiClient aprsIsClient;
|
||||||
|
WiFiClient mqttClient;
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
HardwareSerial gpsSerial(1);
|
HardwareSerial gpsSerial(1);
|
||||||
TinyGPSPlus gps;
|
TinyGPSPlus gps;
|
||||||
@@ -94,7 +97,6 @@ bool modemLoggedToAPRSIS = false;
|
|||||||
std::vector<ReceivedPacket> receivedPackets;
|
std::vector<ReceivedPacket> receivedPackets;
|
||||||
|
|
||||||
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
|
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
|
||||||
//#define STARTUP_DELAY 5 //min
|
|
||||||
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
@@ -105,12 +107,7 @@ void setup() {
|
|||||||
Utils::validateFreqs();
|
Utils::validateFreqs();
|
||||||
GPS_Utils::setup();
|
GPS_Utils::setup();
|
||||||
STATION_Utils::loadBlacklistAndManagers();
|
STATION_Utils::loadBlacklistAndManagers();
|
||||||
|
Utils::startupDelay();
|
||||||
#ifdef STARTUP_DELAY // (TEST) just to wait for WiFi init of Routers
|
|
||||||
displayShow("", " STARTUP DELAY ...", "", "", 0);
|
|
||||||
delay(STARTUP_DELAY * 60 * 1000);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SLEEP_Utils::setup();
|
SLEEP_Utils::setup();
|
||||||
WIFI_Utils::setup();
|
WIFI_Utils::setup();
|
||||||
NTP_Utils::setup();
|
NTP_Utils::setup();
|
||||||
@@ -118,6 +115,7 @@ void setup() {
|
|||||||
WX_Utils::setup();
|
WX_Utils::setup();
|
||||||
WEB_Utils::setup();
|
WEB_Utils::setup();
|
||||||
TNC_Utils::setup();
|
TNC_Utils::setup();
|
||||||
|
MQTT_Utils::setup();
|
||||||
#ifdef HAS_A7670
|
#ifdef HAS_A7670
|
||||||
A7670_Utils::setup();
|
A7670_Utils::setup();
|
||||||
#endif
|
#endif
|
||||||
@@ -166,11 +164,13 @@ void loop() {
|
|||||||
if (Config.aprs_is.active && !modemLoggedToAPRSIS) A7670_Utils::APRS_IS_connect();
|
if (Config.aprs_is.active && !modemLoggedToAPRSIS) A7670_Utils::APRS_IS_connect();
|
||||||
#else
|
#else
|
||||||
WIFI_Utils::checkWiFi();
|
WIFI_Utils::checkWiFi();
|
||||||
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) APRS_IS_Utils::connect();
|
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !aprsIsClient.connected()) APRS_IS_Utils::connect();
|
||||||
|
if (Config.mqtt.active && (WiFi.status() == WL_CONNECTED) && !mqttClient.connected()) MQTT_Utils::connect();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NTP_Utils::update();
|
NTP_Utils::update();
|
||||||
TNC_Utils::loop();
|
TNC_Utils::loop();
|
||||||
|
MQTT_Utils::loop();
|
||||||
|
|
||||||
Utils::checkDisplayInterval();
|
Utils::checkDisplayInterval();
|
||||||
Utils::checkBeaconInterval();
|
Utils::checkBeaconInterval();
|
||||||
@@ -192,17 +192,12 @@ void loop() {
|
|||||||
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi
|
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.tnc.enableServer) { // If TNC server enabled
|
if (Config.tnc.enableServer) TNC_Utils::sendToClients(packet, true); // Send received packet to TNC KISS
|
||||||
TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS
|
if (Config.tnc.enableSerial) TNC_Utils::sendToSerial(packet, true); // Send received packet to Serial KISS
|
||||||
}
|
if (Config.mqtt.active) MQTT_Utils::sendToMqtt(packet); // Send received packet to MQTT
|
||||||
if (Config.tnc.enableSerial) { // If Serial KISS enabled
|
|
||||||
TNC_Utils::sendToSerial(packet); // Send received packet to Serial KISS
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.aprs_is.active) {
|
if (Config.aprs_is.active) APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS
|
||||||
APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS
|
|
||||||
}
|
|
||||||
|
|
||||||
STATION_Utils::processOutputPacketBuffer();
|
STATION_Utils::processOutputPacketBuffer();
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <APRSPacketLib.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "aprs_is_utils.h"
|
#include "aprs_is_utils.h"
|
||||||
@@ -25,12 +26,13 @@
|
|||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
#include "A7670_utils.h"
|
#include "A7670_utils.h"
|
||||||
#include "digi_utils.h"
|
#include "digi_utils.h"
|
||||||
|
#include "tnc_utils.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern WiFiClient espClient;
|
extern WiFiClient aprsIsClient;
|
||||||
extern uint32_t lastScreenOn;
|
extern uint32_t lastScreenOn;
|
||||||
extern String firstLine;
|
extern String firstLine;
|
||||||
extern String secondLine;
|
extern String secondLine;
|
||||||
@@ -41,6 +43,7 @@ extern String sixthLine;
|
|||||||
extern String seventhLine;
|
extern String seventhLine;
|
||||||
extern bool modemLoggedToAPRSIS;
|
extern bool modemLoggedToAPRSIS;
|
||||||
extern bool backUpDigiMode;
|
extern bool backUpDigiMode;
|
||||||
|
extern String versionNumber;
|
||||||
|
|
||||||
uint32_t lastRxTime = millis();
|
uint32_t lastRxTime = millis();
|
||||||
bool passcodeValid = false;
|
bool passcodeValid = false;
|
||||||
@@ -53,17 +56,17 @@ bool passcodeValid = false;
|
|||||||
namespace APRS_IS_Utils {
|
namespace APRS_IS_Utils {
|
||||||
|
|
||||||
void upload(const String& line) {
|
void upload(const String& line) {
|
||||||
espClient.print(line + "\r\n");
|
aprsIsClient.print(line + "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect() {
|
void connect() {
|
||||||
Serial.print("Connecting to APRS-IS ... ");
|
Serial.print("Connecting to APRS-IS ... ");
|
||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
while (!espClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) {
|
while (!aprsIsClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) {
|
||||||
Serial.println("Didn't connect with server...");
|
Serial.println("Didn't connect with server...");
|
||||||
delay(1000);
|
delay(1000);
|
||||||
espClient.stop();
|
aprsIsClient.stop();
|
||||||
espClient.flush();
|
aprsIsClient.flush();
|
||||||
Serial.println("Run client.stop");
|
Serial.println("Run client.stop");
|
||||||
Serial.println("Trying to connect with Server: " + String(Config.aprs_is.server) + " AprsServerPort: " + String(Config.aprs_is.port));
|
Serial.println("Trying to connect with Server: " + String(Config.aprs_is.server) + " AprsServerPort: " + String(Config.aprs_is.port));
|
||||||
count++;
|
count++;
|
||||||
@@ -78,7 +81,9 @@ namespace APRS_IS_Utils {
|
|||||||
aprsAuth += Config.callsign;
|
aprsAuth += Config.callsign;
|
||||||
aprsAuth += " pass ";
|
aprsAuth += " pass ";
|
||||||
aprsAuth += Config.aprs_is.passcode;
|
aprsAuth += Config.aprs_is.passcode;
|
||||||
aprsAuth += " vers CA2RXU_iGate 3.0 filter ";
|
aprsAuth += " vers CA2RXUiGate ";
|
||||||
|
aprsAuth += versionNumber;
|
||||||
|
aprsAuth += " filter ";
|
||||||
aprsAuth += Config.aprs_is.filter;
|
aprsAuth += Config.aprs_is.filter;
|
||||||
upload(aprsAuth);
|
upload(aprsAuth);
|
||||||
}
|
}
|
||||||
@@ -110,7 +115,7 @@ namespace APRS_IS_Utils {
|
|||||||
aprsisState = "--";
|
aprsisState = "--";
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (espClient.connected()) {
|
if (aprsIsClient.connected()) {
|
||||||
aprsisState = "OK";
|
aprsisState = "OK";
|
||||||
} else {
|
} else {
|
||||||
aprsisState = "--";
|
aprsisState = "--";
|
||||||
@@ -192,7 +197,7 @@ namespace APRS_IS_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void processLoRaPacket(const String& packet) {
|
void processLoRaPacket(const String& packet) {
|
||||||
if (passcodeValid && (espClient.connected() || modemLoggedToAPRSIS)) {
|
if (passcodeValid && (aprsIsClient.connected() || modemLoggedToAPRSIS)) {
|
||||||
if (packet.indexOf("NOGATE") == -1 && packet.indexOf("RFONLY") == -1) {
|
if (packet.indexOf("NOGATE") == -1 && packet.indexOf("RFONLY") == -1) {
|
||||||
int firstColonIndex = packet.indexOf(":");
|
int firstColonIndex = packet.indexOf(":");
|
||||||
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) {
|
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) {
|
||||||
@@ -232,12 +237,7 @@ namespace APRS_IS_Utils {
|
|||||||
String buildPacketToTx(const String& aprsisPacket, uint8_t packetType) {
|
String buildPacketToTx(const String& aprsisPacket, uint8_t packetType) {
|
||||||
String packet = aprsisPacket;
|
String packet = aprsisPacket;
|
||||||
packet.trim();
|
packet.trim();
|
||||||
String outputPacket = Config.callsign;
|
String outputPacket = APRSPacketLib::generateBasePacket(Config.callsign, "APLRG1", Config.beacon.path);
|
||||||
outputPacket += ">APLRG1";
|
|
||||||
if (Config.beacon.path != "") {
|
|
||||||
outputPacket += ",";
|
|
||||||
outputPacket += Config.beacon.path;
|
|
||||||
}
|
|
||||||
outputPacket += ":}";
|
outputPacket += ":}";
|
||||||
outputPacket += packet.substring(0, packet.indexOf(",")); // Callsign>Tocall
|
outputPacket += packet.substring(0, packet.indexOf(",")); // Callsign>Tocall
|
||||||
outputPacket.concat(",TCPIP,");
|
outputPacket.concat(",TCPIP,");
|
||||||
@@ -278,8 +278,9 @@ namespace APRS_IS_Utils {
|
|||||||
if (!passcodeValid && packet.indexOf(Config.callsign) != -1) {
|
if (!passcodeValid && packet.indexOf(Config.callsign) != -1) {
|
||||||
if (packet.indexOf("unverified") != -1 ) {
|
if (packet.indexOf("unverified") != -1 ) {
|
||||||
Serial.println("\n****APRS PASSCODE NOT VALID****\n");
|
Serial.println("\n****APRS PASSCODE NOT VALID****\n");
|
||||||
displayShow(firstLine, "", " APRS PASSCODE", " NOT VALID !!!", "", "", "", 0);
|
displayShow(firstLine, "", " APRS PASSCODE", " NOT VALID !!!", "", "", "", 3000);
|
||||||
while (1) {};
|
aprsIsClient.stop();
|
||||||
|
Config.aprs_is.active = false;
|
||||||
} else if (packet.indexOf("verified") != -1 ) {
|
} else if (packet.indexOf("verified") != -1 ) {
|
||||||
passcodeValid = true;
|
passcodeValid = true;
|
||||||
}
|
}
|
||||||
@@ -364,6 +365,10 @@ namespace APRS_IS_Utils {
|
|||||||
Serial.println(" ---> Rejected (Time): No Tx");
|
Serial.println(" ---> Rejected (Time): No Tx");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (Config.tnc.aprsBridgeActive) {
|
||||||
|
if (Config.tnc.enableServer) TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS
|
||||||
|
if (Config.tnc.enableSerial) TNC_Utils::sendToSerial(packet); // Send received packet to Serial KISS
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,9 +376,9 @@ namespace APRS_IS_Utils {
|
|||||||
#ifdef HAS_A7670
|
#ifdef HAS_A7670
|
||||||
A7670_Utils::listenAPRSIS();
|
A7670_Utils::listenAPRSIS();
|
||||||
#else
|
#else
|
||||||
if (espClient.connected()) {
|
if (aprsIsClient.connected()) {
|
||||||
if (espClient.available()) {
|
if (aprsIsClient.available()) {
|
||||||
String aprsisPacket = espClient.readStringUntil('\r');
|
String aprsisPacket = aprsIsClient.readStringUntil('\r');
|
||||||
aprsisPacket.trim(); // Serial.println(aprsisPacket);
|
aprsisPacket.trim(); // Serial.println(aprsisPacket);
|
||||||
processAPRSISPacket(aprsisPacket);
|
processAPRSISPacket(aprsisPacket);
|
||||||
lastRxTime = millis();
|
lastRxTime = millis();
|
||||||
@@ -383,7 +388,7 @@ namespace APRS_IS_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void firstConnection() {
|
void firstConnection() {
|
||||||
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) {
|
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !aprsIsClient.connected()) {
|
||||||
connect();
|
connect();
|
||||||
while (!passcodeValid) {
|
while (!passcodeValid) {
|
||||||
listenAPRSIS();
|
listenAPRSIS();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Adafruit_INA219.h>
|
||||||
#include "battery_utils.h"
|
#include "battery_utils.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "board_pinout.h"
|
#include "board_pinout.h"
|
||||||
@@ -37,6 +37,10 @@ float multiplyCorrection = 0.035;
|
|||||||
|
|
||||||
float voltageDividerTransformation = 0.0;
|
float voltageDividerTransformation = 0.0;
|
||||||
|
|
||||||
|
uint8_t externalI2CSensorAddress = 0x00;
|
||||||
|
int externalI2CSensorType = 0; // 0 = None | 1 = INA219
|
||||||
|
|
||||||
|
Adafruit_INA219 ina219;
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAS_ADC_CALIBRATION
|
#ifdef HAS_ADC_CALIBRATION
|
||||||
@@ -98,6 +102,30 @@ namespace BATTERY_Utils {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getI2CVoltageSensorAddress() {
|
||||||
|
uint8_t err, addr;
|
||||||
|
for(addr = 1; addr < 0x7F; addr++) {
|
||||||
|
#if defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
|
||||||
|
Wire1.beginTransmission(addr);
|
||||||
|
err = Wire1.endTransmission();
|
||||||
|
#else
|
||||||
|
Wire.beginTransmission(addr);
|
||||||
|
err = Wire.endTransmission();
|
||||||
|
#endif
|
||||||
|
delay(5);
|
||||||
|
if (err == 0) {
|
||||||
|
if (addr == 0x40) { // INA219
|
||||||
|
externalI2CSensorAddress = addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool detectINA219(uint8_t addr) {
|
||||||
|
ina219 = Adafruit_INA219(addr);
|
||||||
|
return ina219.begin();
|
||||||
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
if ((Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) && Config.battery.voltageDividerR2 != 0) voltageDividerTransformation = (Config.battery.voltageDividerR1 + Config.battery.voltageDividerR2) / Config.battery.voltageDividerR2;
|
if ((Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) && Config.battery.voltageDividerR2 != 0) voltageDividerTransformation = (Config.battery.voltageDividerR1 + Config.battery.voltageDividerR2) / Config.battery.voltageDividerR2;
|
||||||
|
|
||||||
@@ -107,6 +135,14 @@ namespace BATTERY_Utils {
|
|||||||
adcCalibration();
|
adcCalibration();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
getI2CVoltageSensorAddress();
|
||||||
|
if (externalI2CSensorAddress != 0x00) {
|
||||||
|
if (detectINA219(externalI2CSensorAddress)) {
|
||||||
|
Serial.println("INA219 sensor found");
|
||||||
|
externalI2CSensorType = 1; // INA219
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float checkInternalVoltage() {
|
float checkInternalVoltage() {
|
||||||
@@ -147,7 +183,7 @@ namespace BATTERY_Utils {
|
|||||||
#ifdef ADC_CTRL
|
#ifdef ADC_CTRL
|
||||||
POWER_Utils::adc_ctrl_OFF();
|
POWER_Utils::adc_ctrl_OFF();
|
||||||
|
|
||||||
#ifdef HELTEC_WP
|
#ifdef HELTEC_WP_V1
|
||||||
double inputDivider = (1.0 / (10.0 + 10.0)) * 10.0; // The voltage divider is a 10k + 10k resistor in series
|
double inputDivider = (1.0 / (10.0 + 10.0)) * 10.0; // The voltage divider is a 10k + 10k resistor in series
|
||||||
#else
|
#else
|
||||||
double inputDivider = (1.0 / (390.0 + 100.0)) * 100.0; // The voltage divider is a 390k + 100k resistor in series, 100k on the low side.
|
double inputDivider = (1.0 / (390.0 + 100.0)) * 100.0; // The voltage divider is a 390k + 100k resistor in series, 100k on the low side.
|
||||||
@@ -177,6 +213,7 @@ namespace BATTERY_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float checkExternalVoltage() {
|
float checkExternalVoltage() {
|
||||||
|
if (externalI2CSensorType == 0) {
|
||||||
int sample;
|
int sample;
|
||||||
int sampleSum = 0;
|
int sampleSum = 0;
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
@@ -196,18 +233,29 @@ namespace BATTERY_Utils {
|
|||||||
float extVoltage;
|
float extVoltage;
|
||||||
#ifdef HAS_ADC_CALIBRATION
|
#ifdef HAS_ADC_CALIBRATION
|
||||||
if (calibrationEnable) {
|
if (calibrationEnable) {
|
||||||
extVoltage = esp_adc_cal_raw_to_voltage(sampleSum / 100, &adc_chars) * voltageDividerTransformation; // in mV
|
extVoltage = esp_adc_cal_raw_to_voltage(sampleSum / 100.0, &adc_chars) * voltageDividerTransformation; // in mV
|
||||||
extVoltage /= 1000;
|
extVoltage /= 1000.0;
|
||||||
} else {
|
} else {
|
||||||
extVoltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection;
|
extVoltage = ((((sampleSum/100.0)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
extVoltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection;
|
extVoltage = ((((sampleSum/100.0)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return extVoltage; // raw voltage without mapping
|
return extVoltage; // raw voltage without mapping
|
||||||
|
|
||||||
// return mapVoltage(voltage, 5.05, 6.32, 4.5, 5.5); // mapped voltage
|
// return mapVoltage(voltage, 5.05, 6.32, 4.5, 5.5); // mapped voltage
|
||||||
|
} else if (externalI2CSensorType == 1) { // INA219
|
||||||
|
int sampleSum = 0;
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
sampleSum += ina219.getBusVoltage_V() * 1000.0;
|
||||||
|
delayMicroseconds(50);
|
||||||
|
}
|
||||||
|
float extVoltage = sampleSum/100.0;
|
||||||
|
return extVoltage/1000.0;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void startupBatteryHealth() {
|
void startupBatteryHealth() {
|
||||||
@@ -216,7 +264,7 @@ namespace BATTERY_Utils {
|
|||||||
shouldSleepLowVoltage = true;
|
shouldSleepLowVoltage = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifndef HELTEC_WP
|
#ifndef HELTEC_WP_V1
|
||||||
if (Config.battery.monitorExternalVoltage && checkExternalVoltage() < Config.battery.externalSleepVoltage + 0.1) {
|
if (Config.battery.monitorExternalVoltage && checkExternalVoltage() < Config.battery.externalSleepVoltage + 0.1) {
|
||||||
shouldSleepLowVoltage = true;
|
shouldSleepLowVoltage = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,18 @@
|
|||||||
bool shouldSleepStop = true;
|
bool shouldSleepStop = true;
|
||||||
|
|
||||||
|
|
||||||
void Configuration::writeFile() {
|
bool Configuration::writeFile() {
|
||||||
Serial.println("Saving config...");
|
Serial.println("Saving configuration...");
|
||||||
|
|
||||||
StaticJsonDocument<2560> data;
|
StaticJsonDocument<3584> data;
|
||||||
File configFile = SPIFFS.open("/igate_conf.json", "w");
|
File configFile = SPIFFS.open("/igate_conf.json", "w");
|
||||||
|
|
||||||
|
if (!configFile) {
|
||||||
|
Serial.println("Error: Could not open config file for writing");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
|
||||||
if (wifiAPs[0].ssid != "") { // We don't want to save Auto AP empty SSID
|
if (wifiAPs[0].ssid != "") { // We don't want to save Auto AP empty SSID
|
||||||
for (int i = 0; i < wifiAPs.size(); i++) {
|
for (int i = 0; i < wifiAPs.size(); i++) {
|
||||||
data["wifi"]["AP"][i]["ssid"] = wifiAPs[i].ssid;
|
data["wifi"]["AP"][i]["ssid"] = wifiAPs[i].ssid;
|
||||||
@@ -39,9 +45,13 @@ void Configuration::writeFile() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data["other"]["startupDelay"] = startupDelay;
|
||||||
|
|
||||||
data["wifi"]["autoAP"]["password"] = wifiAutoAP.password;
|
data["wifi"]["autoAP"]["password"] = wifiAutoAP.password;
|
||||||
data["wifi"]["autoAP"]["timeout"] = wifiAutoAP.timeout;
|
data["wifi"]["autoAP"]["timeout"] = wifiAutoAP.timeout;
|
||||||
|
|
||||||
|
callsign.trim();
|
||||||
|
callsign.toUpperCase();
|
||||||
data["callsign"] = callsign;
|
data["callsign"] = callsign;
|
||||||
|
|
||||||
data["aprs_is"]["active"] = aprs_is.active;
|
data["aprs_is"]["active"] = aprs_is.active;
|
||||||
@@ -58,15 +68,21 @@ void Configuration::writeFile() {
|
|||||||
data["beacon"]["longitude"] = beacon.longitude;
|
data["beacon"]["longitude"] = beacon.longitude;
|
||||||
data["beacon"]["overlay"] = beacon.overlay;
|
data["beacon"]["overlay"] = beacon.overlay;
|
||||||
data["beacon"]["symbol"] = beacon.symbol;
|
data["beacon"]["symbol"] = beacon.symbol;
|
||||||
|
data["beacon"]["path"] = beacon.path;
|
||||||
|
|
||||||
data["beacon"]["sendViaAPRSIS"] = beacon.sendViaAPRSIS;
|
data["beacon"]["sendViaAPRSIS"] = beacon.sendViaAPRSIS;
|
||||||
data["beacon"]["sendViaRF"] = beacon.sendViaRF;
|
data["beacon"]["sendViaRF"] = beacon.sendViaRF;
|
||||||
data["beacon"]["path"] = beacon.path;
|
data["beacon"]["beaconFreq"] = beacon.beaconFreq;
|
||||||
|
|
||||||
data["beacon"]["statusActive"] = beacon.statusActive;
|
data["beacon"]["statusActive"] = beacon.statusActive;
|
||||||
data["beacon"]["statusPacket"] = beacon.statusPacket;
|
data["beacon"]["statusPacket"] = beacon.statusPacket;
|
||||||
|
|
||||||
data["beacon"]["gpsActive"] = beacon.gpsActive;
|
data["beacon"]["gpsActive"] = beacon.gpsActive;
|
||||||
data["beacon"]["gpsAmbiguity"] = beacon.gpsAmbiguity;
|
data["beacon"]["ambiguityLevel"] = beacon.ambiguityLevel;
|
||||||
|
|
||||||
|
data["personalNote"] = personalNote;
|
||||||
|
|
||||||
|
data["blacklist"] = blacklist;
|
||||||
|
|
||||||
data["digi"]["mode"] = digi.mode;
|
data["digi"]["mode"] = digi.mode;
|
||||||
data["digi"]["ecoMode"] = digi.ecoMode;
|
data["digi"]["ecoMode"] = digi.ecoMode;
|
||||||
@@ -74,14 +90,17 @@ void Configuration::writeFile() {
|
|||||||
if (digi.ecoMode == 1) data["digi"]["ecoMode"] = 2;
|
if (digi.ecoMode == 1) data["digi"]["ecoMode"] = 2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data["lora"]["rxFreq"] = loramodule.rxFreq;
|
|
||||||
data["lora"]["txFreq"] = loramodule.txFreq;
|
|
||||||
data["lora"]["spreadingFactor"] = loramodule.spreadingFactor;
|
|
||||||
data["lora"]["signalBandwidth"] = loramodule.signalBandwidth;
|
|
||||||
data["lora"]["codingRate4"] = loramodule.codingRate4;
|
|
||||||
data["lora"]["power"] = loramodule.power;
|
|
||||||
data["lora"]["txActive"] = loramodule.txActive;
|
|
||||||
data["lora"]["rxActive"] = loramodule.rxActive;
|
data["lora"]["rxActive"] = loramodule.rxActive;
|
||||||
|
data["lora"]["rxFreq"] = loramodule.rxFreq;
|
||||||
|
data["lora"]["rxSpreadingFactor"] = loramodule.rxSpreadingFactor;
|
||||||
|
data["lora"]["rxCodingRate4"] = loramodule.rxCodingRate4;
|
||||||
|
data["lora"]["rxSignalBandwidth"] = loramodule.rxSignalBandwidth;
|
||||||
|
data["lora"]["txActive"] = loramodule.txActive;
|
||||||
|
data["lora"]["txFreq"] = loramodule.txFreq;
|
||||||
|
data["lora"]["txSpreadingFactor"] = loramodule.txSpreadingFactor;
|
||||||
|
data["lora"]["txCodingRate4"] = loramodule.txCodingRate4;
|
||||||
|
data["lora"]["txSignalBandwidth"] = loramodule.txSignalBandwidth;
|
||||||
|
data["lora"]["power"] = loramodule.power;
|
||||||
|
|
||||||
data["display"]["alwaysOn"] = display.alwaysOn;
|
data["display"]["alwaysOn"] = display.alwaysOn;
|
||||||
data["display"]["timeout"] = display.timeout;
|
data["display"]["timeout"] = display.timeout;
|
||||||
@@ -92,11 +111,12 @@ void Configuration::writeFile() {
|
|||||||
data["battery"]["internalSleepVoltage"] = battery.internalSleepVoltage;
|
data["battery"]["internalSleepVoltage"] = battery.internalSleepVoltage;
|
||||||
|
|
||||||
data["battery"]["sendExternalVoltage"] = battery.sendExternalVoltage;
|
data["battery"]["sendExternalVoltage"] = battery.sendExternalVoltage;
|
||||||
data["battery"]["externalVoltagePin"] = battery.externalVoltagePin;
|
|
||||||
data["battery"]["monitorExternalVoltage"] = battery.monitorExternalVoltage;
|
data["battery"]["monitorExternalVoltage"] = battery.monitorExternalVoltage;
|
||||||
data["battery"]["externalSleepVoltage"] = battery.externalSleepVoltage;
|
data["battery"]["externalSleepVoltage"] = battery.externalSleepVoltage;
|
||||||
|
data["battery"]["useExternalI2CSensor"] = battery.useExternalI2CSensor;
|
||||||
data["battery"]["voltageDividerR1"] = battery.voltageDividerR1;
|
data["battery"]["voltageDividerR1"] = battery.voltageDividerR1;
|
||||||
data["battery"]["voltageDividerR2"] = battery.voltageDividerR2;
|
data["battery"]["voltageDividerR2"] = battery.voltageDividerR2;
|
||||||
|
data["battery"]["externalVoltagePin"] = battery.externalVoltagePin;
|
||||||
|
|
||||||
data["battery"]["sendVoltageAsTelemetry"] = battery.sendVoltageAsTelemetry;
|
data["battery"]["sendVoltageAsTelemetry"] = battery.sendVoltageAsTelemetry;
|
||||||
|
|
||||||
@@ -112,45 +132,53 @@ void Configuration::writeFile() {
|
|||||||
data["tnc"]["enableServer"] = tnc.enableServer;
|
data["tnc"]["enableServer"] = tnc.enableServer;
|
||||||
data["tnc"]["enableSerial"] = tnc.enableSerial;
|
data["tnc"]["enableSerial"] = tnc.enableSerial;
|
||||||
data["tnc"]["acceptOwn"] = tnc.acceptOwn;
|
data["tnc"]["acceptOwn"] = tnc.acceptOwn;
|
||||||
|
data["tnc"]["aprsBridgeActive"] = tnc.aprsBridgeActive;
|
||||||
|
|
||||||
data["other"]["rebootMode"] = rebootMode;
|
data["mqtt"]["active"] = mqtt.active;
|
||||||
data["other"]["rebootModeTime"] = rebootModeTime;
|
data["mqtt"]["server"] = mqtt.server;
|
||||||
|
data["mqtt"]["topic"] = mqtt.topic;
|
||||||
|
data["mqtt"]["username"] = mqtt.username;
|
||||||
|
data["mqtt"]["password"] = mqtt.password;
|
||||||
|
data["mqtt"]["port"] = mqtt.port;
|
||||||
|
data["mqtt"]["beaconOverMqtt"] = mqtt.beaconOverMqtt;
|
||||||
|
|
||||||
data["ota"]["username"] = ota.username;
|
data["ota"]["username"] = ota.username;
|
||||||
data["ota"]["password"] = ota.password;
|
data["ota"]["password"] = ota.password;
|
||||||
|
|
||||||
data["other"]["rememberStationTime"] = rememberStationTime;
|
|
||||||
|
|
||||||
data["other"]["backupDigiMode"] = backupDigiMode;
|
|
||||||
|
|
||||||
data["personalNote"] = personalNote;
|
|
||||||
|
|
||||||
data["blacklist"] = blacklist;
|
|
||||||
|
|
||||||
data["webadmin"]["active"] = webadmin.active;
|
data["webadmin"]["active"] = webadmin.active;
|
||||||
data["webadmin"]["username"] = webadmin.username;
|
data["webadmin"]["username"] = webadmin.username;
|
||||||
data["webadmin"]["password"] = webadmin.password;
|
data["webadmin"]["password"] = webadmin.password;
|
||||||
|
|
||||||
data["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
|
|
||||||
|
|
||||||
data["remoteManagement"]["managers"] = remoteManagement.managers;
|
data["remoteManagement"]["managers"] = remoteManagement.managers;
|
||||||
data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly;
|
data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly;
|
||||||
|
|
||||||
|
data["ntp"]["server"] = ntp.server;
|
||||||
|
data["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
|
||||||
|
|
||||||
|
data["other"]["rebootMode"] = rebootMode;
|
||||||
|
data["other"]["rebootModeTime"] = rebootModeTime;
|
||||||
|
|
||||||
|
data["other"]["rememberStationTime"] = rememberStationTime;
|
||||||
|
|
||||||
|
data["other"]["backupDigiMode"] = backupDigiMode;
|
||||||
|
|
||||||
serializeJson(data, configFile);
|
serializeJson(data, configFile);
|
||||||
|
|
||||||
configFile.close();
|
configFile.close();
|
||||||
|
return true;
|
||||||
Serial.println("Config saved");
|
} catch (...) {
|
||||||
delay(200);
|
Serial.println("Error: Exception occurred while saving config");
|
||||||
|
configFile.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Configuration::readFile() {
|
bool Configuration::readFile() {
|
||||||
Serial.println("Reading config..");
|
Serial.println("Reading config..");
|
||||||
|
|
||||||
File configFile = SPIFFS.open("/igate_conf.json", "r");
|
File configFile = SPIFFS.open("/igate_conf.json", "r");
|
||||||
|
|
||||||
if (configFile) {
|
if (configFile) {
|
||||||
StaticJsonDocument<2560> data;
|
bool needsRewrite = false;
|
||||||
|
StaticJsonDocument<3584> data;
|
||||||
|
|
||||||
DeserializationError error = deserializeJson(data, configFile);
|
DeserializationError error = deserializeJson(data, configFile);
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -166,12 +194,46 @@ bool Configuration::readFile() {
|
|||||||
wifiAPs.push_back(wifiap);
|
wifiAPs.push_back(wifiap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data["other"].containsKey("startupDelay")) needsRewrite = true;
|
||||||
|
startupDelay = data["other"]["startupDelay"] | 0;
|
||||||
|
|
||||||
|
if (!data["wifi"]["autoAP"].containsKey("password") ||
|
||||||
|
!data["wifi"]["autoAP"].containsKey("timeout")) needsRewrite = true;
|
||||||
wifiAutoAP.password = data["wifi"]["autoAP"]["password"] | "1234567890";
|
wifiAutoAP.password = data["wifi"]["autoAP"]["password"] | "1234567890";
|
||||||
wifiAutoAP.timeout = data["wifi"]["autoAP"]["timeout"] | 10;
|
wifiAutoAP.timeout = data["wifi"]["autoAP"]["timeout"] | 10;
|
||||||
|
|
||||||
|
if (!data.containsKey("callsign")) needsRewrite = true;
|
||||||
callsign = data["callsign"] | "NOCALL-10";
|
callsign = data["callsign"] | "NOCALL-10";
|
||||||
rememberStationTime = data["other"]["rememberStationTime"] | 30;
|
|
||||||
|
|
||||||
|
if (!data["aprs_is"].containsKey("active") ||
|
||||||
|
!data["aprs_is"].containsKey("passcode") ||
|
||||||
|
!data["aprs_is"].containsKey("server") ||
|
||||||
|
!data["aprs_is"].containsKey("port") ||
|
||||||
|
!data["aprs_is"].containsKey("filter") ||
|
||||||
|
!data["aprs_is"].containsKey("messagesToRF") ||
|
||||||
|
!data["aprs_is"].containsKey("objectsToRF")) needsRewrite = true;
|
||||||
|
aprs_is.active = data["aprs_is"]["active"] | false;
|
||||||
|
aprs_is.passcode = data["aprs_is"]["passcode"] | "XYZWV";
|
||||||
|
aprs_is.server = data["aprs_is"]["server"] | "rotate.aprs2.net";
|
||||||
|
aprs_is.port = data["aprs_is"]["port"] | 14580;
|
||||||
|
aprs_is.filter = data["aprs_is"]["filter"] | "m/10";
|
||||||
|
aprs_is.messagesToRF = data["aprs_is"]["messagesToRF"] | false;
|
||||||
|
aprs_is.objectsToRF = data["aprs_is"]["objectsToRF"] | false;
|
||||||
|
|
||||||
|
if (!data["beacon"].containsKey("latitude") ||
|
||||||
|
!data["beacon"].containsKey("longitude") ||
|
||||||
|
!data["beacon"].containsKey("comment") ||
|
||||||
|
!data["beacon"].containsKey("interval") ||
|
||||||
|
!data["beacon"].containsKey("overlay") ||
|
||||||
|
!data["beacon"].containsKey("symbol") ||
|
||||||
|
!data["beacon"].containsKey("path") ||
|
||||||
|
!data["beacon"].containsKey("sendViaAPRSIS") ||
|
||||||
|
!data["beacon"].containsKey("sendViaRF") ||
|
||||||
|
!data["beacon"].containsKey("beaconFreq") ||
|
||||||
|
!data["beacon"].containsKey("statusActive") ||
|
||||||
|
!data["beacon"].containsKey("statusPacket") ||
|
||||||
|
!data["beacon"].containsKey("gpsActive") ||
|
||||||
|
!data["beacon"].containsKey("ambiguityLevel")) needsRewrite = true;
|
||||||
beacon.latitude = data["beacon"]["latitude"] | 0.0;
|
beacon.latitude = data["beacon"]["latitude"] | 0.0;
|
||||||
beacon.longitude = data["beacon"]["longitude"] | 0.0;
|
beacon.longitude = data["beacon"]["longitude"] | 0.0;
|
||||||
beacon.comment = data["beacon"]["comment"] | "LoRa APRS";
|
beacon.comment = data["beacon"]["comment"] | "LoRa APRS";
|
||||||
@@ -181,88 +243,156 @@ bool Configuration::readFile() {
|
|||||||
beacon.path = data["beacon"]["path"] | "WIDE1-1";
|
beacon.path = data["beacon"]["path"] | "WIDE1-1";
|
||||||
beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"] | false;
|
beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"] | false;
|
||||||
beacon.sendViaRF = data["beacon"]["sendViaRF"] | false;
|
beacon.sendViaRF = data["beacon"]["sendViaRF"] | false;
|
||||||
|
beacon.beaconFreq = data["beacon"]["beaconFreq"] | 1;
|
||||||
beacon.statusActive = data["beacon"]["statusActive"] | false;
|
beacon.statusActive = data["beacon"]["statusActive"] | false;
|
||||||
beacon.statusPacket = data["beacon"]["statusPacket"] | "";
|
beacon.statusPacket = data["beacon"]["statusPacket"] | "";
|
||||||
|
|
||||||
beacon.gpsActive = data["beacon"]["gpsActive"] | false;
|
beacon.gpsActive = data["beacon"]["gpsActive"] | false;
|
||||||
beacon.gpsAmbiguity = data["beacon"]["gpsAmbiguity"] | false;
|
beacon.ambiguityLevel = data["beacon"]["ambiguityLevel"] | 0;
|
||||||
|
|
||||||
aprs_is.active = data["aprs_is"]["active"] | false;
|
if (!data.containsKey("personalNote")) needsRewrite = true;
|
||||||
aprs_is.passcode = data["aprs_is"]["passcode"] | "XYZWV";
|
personalNote = data["personalNote"] | "personal note here";
|
||||||
aprs_is.server = data["aprs_is"]["server"] | "rotate.aprs2.net";
|
|
||||||
aprs_is.port = data["aprs_is"]["port"] | 14580;
|
|
||||||
aprs_is.filter = data["aprs_is"]["filter"] | "m/10";
|
|
||||||
aprs_is.messagesToRF = data["aprs_is"]["messagesToRF"] | false;
|
|
||||||
aprs_is.objectsToRF = data["aprs_is"]["objectsToRF"] | false;
|
|
||||||
|
|
||||||
|
if (!data.containsKey("blacklist")) needsRewrite = true;
|
||||||
|
blacklist = data["blacklist"] | "station callsign";
|
||||||
|
|
||||||
|
if (!data["digi"].containsKey("mode") ||
|
||||||
|
!data["digi"].containsKey("ecoMode")) needsRewrite = true;
|
||||||
digi.mode = data["digi"]["mode"] | 0;
|
digi.mode = data["digi"]["mode"] | 0;
|
||||||
digi.ecoMode = data["digi"]["ecoMode"] | 0;
|
digi.ecoMode = data["digi"]["ecoMode"] | 0;
|
||||||
if (digi.ecoMode == 1) shouldSleepStop = false;
|
if (digi.ecoMode == 1) shouldSleepStop = false;
|
||||||
|
|
||||||
#if defined(HAS_A7670)
|
#if defined(HAS_A7670)
|
||||||
if (digi.ecoMode == 1) digi.ecoMode = 2;
|
if (digi.ecoMode == 1) digi.ecoMode = 2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
loramodule.txFreq = data["lora"]["txFreq"] | 433775000;
|
if (!data["lora"].containsKey("rxActive") ||
|
||||||
|
!data["lora"].containsKey("rxFreq") ||
|
||||||
|
!data["lora"].containsKey("rxSpreadingFactor") ||
|
||||||
|
!data["lora"].containsKey("rxCodingRate4") ||
|
||||||
|
!data["lora"].containsKey("rxSignalBandwidth") ||
|
||||||
|
!data["lora"].containsKey("txActive") ||
|
||||||
|
!data["lora"].containsKey("txFreq") ||
|
||||||
|
!data["lora"].containsKey("txSpreadingFactor") ||
|
||||||
|
!data["lora"].containsKey("txCodingRate4") ||
|
||||||
|
!data["lora"].containsKey("txSignalBandwidth") ||
|
||||||
|
!data["lora"].containsKey("power")) needsRewrite = true;
|
||||||
|
loramodule.rxActive = data["lora"]["rxActive"] | true;
|
||||||
loramodule.rxFreq = data["lora"]["rxFreq"] | 433775000;
|
loramodule.rxFreq = data["lora"]["rxFreq"] | 433775000;
|
||||||
loramodule.spreadingFactor = data["lora"]["spreadingFactor"] | 12;
|
loramodule.rxSpreadingFactor = data["lora"]["rxSpreadingFactor"] | 12;
|
||||||
loramodule.signalBandwidth = data["lora"]["signalBandwidth"] | 125000;
|
loramodule.rxCodingRate4 = data["lora"]["rxCodingRate4"] | 5;
|
||||||
loramodule.codingRate4 = data["lora"]["codingRate4"] | 5;
|
loramodule.rxSignalBandwidth = data["lora"]["rxSignalBandwidth"] | 125000;
|
||||||
loramodule.power = data["lora"]["power"] | 20;
|
|
||||||
loramodule.txActive = data["lora"]["txActive"] | false;
|
loramodule.txActive = data["lora"]["txActive"] | false;
|
||||||
loramodule.rxActive = data["lora"]["rxActive"] | false;
|
loramodule.txFreq = data["lora"]["txFreq"] | 433775000;
|
||||||
|
loramodule.txSpreadingFactor = data["lora"]["txSpreadingFactor"] | 12;
|
||||||
|
loramodule.txCodingRate4 = data["lora"]["txCodingRate4"] | 5;
|
||||||
|
loramodule.txSignalBandwidth = data["lora"]["txSignalBandwidth"] | 125000;
|
||||||
|
loramodule.power = data["lora"]["power"] | 20;
|
||||||
|
|
||||||
|
if (!data["display"].containsKey("alwaysOn") ||
|
||||||
|
!data["display"].containsKey("timeout") ||
|
||||||
|
!data["display"].containsKey("turn180")) needsRewrite = true;
|
||||||
|
#ifdef HAS_EPAPER
|
||||||
|
display.alwaysOn = true;
|
||||||
|
#else
|
||||||
display.alwaysOn = data["display"]["alwaysOn"] | true;
|
display.alwaysOn = data["display"]["alwaysOn"] | true;
|
||||||
|
#endif
|
||||||
display.timeout = data["display"]["timeout"] | 4;
|
display.timeout = data["display"]["timeout"] | 4;
|
||||||
display.turn180 = data["display"]["turn180"] | false;
|
display.turn180 = data["display"]["turn180"] | false;
|
||||||
|
|
||||||
|
if (!data["battery"].containsKey("sendInternalVoltage") ||
|
||||||
|
!data["battery"].containsKey("monitorInternalVoltage") ||
|
||||||
|
!data["battery"].containsKey("internalSleepVoltage") ||
|
||||||
|
!data["battery"].containsKey("sendExternalVoltage") ||
|
||||||
|
!data["battery"].containsKey("monitorExternalVoltage") ||
|
||||||
|
!data["battery"].containsKey("externalSleepVoltage") ||
|
||||||
|
!data["battery"].containsKey("useExternalI2CSensor") ||
|
||||||
|
!data["battery"].containsKey("voltageDividerR1") ||
|
||||||
|
!data["battery"].containsKey("voltageDividerR2") ||
|
||||||
|
!data["battery"].containsKey("externalVoltagePin") ||
|
||||||
|
!data["battery"].containsKey("sendVoltageAsTelemetry")) needsRewrite = true;
|
||||||
battery.sendInternalVoltage = data["battery"]["sendInternalVoltage"] | false;
|
battery.sendInternalVoltage = data["battery"]["sendInternalVoltage"] | false;
|
||||||
battery.monitorInternalVoltage = data["battery"]["monitorInternalVoltage"] | false;
|
battery.monitorInternalVoltage = data["battery"]["monitorInternalVoltage"] | false;
|
||||||
battery.internalSleepVoltage = data["battery"]["internalSleepVoltage"] | 2.9;
|
battery.internalSleepVoltage = data["battery"]["internalSleepVoltage"] | 2.9;
|
||||||
|
|
||||||
battery.sendExternalVoltage = data["battery"]["sendExternalVoltage"] | false;
|
battery.sendExternalVoltage = data["battery"]["sendExternalVoltage"] | false;
|
||||||
battery.externalVoltagePin = data["battery"]["externalVoltagePin"] | 34;
|
|
||||||
battery.monitorExternalVoltage = data["battery"]["monitorExternalVoltage"] | false;
|
battery.monitorExternalVoltage = data["battery"]["monitorExternalVoltage"] | false;
|
||||||
battery.externalSleepVoltage = data["battery"]["externalSleepVoltage"] | 10.9;
|
battery.externalSleepVoltage = data["battery"]["externalSleepVoltage"] | 10.9;
|
||||||
|
battery.useExternalI2CSensor = data["battery"]["useExternalI2CSensor"] | false;
|
||||||
battery.voltageDividerR1 = data["battery"]["voltageDividerR1"] | 100.0;
|
battery.voltageDividerR1 = data["battery"]["voltageDividerR1"] | 100.0;
|
||||||
battery.voltageDividerR2 = data["battery"]["voltageDividerR2"] | 27.0;
|
battery.voltageDividerR2 = data["battery"]["voltageDividerR2"] | 27.0;
|
||||||
|
battery.externalVoltagePin = data["battery"]["externalVoltagePin"] | 34;
|
||||||
battery.sendVoltageAsTelemetry = data["battery"]["sendVoltageAsTelemetry"] | false;
|
battery.sendVoltageAsTelemetry = data["battery"]["sendVoltageAsTelemetry"] | false;
|
||||||
|
|
||||||
|
if (!data["wxsensor"].containsKey("active") ||
|
||||||
|
!data["wxsensor"].containsKey("heightCorrection") ||
|
||||||
|
!data["wxsensor"].containsKey("temperatureCorrection")) needsRewrite = true;
|
||||||
wxsensor.active = data["wxsensor"]["active"] | false;
|
wxsensor.active = data["wxsensor"]["active"] | false;
|
||||||
wxsensor.heightCorrection = data["wxsensor"]["heightCorrection"] | 0;
|
wxsensor.heightCorrection = data["wxsensor"]["heightCorrection"] | 0;
|
||||||
wxsensor.temperatureCorrection = data["wxsensor"]["temperatureCorrection"] | 0.0;
|
wxsensor.temperatureCorrection = data["wxsensor"]["temperatureCorrection"] | 0.0;
|
||||||
|
|
||||||
|
if (!data["syslog"].containsKey("active") ||
|
||||||
|
!data["syslog"].containsKey("server") ||
|
||||||
|
!data["syslog"].containsKey("port") ||
|
||||||
|
!data["syslog"].containsKey("logBeaconOverTCPIP")) needsRewrite = true;
|
||||||
syslog.active = data["syslog"]["active"] | false;
|
syslog.active = data["syslog"]["active"] | false;
|
||||||
syslog.server = data["syslog"]["server"] | "lora.link9.net";
|
syslog.server = data["syslog"]["server"] | "lora.link9.net";
|
||||||
syslog.port = data["syslog"]["port"] | 1514;
|
syslog.port = data["syslog"]["port"] | 1514;
|
||||||
syslog.logBeaconOverTCPIP = data["syslog"]["logBeaconOverTCPIP"] | false;
|
syslog.logBeaconOverTCPIP = data["syslog"]["logBeaconOverTCPIP"] | false;
|
||||||
|
|
||||||
|
if (!data["tnc"].containsKey("enableServer") ||
|
||||||
|
!data["tnc"].containsKey("enableSerial") ||
|
||||||
|
!data["tnc"].containsKey("acceptOwn") ||
|
||||||
|
!data["tnc"].containsKey("aprsBridgeActive")) needsRewrite = true;
|
||||||
tnc.enableServer = data["tnc"]["enableServer"] | false;
|
tnc.enableServer = data["tnc"]["enableServer"] | false;
|
||||||
tnc.enableSerial = data["tnc"]["enableSerial"] | false;
|
tnc.enableSerial = data["tnc"]["enableSerial"] | false;
|
||||||
tnc.acceptOwn = data["tnc"]["acceptOwn"] | false;
|
tnc.acceptOwn = data["tnc"]["acceptOwn"] | false;
|
||||||
|
tnc.aprsBridgeActive = data["tnc"]["aprsBridgeActive"] | false;
|
||||||
|
|
||||||
|
if (!data["mqtt"].containsKey("active") ||
|
||||||
|
!data["mqtt"].containsKey("server") ||
|
||||||
|
!data["mqtt"].containsKey("topic") ||
|
||||||
|
!data["mqtt"].containsKey("username") ||
|
||||||
|
!data["mqtt"].containsKey("password") ||
|
||||||
|
!data["mqtt"].containsKey("port") ||
|
||||||
|
!data["mqtt"].containsKey("beaconOverMqtt")) needsRewrite = true;
|
||||||
|
mqtt.active = data["mqtt"]["active"] | false;
|
||||||
|
mqtt.server = data["mqtt"]["server"] | "";
|
||||||
|
mqtt.topic = data["mqtt"]["topic"] | "aprs-igate";
|
||||||
|
mqtt.username = data["mqtt"]["username"] | "";
|
||||||
|
mqtt.password = data["mqtt"]["password"] | "";
|
||||||
|
mqtt.port = data["mqtt"]["port"] | 1883;
|
||||||
|
mqtt.beaconOverMqtt = data["mqtt"]["beaconOverMqtt"] | false;
|
||||||
|
|
||||||
|
if (!data["ota"].containsKey("username") ||
|
||||||
|
!data["ota"].containsKey("password")) needsRewrite = true;
|
||||||
ota.username = data["ota"]["username"] | "";
|
ota.username = data["ota"]["username"] | "";
|
||||||
ota.password = data["ota"]["password"] | "";
|
ota.password = data["ota"]["password"] | "";
|
||||||
|
|
||||||
|
if (!data["webadmin"].containsKey("active") ||
|
||||||
|
!data["webadmin"].containsKey("username") ||
|
||||||
|
!data["webadmin"].containsKey("password")) needsRewrite = true;
|
||||||
webadmin.active = data["webadmin"]["active"] | false;
|
webadmin.active = data["webadmin"]["active"] | false;
|
||||||
webadmin.username = data["webadmin"]["username"] | "admin";
|
webadmin.username = data["webadmin"]["username"] | "admin";
|
||||||
webadmin.password = data["webadmin"]["password"] | "";
|
webadmin.password = data["webadmin"]["password"] | "";
|
||||||
|
|
||||||
|
if (!data["remoteManagement"].containsKey("managers") ||
|
||||||
|
!data["remoteManagement"].containsKey("rfOnly")) needsRewrite = true;
|
||||||
|
remoteManagement.managers = data["remoteManagement"]["managers"] | "";
|
||||||
|
remoteManagement.rfOnly = data["remoteManagement"]["rfOnly"] | true;
|
||||||
|
|
||||||
|
if (!data["ntp"].containsKey("server") ||
|
||||||
|
!data["ntp"].containsKey("gmtCorrection")) needsRewrite = true;
|
||||||
|
ntp.server = data["ntp"]["server"] | "pool.ntp.org";
|
||||||
ntp.gmtCorrection = data["ntp"]["gmtCorrection"] | 0.0;
|
ntp.gmtCorrection = data["ntp"]["gmtCorrection"] | 0.0;
|
||||||
|
|
||||||
backupDigiMode = data["other"]["backupDigiMode"] | false;
|
if (!data["other"].containsKey("rebootMode") ||
|
||||||
|
!data["other"].containsKey("rebootModeTime")) needsRewrite = true;
|
||||||
rebootMode = data["other"]["rebootMode"] | false;
|
rebootMode = data["other"]["rebootMode"] | false;
|
||||||
rebootModeTime = data["other"]["rebootModeTime"] | 6;
|
rebootModeTime = data["other"]["rebootModeTime"] | 6;
|
||||||
|
|
||||||
personalNote = data["personalNote"] | "personal note here";
|
if (!data["other"].containsKey("rememberStationTime")) needsRewrite = true;
|
||||||
|
rememberStationTime = data["other"]["rememberStationTime"] | 30;
|
||||||
|
|
||||||
blacklist = data["blacklist"] | "station callsign";
|
if (!data["other"].containsKey("backupDigiMode")) needsRewrite = true;
|
||||||
|
backupDigiMode = data["other"]["backupDigiMode"] | false;
|
||||||
remoteManagement.managers = data["remoteManagement"]["managers"] | "";
|
|
||||||
remoteManagement.rfOnly = data["remoteManagement"]["rfOnly"] | true;
|
|
||||||
|
|
||||||
if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP
|
if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP
|
||||||
WiFi_AP wifiap;
|
WiFi_AP wifiap;
|
||||||
@@ -272,6 +402,13 @@ bool Configuration::readFile() {
|
|||||||
wifiAPs.push_back(wifiap);
|
wifiAPs.push_back(wifiap);
|
||||||
}
|
}
|
||||||
configFile.close();
|
configFile.close();
|
||||||
|
|
||||||
|
if (needsRewrite) {
|
||||||
|
Serial.println("Config JSON incomplete, rewriting...");
|
||||||
|
writeFile();
|
||||||
|
delay(1000);
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
Serial.println("Config read successfuly");
|
Serial.println("Config read successfuly");
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -280,7 +417,7 @@ bool Configuration::readFile() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::init() {
|
void Configuration::setDefaultValues() {
|
||||||
|
|
||||||
WiFi_AP wifiap;
|
WiFi_AP wifiap;
|
||||||
wifiap.ssid = "";
|
wifiap.ssid = "";
|
||||||
@@ -288,34 +425,13 @@ void Configuration::init() {
|
|||||||
|
|
||||||
wifiAPs.push_back(wifiap);
|
wifiAPs.push_back(wifiap);
|
||||||
|
|
||||||
|
startupDelay = 0;
|
||||||
|
|
||||||
wifiAutoAP.password = "1234567890";
|
wifiAutoAP.password = "1234567890";
|
||||||
wifiAutoAP.timeout = 10;
|
wifiAutoAP.timeout = 10;
|
||||||
|
|
||||||
callsign = "N0CALL-10";
|
callsign = "N0CALL-10";
|
||||||
|
|
||||||
beacon.comment = "LoRa APRS";
|
|
||||||
beacon.latitude = 0.0;
|
|
||||||
beacon.longitude = 0.0;
|
|
||||||
beacon.interval = 15;
|
|
||||||
beacon.overlay = "L";
|
|
||||||
beacon.symbol = "a";
|
|
||||||
beacon.sendViaAPRSIS = true;
|
|
||||||
beacon.sendViaRF = false;
|
|
||||||
beacon.path = "WIDE1-1";
|
|
||||||
|
|
||||||
beacon.statusActive = false;
|
|
||||||
beacon.statusPacket = "";
|
|
||||||
|
|
||||||
beacon.gpsActive = false;
|
|
||||||
beacon.gpsAmbiguity = false;
|
|
||||||
|
|
||||||
digi.mode = 0;
|
|
||||||
digi.ecoMode = 0;
|
|
||||||
|
|
||||||
tnc.enableServer = false;
|
|
||||||
tnc.enableSerial = false;
|
|
||||||
tnc.acceptOwn = false;
|
|
||||||
|
|
||||||
aprs_is.active = false;
|
aprs_is.active = false;
|
||||||
aprs_is.passcode = "XYZVW";
|
aprs_is.passcode = "XYZVW";
|
||||||
aprs_is.server = "rotate.aprs2.net";
|
aprs_is.server = "rotate.aprs2.net";
|
||||||
@@ -324,65 +440,104 @@ void Configuration::init() {
|
|||||||
aprs_is.messagesToRF = false;
|
aprs_is.messagesToRF = false;
|
||||||
aprs_is.objectsToRF = false;
|
aprs_is.objectsToRF = false;
|
||||||
|
|
||||||
loramodule.txFreq = 433775000;
|
beacon.comment = "LoRa APRS";
|
||||||
loramodule.rxFreq = 433775000;
|
beacon.latitude = 0.0;
|
||||||
loramodule.spreadingFactor = 12;
|
beacon.longitude = 0.0;
|
||||||
loramodule.signalBandwidth = 125000;
|
beacon.interval = 15;
|
||||||
loramodule.codingRate4 = 5;
|
beacon.overlay = "L";
|
||||||
loramodule.power = 20;
|
beacon.symbol = "a";
|
||||||
loramodule.txActive = false;
|
beacon.path = "WIDE1-1";
|
||||||
|
|
||||||
|
beacon.sendViaAPRSIS = true;
|
||||||
|
beacon.sendViaRF = false;
|
||||||
|
beacon.beaconFreq = 1;
|
||||||
|
|
||||||
|
beacon.statusActive = false;
|
||||||
|
beacon.statusPacket = "";
|
||||||
|
|
||||||
|
beacon.gpsActive = false;
|
||||||
|
beacon.ambiguityLevel = 0;
|
||||||
|
|
||||||
|
personalNote = "";
|
||||||
|
|
||||||
|
blacklist = "";
|
||||||
|
|
||||||
|
digi.mode = 0;
|
||||||
|
digi.ecoMode = 0;
|
||||||
|
|
||||||
loramodule.rxActive = true;
|
loramodule.rxActive = true;
|
||||||
|
loramodule.rxFreq = 433775000;
|
||||||
|
loramodule.rxSpreadingFactor = 12;
|
||||||
|
loramodule.rxCodingRate4 = 5;
|
||||||
|
loramodule.rxSignalBandwidth = 125000;
|
||||||
|
loramodule.txActive = false;
|
||||||
|
loramodule.txFreq = 433775000;
|
||||||
|
loramodule.txSpreadingFactor = 12;
|
||||||
|
loramodule.txCodingRate4 = 5;
|
||||||
|
loramodule.txSignalBandwidth = 125000;
|
||||||
|
loramodule.power = 20;
|
||||||
|
|
||||||
display.alwaysOn = true;
|
display.alwaysOn = true;
|
||||||
display.timeout = 4;
|
display.timeout = 4;
|
||||||
display.turn180 = false;
|
display.turn180 = false;
|
||||||
|
|
||||||
syslog.active = false;
|
|
||||||
syslog.server = "lora.link9.net";
|
|
||||||
syslog.port = 1514;
|
|
||||||
syslog.logBeaconOverTCPIP = false;
|
|
||||||
|
|
||||||
wxsensor.active = false;
|
|
||||||
wxsensor.heightCorrection = 0;
|
|
||||||
wxsensor.temperatureCorrection = 0.0;
|
|
||||||
|
|
||||||
ota.username = "";
|
|
||||||
ota.password = "";
|
|
||||||
|
|
||||||
rememberStationTime = 30;
|
|
||||||
|
|
||||||
battery.sendInternalVoltage = false;
|
battery.sendInternalVoltage = false;
|
||||||
battery.monitorInternalVoltage = false;
|
battery.monitorInternalVoltage = false;
|
||||||
battery.internalSleepVoltage = 2.9;
|
battery.internalSleepVoltage = 2.9;
|
||||||
|
|
||||||
battery.sendExternalVoltage = false;
|
battery.sendExternalVoltage = false;
|
||||||
battery.externalVoltagePin = 34;
|
|
||||||
battery.monitorExternalVoltage = false;
|
battery.monitorExternalVoltage = false;
|
||||||
battery.externalSleepVoltage = 10.9;
|
battery.externalSleepVoltage = 10.9;
|
||||||
|
battery.useExternalI2CSensor = false;
|
||||||
battery.voltageDividerR1 = 100.0;
|
battery.voltageDividerR1 = 100.0;
|
||||||
battery.voltageDividerR2 = 27.0;
|
battery.voltageDividerR2 = 27.0;
|
||||||
|
battery.externalVoltagePin = 34;
|
||||||
|
|
||||||
battery.sendVoltageAsTelemetry = false;
|
battery.sendVoltageAsTelemetry = false;
|
||||||
|
|
||||||
backupDigiMode = false;
|
wxsensor.active = false;
|
||||||
|
wxsensor.heightCorrection = 0;
|
||||||
|
wxsensor.temperatureCorrection = 0.0;
|
||||||
|
|
||||||
rebootMode = false;
|
syslog.active = false;
|
||||||
rebootModeTime = 0;
|
syslog.server = "lora.link9.net";
|
||||||
|
syslog.port = 1514;
|
||||||
|
syslog.logBeaconOverTCPIP = false;
|
||||||
|
|
||||||
personalNote = "";
|
tnc.enableServer = false;
|
||||||
|
tnc.enableSerial = false;
|
||||||
|
tnc.acceptOwn = false;
|
||||||
|
tnc.aprsBridgeActive = false;
|
||||||
|
|
||||||
blacklist = "";
|
mqtt.active = false;
|
||||||
|
mqtt.server = "";
|
||||||
|
mqtt.topic = "aprs-igate";
|
||||||
|
mqtt.username = "";
|
||||||
|
mqtt.password = "";
|
||||||
|
mqtt.port = 1883;
|
||||||
|
mqtt.beaconOverMqtt = false;
|
||||||
|
|
||||||
|
ota.username = "";
|
||||||
|
ota.password = "";
|
||||||
|
|
||||||
webadmin.active = false;
|
webadmin.active = false;
|
||||||
webadmin.username = "admin";
|
webadmin.username = "admin";
|
||||||
webadmin.password = "";
|
webadmin.password = "";
|
||||||
|
|
||||||
ntp.gmtCorrection = 0.0;
|
|
||||||
|
|
||||||
remoteManagement.managers = "";
|
remoteManagement.managers = "";
|
||||||
remoteManagement.rfOnly = true;
|
remoteManagement.rfOnly = true;
|
||||||
|
|
||||||
Serial.println("All is Written!");
|
ntp.server = "pool.ntp.org";
|
||||||
|
ntp.gmtCorrection = 0.0;
|
||||||
|
|
||||||
|
rebootMode = false;
|
||||||
|
rebootModeTime = 0;
|
||||||
|
|
||||||
|
rememberStationTime = 30;
|
||||||
|
|
||||||
|
backupDigiMode = false;
|
||||||
|
|
||||||
|
Serial.println("New Data Created... All is Written!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Configuration::Configuration() {
|
Configuration::Configuration() {
|
||||||
@@ -395,8 +550,9 @@ Configuration::Configuration() {
|
|||||||
|
|
||||||
bool exists = SPIFFS.exists("/igate_conf.json");
|
bool exists = SPIFFS.exists("/igate_conf.json");
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
init();
|
setDefaultValues();
|
||||||
writeFile();
|
writeFile();
|
||||||
|
delay(1000);
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,16 @@
|
|||||||
#ifdef HAS_EPAPER
|
#ifdef HAS_EPAPER
|
||||||
#include <heltec-eink-modules.h>
|
#include <heltec-eink-modules.h>
|
||||||
#include "Fonts/FreeSansBold9pt7b.h"
|
#include "Fonts/FreeSansBold9pt7b.h"
|
||||||
|
#ifdef HELTEC_WP_V1
|
||||||
EInkDisplay_WirelessPaperV1_1 display;
|
EInkDisplay_WirelessPaperV1_1 display;
|
||||||
|
#endif
|
||||||
|
#ifdef HELTEC_WP_V1_2
|
||||||
|
EInkDisplay_WirelessPaperV1_2 display;
|
||||||
|
#endif
|
||||||
|
#ifdef HELTEC_VM_E290
|
||||||
|
EInkDisplay_VisionMasterE290 display;
|
||||||
|
#endif
|
||||||
|
|
||||||
String lastEpaperText;
|
String lastEpaperText;
|
||||||
#else
|
#else
|
||||||
#include <Adafruit_GFX.h>
|
#include <Adafruit_GFX.h>
|
||||||
@@ -91,6 +100,14 @@ void displaySetup() {
|
|||||||
#ifdef HAS_EPAPER
|
#ifdef HAS_EPAPER
|
||||||
display.landscape();
|
display.landscape();
|
||||||
display.printCenter("LoRa APRS iGate Initialising...");
|
display.printCenter("LoRa APRS iGate Initialising...");
|
||||||
|
if (Config.display.turn180) {
|
||||||
|
#if defined(HELTEC_VM_E290) || defined(HELTEC_WP_V1)
|
||||||
|
display.setRotation(3);
|
||||||
|
#endif
|
||||||
|
#if defined(HELTEC_WP_V1_2)
|
||||||
|
display.setRotation(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
display.update();
|
display.update();
|
||||||
#else
|
#else
|
||||||
#ifdef OLED_DISPLAY_HAS_RST_PIN
|
#ifdef OLED_DISPLAY_HAS_RST_PIN
|
||||||
@@ -101,7 +118,7 @@ void displaySetup() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
if (!display.begin(0x3c, false)) {
|
if (display.begin(0x3c, false)) {
|
||||||
displayFound = true;
|
displayFound = true;
|
||||||
if (Config.display.turn180) display.setRotation(2);
|
if (Config.display.turn180) display.setRotation(2);
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
@@ -152,7 +169,6 @@ void displayToggle(bool toggle) {
|
|||||||
digitalWrite(TFT_BL, LOW);
|
digitalWrite(TFT_BL, LOW);
|
||||||
#else
|
#else
|
||||||
#ifdef HAS_EPAPER
|
#ifdef HAS_EPAPER
|
||||||
display.printCenter("Enabled EPAPER Display...");
|
|
||||||
display.update();
|
display.update();
|
||||||
#else
|
#else
|
||||||
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <APRSPacketLib.h>
|
||||||
#include <TinyGPS++.h>
|
#include <TinyGPS++.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
@@ -31,7 +32,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern WiFiClient espClient;
|
|
||||||
extern HardwareSerial gpsSerial;
|
extern HardwareSerial gpsSerial;
|
||||||
extern TinyGPSPlus gps;
|
extern TinyGPSPlus gps;
|
||||||
String distance, iGateBeaconPacket, iGateLoRaBeaconPacket;
|
String distance, iGateBeaconPacket, iGateLoRaBeaconPacket;
|
||||||
@@ -43,70 +43,6 @@ namespace GPS_Utils {
|
|||||||
return iGateLoRaBeaconPacket;
|
return iGateLoRaBeaconPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ax25_base91enc(char *s, uint8_t n, uint32_t v) {
|
|
||||||
for(s += n, *s = '\0'; n; n--) {
|
|
||||||
*(--s) = v % 91 + 33;
|
|
||||||
v /= 91;
|
|
||||||
}
|
|
||||||
return(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
float roundToTwoDecimals(float degrees) {
|
|
||||||
return round(degrees * 100) / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
String encodeGPS(float latitude, float longitude, const String& overlay, const String& symbol) {
|
|
||||||
String encodedData = overlay;
|
|
||||||
uint32_t aprs_lat, aprs_lon;
|
|
||||||
|
|
||||||
float processedLatitude = latitude;
|
|
||||||
float processedLongitude = longitude;
|
|
||||||
if (Config.beacon.gpsActive && Config.beacon.gpsAmbiguity) {
|
|
||||||
processedLatitude = roundToTwoDecimals(latitude);
|
|
||||||
processedLongitude = roundToTwoDecimals(longitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
aprs_lat = 900000000 - processedLatitude * 10000000;
|
|
||||||
aprs_lat = aprs_lat / 26 - aprs_lat / 2710 + aprs_lat / 15384615;
|
|
||||||
aprs_lon = 900000000 + processedLongitude * 10000000 / 2;
|
|
||||||
aprs_lon = aprs_lon / 26 - aprs_lon / 2710 + aprs_lon / 15384615;
|
|
||||||
|
|
||||||
String Ns, Ew, helper;
|
|
||||||
if(processedLatitude < 0) { Ns = "S"; } else { Ns = "N"; }
|
|
||||||
if(processedLatitude < 0) { processedLatitude = -processedLatitude; }
|
|
||||||
|
|
||||||
if(processedLongitude < 0) { Ew = "W"; } else { Ew = "E"; }
|
|
||||||
if(processedLongitude < 0) { processedLongitude = -processedLongitude; }
|
|
||||||
|
|
||||||
char helper_base91[] = {"0000\0"};
|
|
||||||
int i;
|
|
||||||
ax25_base91enc(helper_base91, 4, aprs_lat);
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
encodedData += helper_base91[i];
|
|
||||||
}
|
|
||||||
ax25_base91enc(helper_base91, 4, aprs_lon);
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
encodedData += helper_base91[i];
|
|
||||||
}
|
|
||||||
encodedData += symbol;
|
|
||||||
encodedData += " ";
|
|
||||||
encodedData += "\x47";
|
|
||||||
return encodedData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void generateBeaconFirstPart() {
|
|
||||||
String beaconPacket = Config.callsign;
|
|
||||||
beaconPacket += ">APLRG1";
|
|
||||||
if (Config.beacon.path.indexOf("WIDE") == 0) {
|
|
||||||
beaconPacket += ",";
|
|
||||||
beaconPacket += Config.beacon.path;
|
|
||||||
}
|
|
||||||
iGateBeaconPacket = beaconPacket;
|
|
||||||
iGateBeaconPacket += ",qAC:!";
|
|
||||||
iGateLoRaBeaconPacket = beaconPacket;
|
|
||||||
iGateLoRaBeaconPacket += ":!";
|
|
||||||
}
|
|
||||||
|
|
||||||
void generateBeacons() {
|
void generateBeacons() {
|
||||||
if (Config.callsign.indexOf("NOCALL-10") != 0 && !Utils::checkValidCallsign(Config.callsign)) {
|
if (Config.callsign.indexOf("NOCALL-10") != 0 && !Utils::checkValidCallsign(Config.callsign)) {
|
||||||
displayShow("***** ERROR ******", "CALLSIGN = NOT VALID!", "", "Only Rx Mode Active", 3000);
|
displayShow("***** ERROR ******", "CALLSIGN = NOT VALID!", "", "Only Rx Mode Active", 3000);
|
||||||
@@ -117,9 +53,17 @@ namespace GPS_Utils {
|
|||||||
Config.digi.mode = 0;
|
Config.digi.mode = 0;
|
||||||
Config.backupDigiMode = false;
|
Config.backupDigiMode = false;
|
||||||
}
|
}
|
||||||
generateBeaconFirstPart();
|
String beaconPacket = APRSPacketLib::generateBasePacket(Config.callsign, "APLRG1", Config.beacon.path);
|
||||||
String encodedGPS = encodeGPS(Config.beacon.latitude, Config.beacon.longitude, Config.beacon.overlay, Config.beacon.symbol);
|
String encodedGPS = APRSPacketLib::encodeGPSIntoBase91(Config.beacon.latitude, Config.beacon.longitude, 0, 0, Config.beacon.symbol, false, 0, true, Config.beacon.ambiguityLevel);
|
||||||
|
|
||||||
|
iGateBeaconPacket = beaconPacket;
|
||||||
|
iGateBeaconPacket += ",qAC:!";
|
||||||
|
iGateBeaconPacket += Config.beacon.overlay;
|
||||||
iGateBeaconPacket += encodedGPS;
|
iGateBeaconPacket += encodedGPS;
|
||||||
|
|
||||||
|
iGateLoRaBeaconPacket = beaconPacket;
|
||||||
|
iGateLoRaBeaconPacket += ":=";
|
||||||
|
iGateLoRaBeaconPacket += Config.beacon.overlay;
|
||||||
iGateLoRaBeaconPacket += encodedGPS;
|
iGateLoRaBeaconPacket += encodedGPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,47 +71,40 @@ namespace GPS_Utils {
|
|||||||
return TinyGPSPlus::distanceBetween(Config.beacon.latitude,Config.beacon.longitude, latitude, longitude) / 1000.0;
|
return TinyGPSPlus::distanceBetween(Config.beacon.latitude,Config.beacon.longitude, latitude, longitude) / 1000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String buildDistanceAndComment(float latitude, float longitude, const String& comment) {
|
||||||
|
distance = String(calculateDistanceTo(latitude, longitude),1);
|
||||||
|
|
||||||
|
String distanceAndComment = String(latitude,5);
|
||||||
|
distanceAndComment += "N / ";
|
||||||
|
distanceAndComment += String(longitude,5);
|
||||||
|
distanceAndComment += "E / ";
|
||||||
|
distanceAndComment += distance;
|
||||||
|
distanceAndComment += "km";
|
||||||
|
|
||||||
|
if (comment != "") {
|
||||||
|
distanceAndComment += " / ";
|
||||||
|
distanceAndComment += comment;
|
||||||
|
}
|
||||||
|
return distanceAndComment;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
String decodeEncodedGPS(const String& packet) {
|
String decodeEncodedGPS(const String& packet) {
|
||||||
int indexOfExclamation = packet.indexOf(":!");
|
int indexOfExclamation = packet.indexOf(":!");
|
||||||
int indexOfEqual = packet.indexOf(":=");
|
int indexOfEqual = packet.indexOf(":=");
|
||||||
|
|
||||||
const uint8_t OFFSET = 3; // Offset for encoded data in the packet
|
const uint8_t OFFSET = 3; // Offset for encoded data in the packet
|
||||||
String GPSPacket;
|
String infoGPS;
|
||||||
if (indexOfExclamation > 10) {
|
if (indexOfExclamation > 10) {
|
||||||
GPSPacket = packet.substring(indexOfExclamation + OFFSET);
|
infoGPS = packet.substring(indexOfExclamation + OFFSET);
|
||||||
} else if (indexOfEqual > 10) {
|
} else if (indexOfEqual > 10) {
|
||||||
GPSPacket = packet.substring(indexOfEqual + OFFSET);
|
infoGPS = packet.substring(indexOfEqual + OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
String encodedLatitude = GPSPacket.substring(0,4);
|
float decodedLatitude = APRSPacketLib::decodeBase91EncodedLatitude(infoGPS.substring(0,4));
|
||||||
int Y1 = encodedLatitude[0] - 33;
|
float decodedLongitude = APRSPacketLib::decodeBase91EncodedLongitude(infoGPS.substring(4,8));
|
||||||
int Y2 = encodedLatitude[1] - 33;
|
|
||||||
int Y3 = encodedLatitude[2] - 33;
|
|
||||||
int Y4 = encodedLatitude[3] - 33;
|
|
||||||
float decodedLatitude = 90.0 - (((Y1 * pow(91,3)) + (Y2 * pow(91,2)) + (Y3 * 91) + Y4) / 380926.0);
|
|
||||||
|
|
||||||
String encodedLongitude = GPSPacket.substring(4,8);
|
return buildDistanceAndComment(decodedLatitude, decodedLongitude, infoGPS.substring(12));
|
||||||
int X1 = encodedLongitude[0] - 33;
|
|
||||||
int X2 = encodedLongitude[1] - 33;
|
|
||||||
int X3 = encodedLongitude[2] - 33;
|
|
||||||
int X4 = encodedLongitude[3] - 33;
|
|
||||||
float decodedLongitude = -180.0 + (((X1 * pow(91,3)) + (X2 * pow(91,2)) + (X3 * 91) + X4) / 190463.0);
|
|
||||||
|
|
||||||
distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1);
|
|
||||||
|
|
||||||
String decodedGPS = String(decodedLatitude,5);
|
|
||||||
decodedGPS += "N / ";
|
|
||||||
decodedGPS += String(decodedLongitude,5);
|
|
||||||
decodedGPS += "E / ";
|
|
||||||
decodedGPS += distance;
|
|
||||||
decodedGPS += "km";
|
|
||||||
|
|
||||||
String comment = GPSPacket.substring(12);
|
|
||||||
if (comment != "") {
|
|
||||||
decodedGPS += " / ";
|
|
||||||
decodedGPS += comment;
|
|
||||||
}
|
|
||||||
return decodedGPS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getReceivedGPS(const String& packet) {
|
String getReceivedGPS(const String& packet) {
|
||||||
@@ -196,50 +133,43 @@ namespace GPS_Utils {
|
|||||||
convertedLongitude += Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3).toFloat() / (60*100);
|
convertedLongitude += Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3).toFloat() / (60*100);
|
||||||
if (Longitude.endsWith("W")) convertedLongitude = -convertedLongitude; // Handle Western Hemisphere
|
if (Longitude.endsWith("W")) convertedLongitude = -convertedLongitude; // Handle Western Hemisphere
|
||||||
|
|
||||||
distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1);
|
return buildDistanceAndComment(convertedLatitude, convertedLongitude, infoGPS.substring(19));
|
||||||
|
|
||||||
String decodedGPS = String(convertedLatitude,5);
|
|
||||||
decodedGPS += "N / ";
|
|
||||||
decodedGPS += String(convertedLongitude,5);
|
|
||||||
decodedGPS += "E / ";
|
|
||||||
decodedGPS += distance;
|
|
||||||
decodedGPS += "km";
|
|
||||||
|
|
||||||
String comment = infoGPS.substring(19);
|
|
||||||
if (comment != "") {
|
|
||||||
decodedGPS += " / ";
|
|
||||||
decodedGPS += comment;
|
|
||||||
}
|
|
||||||
return decodedGPS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getDistanceAndComment(const String& packet) {
|
String getDistanceAndComment(const String& packet) {
|
||||||
int indexOfAt = packet.indexOf(":@");
|
int indexOfAt = packet.indexOf(":@");
|
||||||
if (indexOfAt > 10) {
|
if (indexOfAt > 10) return getReceivedGPS(packet);
|
||||||
return getReceivedGPS(packet);
|
|
||||||
} else {
|
const uint8_t nonEncondedLatitudeOffset = 9; // "N" / "S"
|
||||||
const uint8_t ENCODED_BYTE_OFFSET = 14; // Offset for encoded data in the packet
|
const uint8_t nonEncondedLongitudeOffset = 19; // "E" / "W"
|
||||||
|
const uint8_t encondedByteOffset = 14;
|
||||||
|
|
||||||
int indexOfExclamation = packet.indexOf(":!");
|
int indexOfExclamation = packet.indexOf(":!");
|
||||||
int indexOfEqual = packet.indexOf(":=");
|
int indexOfEqual = packet.indexOf(":=");
|
||||||
uint8_t encodedBytePosition = 0;
|
int baseIndex = - 1;
|
||||||
if (indexOfExclamation > 10) { // Determine the position where encoded data starts
|
if (indexOfExclamation > 10) {
|
||||||
encodedBytePosition = indexOfExclamation + ENCODED_BYTE_OFFSET;
|
baseIndex = indexOfExclamation;
|
||||||
} else if (indexOfEqual > 10) {
|
} else if (indexOfEqual > 10) {
|
||||||
encodedBytePosition = indexOfEqual + ENCODED_BYTE_OFFSET;
|
baseIndex = indexOfEqual;
|
||||||
}
|
}
|
||||||
|
if (baseIndex == -1) return " _ / _ / _ ";
|
||||||
|
|
||||||
|
int latitudeIndex = baseIndex + nonEncondedLatitudeOffset;
|
||||||
|
int longitudeIndex = baseIndex + nonEncondedLongitudeOffset;
|
||||||
|
int encondedByteIndex = baseIndex + encondedByteOffset;
|
||||||
|
int packetLength = packet.length();
|
||||||
|
|
||||||
|
if (latitudeIndex >= packetLength || longitudeIndex >= packetLength || encondedByteIndex >= packetLength) return " _ / _ / _ ";
|
||||||
|
|
||||||
|
char latChar = packet[latitudeIndex];
|
||||||
|
char lngChar = packet[longitudeIndex];
|
||||||
|
if ((latChar == 'N' || latChar == 'S') && (lngChar == 'E' || lngChar == 'W')) return getReceivedGPS(packet);
|
||||||
|
|
||||||
|
char byteChar = packet[encondedByteIndex];
|
||||||
|
if (byteChar == 'G' || byteChar == 'Q' || byteChar == '[' || byteChar == 'H' || byteChar == 'X' || byteChar == '3') return decodeEncodedGPS(packet);
|
||||||
|
|
||||||
if (encodedBytePosition != 0) {
|
|
||||||
char currentChar = packet[encodedBytePosition];
|
|
||||||
if (currentChar == 'G' || currentChar == 'Q' || currentChar == '[' || currentChar == 'H' || currentChar == 'X') {
|
|
||||||
return decodeEncodedGPS(packet); // If valid encoded data position is found, decode it
|
|
||||||
} else {
|
|
||||||
return getReceivedGPS(packet);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return " _ / _ / _ ";
|
return " _ / _ / _ ";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern uint32_t lastRxTime;
|
extern uint32_t lastRxTime;
|
||||||
|
extern bool packetIsBeacon;
|
||||||
|
|
||||||
extern std::vector<ReceivedPacket> receivedPackets;
|
extern std::vector<ReceivedPacket> receivedPackets;
|
||||||
|
|
||||||
@@ -92,16 +93,31 @@ namespace LoRa_Utils {
|
|||||||
#if defined(HAS_SX1278) || defined(HAS_SX1276)
|
#if defined(HAS_SX1278) || defined(HAS_SX1276)
|
||||||
radio.setDio0Action(setFlag, RISING);
|
radio.setDio0Action(setFlag, RISING);
|
||||||
#endif
|
#endif
|
||||||
radio.setSpreadingFactor(Config.loramodule.spreadingFactor);
|
|
||||||
float signalBandwidth = Config.loramodule.signalBandwidth/1000;
|
/*#ifdef SX126X_DIO3_TCXO_VOLTAGE
|
||||||
|
if (radio.setTCXO(float(SX126X_DIO3_TCXO_VOLTAGE)) == RADIOLIB_ERR_NONE) {
|
||||||
|
Utils::println("Set LoRa Module TCXO Voltage to:" + String(SX126X_DIO3_TCXO_VOLTAGE));
|
||||||
|
} else {
|
||||||
|
Utils::println("Set LoRa Module TCXO Voltage failed! State: " + String(state));
|
||||||
|
while (true);
|
||||||
|
}
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
radio.setSpreadingFactor(Config.loramodule.rxSpreadingFactor);
|
||||||
|
radio.setCodingRate(Config.loramodule.rxCodingRate4);
|
||||||
|
float signalBandwidth = Config.loramodule.rxSignalBandwidth/1000;
|
||||||
radio.setBandwidth(signalBandwidth);
|
radio.setBandwidth(signalBandwidth);
|
||||||
radio.setCodingRate(Config.loramodule.codingRate4);
|
|
||||||
radio.setCRC(true);
|
radio.setCRC(true);
|
||||||
|
|
||||||
#if (defined(RADIO_RXEN) && defined(RADIO_TXEN)) // QRP Labs LightGateway has 400M22S (SX1268)
|
#if (defined(RADIO_RXEN) && defined(RADIO_TXEN)) // QRP Labs LightGateway has 400M22S (SX1268)
|
||||||
radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN);
|
radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*#ifdef SX126X_DIO2_AS_RF_SWITCH
|
||||||
|
radio.setRfSwitchPins(RADIO_RXEN, RADIOLIB_NC);
|
||||||
|
radio.setDio2AsRfSwitch(true);
|
||||||
|
#endif*/
|
||||||
|
|
||||||
#ifdef HAS_1W_LORA // Ebyte E22 400M30S (SX1268) / 900M30S (SX1262) / Ebyte E220 400M30S (LLCC68)
|
#ifdef HAS_1W_LORA // Ebyte E22 400M30S (SX1268) / 900M30S (SX1262) / Ebyte E220 400M30S (LLCC68)
|
||||||
state = radio.setOutputPower(Config.loramodule.power); // max value 20dB for 1W modules as they have Low Noise Amp
|
state = radio.setOutputPower(Config.loramodule.power); // max value 20dB for 1W modules as they have Low Noise Amp
|
||||||
radio.setCurrentLimit(140); // to be validated (100 , 120, 140)?
|
radio.setCurrentLimit(140); // to be validated (100 , 120, 140)?
|
||||||
@@ -119,6 +135,13 @@ namespace LoRa_Utils {
|
|||||||
radio.setRxBoostedGainMode(true);
|
radio.setRxBoostedGainMode(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAS_TCXO) && !defined(HAS_1W_LORA)
|
||||||
|
radio.setDio2AsRfSwitch();
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_TCXO
|
||||||
|
radio.setTCXO(1.8);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (state == RADIOLIB_ERR_NONE) {
|
if (state == RADIOLIB_ERR_NONE) {
|
||||||
Utils::println("init : LoRa Module ... done!");
|
Utils::println("init : LoRa Module ... done!");
|
||||||
} else {
|
} else {
|
||||||
@@ -128,23 +151,31 @@ namespace LoRa_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void changeFreqTx() {
|
void changeFreqTx() {
|
||||||
delay(500);
|
delay(300);
|
||||||
float freq = (float)Config.loramodule.txFreq / 1000000;
|
float freq = (float)Config.loramodule.txFreq / 1000000;
|
||||||
radio.setFrequency(freq);
|
radio.setFrequency(freq);
|
||||||
|
radio.setSpreadingFactor(Config.loramodule.txSpreadingFactor);
|
||||||
|
radio.setCodingRate(Config.loramodule.txCodingRate4);
|
||||||
|
radio.setBandwidth(Config.loramodule.txSignalBandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void changeFreqRx() {
|
void changeFreqRx() {
|
||||||
delay(500);
|
delay(300);
|
||||||
float freq = (float)Config.loramodule.rxFreq / 1000000;
|
float freq = (float)Config.loramodule.rxFreq / 1000000;
|
||||||
radio.setFrequency(freq);
|
radio.setFrequency(freq);
|
||||||
|
radio.setSpreadingFactor(Config.loramodule.rxSpreadingFactor);
|
||||||
|
radio.setCodingRate(Config.loramodule.rxCodingRate4);
|
||||||
|
radio.setBandwidth(Config.loramodule.rxSignalBandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendNewPacket(const String& newPacket) {
|
void sendNewPacket(const String& newPacket) {
|
||||||
if (!Config.loramodule.txActive) return;
|
if (!Config.loramodule.txActive) return;
|
||||||
|
|
||||||
if (Config.loramodule.txFreq != Config.loramodule.rxFreq) {
|
if (Config.loramodule.txFreq != Config.loramodule.rxFreq) {
|
||||||
|
if (!packetIsBeacon || (packetIsBeacon && Config.beacon.beaconFreq == 1)) {
|
||||||
changeFreqTx();
|
changeFreqTx();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef INTERNAL_LED_PIN
|
#ifdef INTERNAL_LED_PIN
|
||||||
if (Config.digi.ecoMode != 1) digitalWrite(INTERNAL_LED_PIN, HIGH); // disabled in Ultra Eco Mode
|
if (Config.digi.ecoMode != 1) digitalWrite(INTERNAL_LED_PIN, HIGH); // disabled in Ultra Eco Mode
|
||||||
@@ -165,9 +196,11 @@ namespace LoRa_Utils {
|
|||||||
if (Config.digi.ecoMode != 1) digitalWrite(INTERNAL_LED_PIN, LOW); // disabled in Ultra Eco Mode
|
if (Config.digi.ecoMode != 1) digitalWrite(INTERNAL_LED_PIN, LOW); // disabled in Ultra Eco Mode
|
||||||
#endif
|
#endif
|
||||||
if (Config.loramodule.txFreq != Config.loramodule.rxFreq) {
|
if (Config.loramodule.txFreq != Config.loramodule.rxFreq) {
|
||||||
|
if (!packetIsBeacon || (packetIsBeacon && Config.beacon.beaconFreq == 1)) {
|
||||||
changeFreqRx();
|
changeFreqRx();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String receivePacketFromSleep() {
|
String receivePacketFromSleep() {
|
||||||
String packet = "";
|
String packet = "";
|
||||||
|
|||||||
101
src/mqtt_utils.cpp
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
|
*
|
||||||
|
* This file is part of LoRa APRS iGate.
|
||||||
|
*
|
||||||
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <WiFiClientSecure.h>
|
||||||
|
#include <PubSubClient.h>
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "station_utils.h"
|
||||||
|
#include "mqtt_utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern Configuration Config;
|
||||||
|
extern WiFiClient mqttClient;
|
||||||
|
|
||||||
|
PubSubClient pubSub;
|
||||||
|
|
||||||
|
|
||||||
|
namespace MQTT_Utils {
|
||||||
|
|
||||||
|
void sendToMqtt(const String& packet) {
|
||||||
|
if (!pubSub.connected()) {
|
||||||
|
Serial.println("Can not send to MQTT because it is not connected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const String cleanPacket = packet.substring(3);
|
||||||
|
const String sender = cleanPacket.substring(0, cleanPacket.indexOf(">"));
|
||||||
|
const String topic = String(Config.mqtt.topic + "/" + sender);
|
||||||
|
|
||||||
|
const bool result = pubSub.publish(topic.c_str(), cleanPacket.c_str());
|
||||||
|
if (result) {
|
||||||
|
Serial.print("Packet sent to MQTT topic "); Serial.println(topic);
|
||||||
|
} else {
|
||||||
|
Serial.println("Packet not sent to MQTT (check connection)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void receivedFromMqtt(char* topic, byte* payload, unsigned int length) {
|
||||||
|
Serial.print("Received from MQTT topic "); Serial.print(topic); Serial.print(": ");
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
Serial.print((char)payload[i]);
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
STATION_Utils::addToOutputPacketBuffer(String(payload, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect() {
|
||||||
|
if (pubSub.connected()) return;
|
||||||
|
if (Config.mqtt.server.isEmpty() || Config.mqtt.port <= 0) {
|
||||||
|
Serial.println("Connect to MQTT server KO because no host or port given");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pubSub.setServer(Config.mqtt.server.c_str(), Config.mqtt.port);
|
||||||
|
Serial.print("Trying to connect with MQTT Server: " + String(Config.mqtt.server) + " MqttServerPort: " + String(Config.mqtt.port));
|
||||||
|
|
||||||
|
bool connected = false;
|
||||||
|
if (!Config.mqtt.username.isEmpty()) {
|
||||||
|
connected = pubSub.connect(Config.callsign.c_str(), Config.mqtt.username.c_str(), Config.mqtt.password.c_str());
|
||||||
|
} else {
|
||||||
|
connected = pubSub.connect(Config.callsign.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connected) {
|
||||||
|
Serial.println(" -> Connected !");
|
||||||
|
const String subscribedTopic = Config.mqtt.topic + "/" + Config.callsign + "/#";
|
||||||
|
if (!pubSub.subscribe(subscribedTopic.c_str())) {
|
||||||
|
Serial.println("Subscribed to MQTT Failed");
|
||||||
|
}
|
||||||
|
Serial.print("Subscribed to MQTT topic : ");
|
||||||
|
Serial.println(subscribedTopic);
|
||||||
|
} else {
|
||||||
|
Serial.println(" -> Not Connected (Retry in a few secs)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (!Config.mqtt.active) return;
|
||||||
|
if (!pubSub.connected()) return;
|
||||||
|
pubSub.loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
if (!Config.mqtt.active) return;
|
||||||
|
pubSub.setClient(mqttClient);
|
||||||
|
pubSub.setCallback(receivedFromMqtt);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
|
|
||||||
WiFiUDP ntpUDP;
|
WiFiUDP ntpUDP;
|
||||||
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 15 * 60 * 1000); // Update interval 15 min
|
NTPClient* timeClient;
|
||||||
|
|
||||||
|
|
||||||
namespace NTP_Utils {
|
namespace NTP_Utils {
|
||||||
@@ -35,17 +35,17 @@ namespace NTP_Utils {
|
|||||||
void setup() {
|
void setup() {
|
||||||
if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") {
|
if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") {
|
||||||
int gmt = Config.ntp.gmtCorrection * 3600;
|
int gmt = Config.ntp.gmtCorrection * 3600;
|
||||||
timeClient.setTimeOffset(gmt);
|
timeClient = new NTPClient(ntpUDP, Config.ntp.server.c_str(), gmt, 15 * 60 * 1000); // Update interval 15 min
|
||||||
timeClient.begin();
|
timeClient->begin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update() {
|
void update() {
|
||||||
if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") timeClient.update();
|
if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") timeClient->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getFormatedTime() {
|
String getFormatedTime() {
|
||||||
if (Config.digi.ecoMode == 0) return timeClient.getFormattedTime();
|
if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0) return timeClient->getFormattedTime();
|
||||||
return "DigiEcoMode Active";
|
return "DigiEcoMode Active";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,19 +49,19 @@ namespace POWER_Utils {
|
|||||||
|
|
||||||
#ifdef VEXT_CTRL
|
#ifdef VEXT_CTRL
|
||||||
void vext_ctrl_ON() {
|
void vext_ctrl_ON() {
|
||||||
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3)
|
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3) || defined(HELTEC_VM_E290)
|
||||||
digitalWrite(VEXT_CTRL, Config.digi.ecoMode == 1 ? LOW : HIGH);
|
digitalWrite(VEXT_CTRL, Config.digi.ecoMode == 1 ? LOW : HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if defined(HELTEC_WP) || defined(HELTEC_WS) || defined(HELTEC_V3_2) || defined(HELTEC_WSL_V3)
|
#if defined(HELTEC_WP_V1) || defined(HELTEC_WP_V1_2) || defined(HELTEC_WS) || defined(HELTEC_V3_2) || defined(HELTEC_WSL_V3)
|
||||||
digitalWrite(VEXT_CTRL, Config.digi.ecoMode == 1 ? HIGH : LOW);
|
digitalWrite(VEXT_CTRL, Config.digi.ecoMode == 1 ? HIGH : LOW);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void vext_ctrl_OFF() {
|
void vext_ctrl_OFF() {
|
||||||
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3)
|
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3) || defined(HELTEC_VM_E290)
|
||||||
digitalWrite(VEXT_CTRL, Config.digi.ecoMode == 1 ? HIGH : LOW);
|
digitalWrite(VEXT_CTRL, Config.digi.ecoMode == 1 ? HIGH : LOW);
|
||||||
#endif
|
#endif
|
||||||
#if defined(HELTEC_WP) || defined(HELTEC_WS) || defined(HELTEC_V3_2) || defined(HELTEC_WSL_V3)
|
#if defined(HELTEC_WP_V1) || defined(HELTEC_WP_V1_2) || defined(HELTEC_WS) || defined(HELTEC_V3_2) || defined(HELTEC_WSL_V3)
|
||||||
digitalWrite(VEXT_CTRL, Config.digi.ecoMode == 1 ? LOW : HIGH);
|
digitalWrite(VEXT_CTRL, Config.digi.ecoMode == 1 ? LOW : HIGH);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -70,19 +70,19 @@ namespace POWER_Utils {
|
|||||||
|
|
||||||
#ifdef ADC_CTRL
|
#ifdef ADC_CTRL
|
||||||
void adc_ctrl_ON() {
|
void adc_ctrl_ON() {
|
||||||
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3_2)
|
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3_2) || defined(HELTEC_VM_E290)
|
||||||
digitalWrite(ADC_CTRL, HIGH);
|
digitalWrite(ADC_CTRL, HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if defined(HELTEC_V3) || defined(HELTEC_V2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WP)
|
#if defined(HELTEC_V3) || defined(HELTEC_V2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WP_V1) || defined(HELTEC_WP_V1_2)
|
||||||
digitalWrite(ADC_CTRL, LOW);
|
digitalWrite(ADC_CTRL, LOW);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_ctrl_OFF() {
|
void adc_ctrl_OFF() {
|
||||||
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3_2)
|
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3_2) || defined(HELTEC_VM_E290)
|
||||||
digitalWrite(ADC_CTRL, LOW);
|
digitalWrite(ADC_CTRL, LOW);
|
||||||
#endif
|
#endif
|
||||||
#if defined(HELTEC_V3) || defined(HELTEC_V2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WP)
|
#if defined(HELTEC_V3) || defined(HELTEC_V2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WP_V1) || defined(HELTEC_WP_V1_2)
|
||||||
digitalWrite(ADC_CTRL, HIGH);
|
digitalWrite(ADC_CTRL, HIGH);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -296,18 +296,6 @@ namespace POWER_Utils {
|
|||||||
adc_ctrl_OFF();
|
adc_ctrl_OFF();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HELTEC_WIRELESS_TRACKER)
|
|
||||||
Wire.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WS) || defined(LIGHTGATEWAY_1_0) || defined(LIGHTGATEWAY_PLUS_1_0) || defined(TTGO_LORA32_T3S3_V1_2) || defined(HELTEC_V2)
|
|
||||||
Wire.begin(OLED_SDA, OLED_SCL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WP) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
|
|
||||||
Wire1.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TTGO_T_DECK_GPS) || defined(TTGO_T_DECK_PLUS)
|
#if defined(TTGO_T_DECK_GPS) || defined(TTGO_T_DECK_PLUS)
|
||||||
pinMode(BOARD_POWERON, OUTPUT);
|
pinMode(BOARD_POWERON, OUTPUT);
|
||||||
digitalWrite(BOARD_POWERON, HIGH);
|
digitalWrite(BOARD_POWERON, HIGH);
|
||||||
@@ -321,9 +309,20 @@ namespace POWER_Utils {
|
|||||||
digitalWrite(TFT_CS, HIGH);
|
digitalWrite(TFT_CS, HIGH);
|
||||||
|
|
||||||
delay(500);
|
delay(500);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_WIRE_WITH_OLED_PINS
|
||||||
|
Wire.begin(OLED_SDA, OLED_SCL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_WIRE_WITH_BOARD_I2C_PINS
|
||||||
Wire.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
|
Wire.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_WIRE1_WITH_BOARD_I2C_PINS
|
||||||
|
Wire1.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
|
||||||
|
#endif
|
||||||
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
BATTERY_Utils::setup();
|
BATTERY_Utils::setup();
|
||||||
BATTERY_Utils::startupBatteryHealth();
|
BATTERY_Utils::startupBatteryHealth();
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ extern float snr;
|
|||||||
extern int freqError;
|
extern int freqError;
|
||||||
extern bool shouldSleepLowVoltage;
|
extern bool shouldSleepLowVoltage;
|
||||||
extern bool saveNewDigiEcoModeConfig;
|
extern bool saveNewDigiEcoModeConfig;
|
||||||
|
extern String versionNumber;
|
||||||
|
|
||||||
|
|
||||||
namespace QUERY_Utils {
|
namespace QUERY_Utils {
|
||||||
@@ -42,7 +43,9 @@ namespace QUERY_Utils {
|
|||||||
if (queryQuestion == "?APRS?" || queryQuestion == "H" || queryQuestion == "HELP" || queryQuestion=="?") {
|
if (queryQuestion == "?APRS?" || queryQuestion == "H" || queryQuestion == "HELP" || queryQuestion=="?") {
|
||||||
answer.concat("?APRSV ?APRSP ?APRSL ?APRSSSR ?EM=? ?TX=? "); // ?APRSH ?WHERE callsign
|
answer.concat("?APRSV ?APRSP ?APRSL ?APRSSSR ?EM=? ?TX=? "); // ?APRSH ?WHERE callsign
|
||||||
} else if (queryQuestion == "?APRSV") {
|
} else if (queryQuestion == "?APRSV") {
|
||||||
answer.concat("CA2RXU_LoRa_iGate 3.0 v");
|
answer.concat("CA2RXU_LoRa_iGate v");
|
||||||
|
answer.concat(versionNumber);
|
||||||
|
answer.concat(" ");
|
||||||
answer.concat(versionDate);
|
answer.concat(versionDate);
|
||||||
} else if (queryQuestion == "?APRSP") {
|
} else if (queryQuestion == "?APRSP") {
|
||||||
answer.concat("iGate QTH: ");
|
answer.concat("iGate QTH: ");
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace SLEEP_Utils {
|
|||||||
if (Config.digi.ecoMode == 1) {
|
if (Config.digi.ecoMode == 1) {
|
||||||
pinMode(RADIO_WAKEUP_PIN, INPUT);
|
pinMode(RADIO_WAKEUP_PIN, INPUT);
|
||||||
attachInterrupt(digitalPinToInterrupt(RADIO_WAKEUP_PIN), wakeUpLoRaPacketReceived, RISING);
|
attachInterrupt(digitalPinToInterrupt(RADIO_WAKEUP_PIN), wakeUpLoRaPacketReceived, RISING);
|
||||||
#if defined(TTGO_LORA32_V2_1) || defined(TTGO_LORA32_V2_1_915) || defined(TTGO_LORA32_T3S3_V1_2) || defined(TTGO_T_BEAM_V1_0) || defined(TTGO_T_BEAM_V1_0_915) || defined(TTGO_T_BEAM_V1_0_SX1268) || defined(TTGO_T_BEAM_V1_2) || defined(TTGO_T_BEAM_V1_2_915) || defined(TTGO_T_BEAM_V1_2_SX1262) || defined(TTGO_T_DECK_PLUS) || defined(TTGO_T_DECK_GPS) || defined(TTGO_T_Beam_S3_SUPREME_V3) || defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WP) || defined(HELTEC_WS) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY) || defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V2) || defined(XIAO_ESP32S3_LORA) || defined(LIGHTGATEWAY_1_0) || defined(LIGHTGATEWAY_PLUS_1_0) || defined(TROY_LoRa_APRS) || defined(OE5HWN_MeshCom) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_LoRa_915) || defined(ESP32_DIY_1W_LoRa) || defined(ESP32_DIY_1W_LoRa_915) || defined(ESP32_DIY_1W_LoRa_LLCC68) || defined(ESP32_DIY_1W_LoRa_Mesh_V1_2) || defined(WEMOS_S2_MINI_DIY_LoRa) || defined(WEMOS_D1_R32_RA02) || defined(WEMOS_LOLIN32_OLED_DIY_LoRa)
|
#if defined(TTGO_LORA32_V2_1) || defined(TTGO_LORA32_V2_1_915) || defined(TTGO_LORA32_T3S3_V1_2) || defined(TTGO_T_BEAM_V1_0) || defined(TTGO_T_BEAM_V1_0_915) || defined(TTGO_T_BEAM_V1_0_SX1268) || defined(TTGO_T_BEAM_V1_2) || defined(TTGO_T_BEAM_V1_2_915) || defined(TTGO_T_BEAM_V1_2_SX1262) || defined(TTGO_T_DECK_PLUS) || defined(TTGO_T_DECK_GPS) || defined(TTGO_T_Beam_S3_SUPREME_V3) || defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WP_V1) || defined(HELTEC_WS) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY) || defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V2) || defined(XIAO_ESP32S3_LORA) || defined(LIGHTGATEWAY_1_0) || defined(LIGHTGATEWAY_PLUS_1_0) || defined(TROY_LoRa_APRS) || defined(OE5HWN_MeshCom) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_LoRa_915) || defined(ESP32_DIY_1W_LoRa) || defined(ESP32_DIY_1W_LoRa_915) || defined(ESP32_DIY_1W_LoRa_LLCC68) || defined(ESP32_DIY_1W_LoRa_Mesh_V1_2) || defined(WEMOS_S2_MINI_DIY_LoRa) || defined(WEMOS_D1_R32_RA02) || defined(WEMOS_LOLIN32_OLED_DIY_LoRa)
|
||||||
esp_sleep_enable_ext1_wakeup(GPIO_WAKEUP_PIN, ESP_EXT1_WAKEUP_ANY_HIGH);
|
esp_sleep_enable_ext1_wakeup(GPIO_WAKEUP_PIN, ESP_EXT1_WAKEUP_ANY_HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if defined(HELTEC_HTCT62) || defined(ESP32C3_DIY_1W_LoRa) || defined(ESP32C3_DIY_1W_LoRa_915) || defined(ESP32_C3_OctopusLab_LoRa)
|
#if defined(HELTEC_HTCT62) || defined(ESP32C3_DIY_1W_LoRa) || defined(ESP32C3_DIY_1W_LoRa_915) || defined(ESP32_C3_OctopusLab_LoRa)
|
||||||
|
|||||||
@@ -33,18 +33,31 @@ extern bool shouldSleepLowVoltage;
|
|||||||
|
|
||||||
uint32_t lastTxTime = millis();
|
uint32_t lastTxTime = millis();
|
||||||
std::vector<LastHeardStation> lastHeardStations;
|
std::vector<LastHeardStation> lastHeardStations;
|
||||||
std::vector<String> outputPacketBuffer;
|
|
||||||
std::vector<Packet25SegBuffer> packet25SegBuffer;
|
|
||||||
std::vector<String> blacklist;
|
std::vector<String> blacklist;
|
||||||
std::vector<String> managers;
|
std::vector<String> managers;
|
||||||
std::vector<LastHeardStation> lastHeardObjects;
|
std::vector<LastHeardStation> lastHeardObjects;
|
||||||
|
|
||||||
|
struct OutputPacketBuffer {
|
||||||
|
String packet;
|
||||||
|
bool isBeacon;
|
||||||
|
};
|
||||||
|
std::vector<OutputPacketBuffer> outputPacketBuffer;
|
||||||
|
|
||||||
|
struct Packet25SegBuffer {
|
||||||
|
uint32_t receivedTime;
|
||||||
|
String station;
|
||||||
|
String payload;
|
||||||
|
};
|
||||||
|
std::vector<Packet25SegBuffer> packet25SegBuffer;
|
||||||
|
|
||||||
|
|
||||||
bool saveNewDigiEcoModeConfig = false;
|
bool saveNewDigiEcoModeConfig = false;
|
||||||
|
bool packetIsBeacon = false;
|
||||||
|
|
||||||
|
|
||||||
namespace STATION_Utils {
|
namespace STATION_Utils {
|
||||||
|
|
||||||
std::vector<String> loadCallSignList(const String& list) {
|
std::vector<String> loadCallsignList(const String& list) {
|
||||||
std::vector<String> loadedList;
|
std::vector<String> loadedList;
|
||||||
|
|
||||||
String callsigns = list;
|
String callsigns = list;
|
||||||
@@ -64,12 +77,12 @@ namespace STATION_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loadBlacklistAndManagers() {
|
void loadBlacklistAndManagers() {
|
||||||
blacklist = loadCallSignList(Config.blacklist);
|
blacklist = loadCallsignList(Config.blacklist);
|
||||||
managers = loadCallSignList(Config.remoteManagement.managers);
|
managers = loadCallsignList(Config.remoteManagement.managers);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkCallsignList(const std::vector<String>& list, const String& callsign) {
|
bool checkCallsignList(const std::vector<String>& list, const String& callsign) {
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (size_t i = 0; i < list.size(); i++) {
|
||||||
int wildcardIndex = list[i].indexOf("*");
|
int wildcardIndex = list[i].indexOf("*");
|
||||||
if (wildcardIndex >= 0) {
|
if (wildcardIndex >= 0) {
|
||||||
String wildcard = list[i].substring(0, wildcardIndex);
|
String wildcard = list[i].substring(0, wildcardIndex);
|
||||||
@@ -138,7 +151,7 @@ namespace STATION_Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!stationHeard) lastHeardStations.emplace_back(LastHeardStation{millis(), station});
|
if (!stationHeard) lastHeardStations.emplace_back(LastHeardStation{millis(), station});
|
||||||
Utils::activeStations();
|
Utils::showActiveStations();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wasHeard(const String& station) {
|
bool wasHeard(const String& station) {
|
||||||
@@ -171,7 +184,9 @@ namespace STATION_Utils {
|
|||||||
size_t currentIndex = 0;
|
size_t currentIndex = 0;
|
||||||
while (currentIndex < outputPacketBuffer.size()) { // this sends all packets from output buffer
|
while (currentIndex < outputPacketBuffer.size()) { // this sends all packets from output buffer
|
||||||
delay(3000); // and cleans buffer to avoid sending packets with time offset
|
delay(3000); // and cleans buffer to avoid sending packets with time offset
|
||||||
LoRa_Utils::sendNewPacket(outputPacketBuffer[currentIndex]); // next time it wakes up
|
if (outputPacketBuffer[currentIndex].isBeacon) packetIsBeacon = true;
|
||||||
|
LoRa_Utils::sendNewPacket(outputPacketBuffer[currentIndex].packet); // next time it wakes up
|
||||||
|
if (outputPacketBuffer[currentIndex].isBeacon) packetIsBeacon = false;
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
}
|
}
|
||||||
outputPacketBuffer.clear();
|
outputPacketBuffer.clear();
|
||||||
@@ -190,13 +205,17 @@ namespace STATION_Utils {
|
|||||||
uint32_t lastRx = millis() - lastRxTime;
|
uint32_t lastRx = millis() - lastRxTime;
|
||||||
uint32_t lastTx = millis() - lastTxTime;
|
uint32_t lastTx = millis() - lastTxTime;
|
||||||
if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) {
|
if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) {
|
||||||
LoRa_Utils::sendNewPacket(outputPacketBuffer[0]);
|
if (outputPacketBuffer[0].isBeacon) packetIsBeacon = true;
|
||||||
|
LoRa_Utils::sendNewPacket(outputPacketBuffer[0].packet);
|
||||||
|
if (outputPacketBuffer[0].isBeacon) packetIsBeacon = false;
|
||||||
outputPacketBuffer.erase(outputPacketBuffer.begin());
|
outputPacketBuffer.erase(outputPacketBuffer.begin());
|
||||||
lastTxTime = millis();
|
lastTxTime = millis();
|
||||||
}
|
}
|
||||||
if (shouldSleepLowVoltage) {
|
if (shouldSleepLowVoltage) {
|
||||||
while (outputPacketBuffer.size() > 0) {
|
while (outputPacketBuffer.size() > 0) {
|
||||||
LoRa_Utils::sendNewPacket(outputPacketBuffer[0]);
|
if (outputPacketBuffer[0].isBeacon) packetIsBeacon = true;
|
||||||
|
LoRa_Utils::sendNewPacket(outputPacketBuffer[0].packet);
|
||||||
|
if (outputPacketBuffer[0].isBeacon) packetIsBeacon = false;
|
||||||
outputPacketBuffer.erase(outputPacketBuffer.begin());
|
outputPacketBuffer.erase(outputPacketBuffer.begin());
|
||||||
delay(4000);
|
delay(4000);
|
||||||
}
|
}
|
||||||
@@ -209,8 +228,12 @@ namespace STATION_Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addToOutputPacketBuffer(const String& packet) {
|
void addToOutputPacketBuffer(const String& packet, bool flag) {
|
||||||
outputPacketBuffer.push_back(packet);
|
OutputPacketBuffer entry;
|
||||||
|
entry.packet = packet;
|
||||||
|
entry.isBeacon = flag;
|
||||||
|
|
||||||
|
outputPacketBuffer.push_back(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern String versionDate;
|
extern String versionDate;
|
||||||
|
extern String versionNumber;
|
||||||
|
|
||||||
WiFiUDP udpClient;
|
WiFiUDP udpClient;
|
||||||
|
|
||||||
@@ -35,7 +36,9 @@ namespace SYSLOG_Utils {
|
|||||||
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
|
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
|
||||||
String syslogPacket = "<165>1 - ";
|
String syslogPacket = "<165>1 - ";
|
||||||
syslogPacket.concat(Config.callsign);
|
syslogPacket.concat(Config.callsign);
|
||||||
syslogPacket.concat(" CA2RXU_LoRa_iGate_3.0 - - - "); //RFC5424 The Syslog Protocol
|
syslogPacket.concat(" CA2RXU_LoRa_iGate_");
|
||||||
|
syslogPacket.concat(versionNumber);
|
||||||
|
syslogPacket.concat(" - - - "); //RFC5424 The Syslog Protocol
|
||||||
|
|
||||||
char signalData[35];
|
char signalData[35];
|
||||||
snprintf(signalData, sizeof(signalData), " / %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
|
snprintf(signalData, sizeof(signalData), " / %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ namespace TELEMETRY_Utils {
|
|||||||
telemetryCounter++;
|
telemetryCounter++;
|
||||||
if (telemetryCounter == 1000) telemetryCounter = 0;
|
if (telemetryCounter == 1000) telemetryCounter = 0;
|
||||||
if (Config.battery.sendInternalVoltage) telemetry += generateEncodedTelemetryBytes(BATTERY_Utils::checkInternalVoltage(), false, 0);
|
if (Config.battery.sendInternalVoltage) telemetry += generateEncodedTelemetryBytes(BATTERY_Utils::checkInternalVoltage(), false, 0);
|
||||||
if (Config.battery.sendExternalVoltage) telemetry += generateEncodedTelemetryBytes(BATTERY_Utils::checkExternalVoltage(), false, 1);
|
if (Config.battery.sendExternalVoltage) telemetry += generateEncodedTelemetryBytes(BATTERY_Utils::checkExternalVoltage(), false, Config.battery.useExternalI2CSensor ? 0 : 1);
|
||||||
telemetry += "|";
|
telemetry += "|";
|
||||||
return telemetry;
|
return telemetry;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
#include "ESPmDNS.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "station_utils.h"
|
#include "station_utils.h"
|
||||||
#include "kiss_protocol.h"
|
#include "kiss_protocol.h"
|
||||||
|
#include "aprs_is_utils.h"
|
||||||
#include "kiss_utils.h"
|
#include "kiss_utils.h"
|
||||||
|
#include "tnc_utils.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
|
extern WiFiClient aprsIsClient;
|
||||||
|
extern bool passcodeValid;
|
||||||
|
|
||||||
#define MAX_CLIENTS 4
|
#define MAX_CLIENTS 4
|
||||||
#define INPUT_BUFFER_SIZE (2 + MAX_CLIENTS)
|
#define INPUT_BUFFER_SIZE (2 + MAX_CLIENTS)
|
||||||
@@ -45,6 +50,17 @@ namespace TNC_Utils {
|
|||||||
if (Config.tnc.enableServer && Config.digi.ecoMode == 0) {
|
if (Config.tnc.enableServer && Config.digi.ecoMode == 0) {
|
||||||
tncServer.stop();
|
tncServer.stop();
|
||||||
tncServer.begin();
|
tncServer.begin();
|
||||||
|
String host = "igate-" + Config.callsign;
|
||||||
|
if (!MDNS.begin(host.c_str())) {
|
||||||
|
Serial.println("Error Starting mDNS");
|
||||||
|
tncServer.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!MDNS.addService("tnc", "tcp", TNC_PORT)) {
|
||||||
|
Serial.println("Error: Could not add mDNS service");
|
||||||
|
}
|
||||||
|
Serial.println("TNC server started successfully");
|
||||||
|
Serial.println("mDNS Host: " + host + ".local");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +97,8 @@ namespace TNC_Utils {
|
|||||||
String sender = frame.substring(0,frame.indexOf(">"));
|
String sender = frame.substring(0,frame.indexOf(">"));
|
||||||
|
|
||||||
if (Config.tnc.acceptOwn || sender != Config.callsign) {
|
if (Config.tnc.acceptOwn || sender != Config.callsign) {
|
||||||
STATION_Utils::addToOutputPacketBuffer(frame);
|
if (Config.loramodule.txActive) STATION_Utils::addToOutputPacketBuffer(frame);
|
||||||
|
if (Config.tnc.aprsBridgeActive && Config.aprs_is.active && passcodeValid && aprsIsClient.connected()) APRS_IS_Utils::upload(frame);
|
||||||
} else {
|
} else {
|
||||||
Utils::println("Ignored own frame from KISS");
|
Utils::println("Ignored own frame from KISS");
|
||||||
}
|
}
|
||||||
@@ -118,8 +135,8 @@ namespace TNC_Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendToClients(const String& packet) {
|
void sendToClients(const String& packet, bool stripBytes) {
|
||||||
String cleanPacket = packet.substring(3);
|
String cleanPacket = stripBytes ? packet.substring(3): packet;
|
||||||
|
|
||||||
const String kissEncoded = encodeKISS(cleanPacket);
|
const String kissEncoded = encodeKISS(cleanPacket);
|
||||||
|
|
||||||
@@ -139,8 +156,8 @@ namespace TNC_Utils {
|
|||||||
Utils::println(cleanPacket);
|
Utils::println(cleanPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendToSerial(const String& packet) {
|
void sendToSerial(const String& packet, bool stripBytes) {
|
||||||
String cleanPacket = packet.substring(3);
|
String cleanPacket = stripBytes ? packet.substring(3): packet;
|
||||||
Serial.print(encodeKISS(cleanPacket));
|
Serial.print(encodeKISS(cleanPacket));
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <APRSPacketLib.h>
|
||||||
#include <TinyGPS++.h>
|
#include <TinyGPS++.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include "telemetry_utils.h"
|
#include "telemetry_utils.h"
|
||||||
@@ -35,7 +36,6 @@
|
|||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern WiFiClient espClient;
|
|
||||||
extern TinyGPSPlus gps;
|
extern TinyGPSPlus gps;
|
||||||
extern String versionDate;
|
extern String versionDate;
|
||||||
extern String firstLine;
|
extern String firstLine;
|
||||||
@@ -72,12 +72,8 @@ String secondaryBeaconPacket;
|
|||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
void processStatus() {
|
void processStatus() {
|
||||||
String status = Config.callsign;
|
String status = APRSPacketLib::generateBasePacket(Config.callsign, "APLRG1", Config.beacon.path);
|
||||||
status.concat(">APLRG1");
|
|
||||||
if (Config.beacon.path.indexOf("WIDE") == 0) {
|
|
||||||
status.concat(",");
|
|
||||||
status.concat(Config.beacon.path);
|
|
||||||
}
|
|
||||||
if (WiFi.status() == WL_CONNECTED && Config.aprs_is.active && Config.beacon.sendViaAPRSIS) {
|
if (WiFi.status() == WL_CONNECTED && Config.aprs_is.active && Config.beacon.sendViaAPRSIS) {
|
||||||
delay(1000);
|
delay(1000);
|
||||||
status.concat(",qAC:>");
|
status.concat(",qAC:>");
|
||||||
@@ -89,7 +85,7 @@ namespace Utils {
|
|||||||
if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) {
|
if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) {
|
||||||
status.concat(":>");
|
status.concat(":>");
|
||||||
status.concat(Config.beacon.statusPacket);
|
status.concat(Config.beacon.statusPacket);
|
||||||
STATION_Utils::addToOutputPacketBuffer(status);
|
STATION_Utils::addToOutputPacketBuffer(status, true); // treated also as beacon on Tx Freq
|
||||||
statusAfterBoot = false;
|
statusAfterBoot = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,7 +124,7 @@ namespace Utils {
|
|||||||
seventhLine = " listening...";
|
seventhLine = " listening...";
|
||||||
}
|
}
|
||||||
|
|
||||||
void activeStations() {
|
void showActiveStations() {
|
||||||
char buffer[30]; // Adjust size as needed
|
char buffer[30]; // Adjust size as needed
|
||||||
sprintf(buffer, "Stations (%dmin) = %2d", Config.rememberStationTime, lastHeardStations.size());
|
sprintf(buffer, "Stations (%dmin) = %2d", Config.rememberStationTime, lastHeardStations.size());
|
||||||
fourthLine = buffer;
|
fourthLine = buffer;
|
||||||
@@ -160,7 +156,7 @@ namespace Utils {
|
|||||||
|
|
||||||
STATION_Utils::deleteNotHeard();
|
STATION_Utils::deleteNotHeard();
|
||||||
|
|
||||||
activeStations();
|
showActiveStations();
|
||||||
|
|
||||||
beaconPacket = iGateBeaconPacket;
|
beaconPacket = iGateBeaconPacket;
|
||||||
secondaryBeaconPacket = iGateLoRaBeaconPacket;
|
secondaryBeaconPacket = iGateLoRaBeaconPacket;
|
||||||
@@ -168,10 +164,18 @@ namespace Utils {
|
|||||||
if (Config.beacon.gpsActive && Config.digi.ecoMode == 0) {
|
if (Config.beacon.gpsActive && Config.digi.ecoMode == 0) {
|
||||||
GPS_Utils::getData();
|
GPS_Utils::getData();
|
||||||
if (gps.location.isUpdated() && gps.location.lat() != 0.0 && gps.location.lng() != 0.0) {
|
if (gps.location.isUpdated() && gps.location.lat() != 0.0 && gps.location.lng() != 0.0) {
|
||||||
GPS_Utils::generateBeaconFirstPart();
|
String basePacket = APRSPacketLib::generateBasePacket(Config.callsign, "APLRG1", Config.beacon.path);
|
||||||
String encodedGPS = GPS_Utils::encodeGPS(gps.location.lat(), gps.location.lng(), Config.beacon.overlay, Config.beacon.symbol);
|
String encodedGPS = APRSPacketLib::encodeGPSIntoBase91(gps.location.lat(),gps.location.lng(), 0, 0, Config.beacon.symbol, false, 0, true, Config.beacon.ambiguityLevel);
|
||||||
beaconPacket = iGateBeaconPacket + encodedGPS;
|
|
||||||
secondaryBeaconPacket = iGateLoRaBeaconPacket + encodedGPS;
|
beaconPacket = basePacket;
|
||||||
|
beaconPacket += ",qAC:!";
|
||||||
|
beaconPacket += Config.beacon.overlay;
|
||||||
|
beaconPacket += encodedGPS;
|
||||||
|
|
||||||
|
secondaryBeaconPacket = basePacket;
|
||||||
|
secondaryBeaconPacket += ":=";
|
||||||
|
secondaryBeaconPacket += Config.beacon.overlay;
|
||||||
|
secondaryBeaconPacket += encodedGPS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -211,7 +215,7 @@ namespace Utils {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HELTEC_WP
|
#ifndef HELTEC_WP_V1
|
||||||
if (Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) {
|
if (Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) {
|
||||||
float externalVoltage = BATTERY_Utils::checkExternalVoltage();
|
float externalVoltage = BATTERY_Utils::checkExternalVoltage();
|
||||||
if (Config.battery.monitorExternalVoltage && externalVoltage < Config.battery.externalSleepVoltage) {
|
if (Config.battery.monitorExternalVoltage && externalVoltage < Config.battery.externalSleepVoltage) {
|
||||||
@@ -260,7 +264,7 @@ namespace Utils {
|
|||||||
Utils::println("-- Sending Beacon to RF --");
|
Utils::println("-- Sending Beacon to RF --");
|
||||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING DIGI BEACON", 0);
|
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING DIGI BEACON", 0);
|
||||||
seventhLine = " listening...";
|
seventhLine = " listening...";
|
||||||
STATION_Utils::addToOutputPacketBuffer(secondaryBeaconPacket);
|
STATION_Utils::addToOutputPacketBuffer(secondaryBeaconPacket, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastBeaconTx = millis();
|
lastBeaconTx = millis();
|
||||||
@@ -285,6 +289,7 @@ namespace Utils {
|
|||||||
Serial.println("Tx Freq less than 125kHz from Rx Freq ---> NOT VALID");
|
Serial.println("Tx Freq less than 125kHz from Rx Freq ---> NOT VALID");
|
||||||
displayShow("Tx Freq is less than ", "125kHz from Rx Freq", "device will autofix", "and then reboot", 1000);
|
displayShow("Tx Freq is less than ", "125kHz from Rx Freq", "device will autofix", "and then reboot", 1000);
|
||||||
Config.loramodule.txFreq = Config.loramodule.rxFreq; // Inform about that but then change the TX QRG to RX QRG and reset the device
|
Config.loramodule.txFreq = Config.loramodule.rxFreq; // Inform about that but then change the TX QRG to RX QRG and reset the device
|
||||||
|
Config.beacon.beaconFreq = 1; // return to LoRa Tx Beacon Freq
|
||||||
Config.writeFile();
|
Config.writeFile();
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
@@ -402,6 +407,7 @@ namespace Utils {
|
|||||||
cleanCallsign = callsign.substring(0, callsign.indexOf("-"));
|
cleanCallsign = callsign.substring(0, callsign.indexOf("-"));
|
||||||
String ssid = callsign.substring(callsign.indexOf("-") + 1);
|
String ssid = callsign.substring(callsign.indexOf("-") + 1);
|
||||||
if (ssid.indexOf("-") != -1 || ssid.length() > 2) return false;
|
if (ssid.indexOf("-") != -1 || ssid.length() > 2) return false;
|
||||||
|
if (ssid.length() == 2 && ssid[0] == '0') return false;
|
||||||
for (int i = 0; i < ssid.length(); i++) {
|
for (int i = 0; i < ssid.length(); i++) {
|
||||||
if (!isAlphaNumeric(ssid[i])) return false;
|
if (!isAlphaNumeric(ssid[i])) return false;
|
||||||
}
|
}
|
||||||
@@ -437,4 +443,11 @@ namespace Utils {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void startupDelay() {
|
||||||
|
if (Config.startupDelay > 0) {
|
||||||
|
displayShow("", " STARTUP DELAY ...", "", "", 0);
|
||||||
|
delay(Config.startupDelay * 60 * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -115,139 +115,212 @@ namespace WEB_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handleWriteConfiguration(AsyncWebServerRequest *request) {
|
void handleWriteConfiguration(AsyncWebServerRequest *request) {
|
||||||
Serial.println("Got new config from www");
|
Serial.println("Got new Configuration Data from www");
|
||||||
|
|
||||||
int networks = request->getParam("wifi.APs", true)->value().toInt();
|
auto getParamStringSafe = [&](const String& name, const String& defaultValue = "") -> String {
|
||||||
|
if (request->hasParam(name, true)) {
|
||||||
|
return request->getParam(name, true)->value();
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto getParamIntSafe = [&](const String& name, int defaultValue = 0) -> int {
|
||||||
|
if (request->hasParam(name, true)) {
|
||||||
|
return request->getParam(name, true)->value().toInt();
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto getParamFloatSafe = [&](const String& name, float defaultValue = 0.0) -> float {
|
||||||
|
if (request->hasParam(name, true)) {
|
||||||
|
return request->getParam(name, true)->value().toFloat();
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto getParamDoubleSafe = [&](const String& name, double defaultValue = 0.0) -> double {
|
||||||
|
if (request->hasParam(name, true)) {
|
||||||
|
return request->getParam(name, true)->value().toDouble();
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
int networks = getParamIntSafe("wifi.APs");
|
||||||
|
|
||||||
Config.wifiAPs = {};
|
Config.wifiAPs = {};
|
||||||
|
|
||||||
for (int i = 0; i < networks; i++) {
|
for (int i = 0; i < networks; i++) {
|
||||||
WiFi_AP wifiap;
|
WiFi_AP wifiap;
|
||||||
wifiap.ssid = request->getParam("wifi.AP." + String(i) + ".ssid", true)->value();
|
wifiap.ssid = getParamStringSafe("wifi.AP." + String(i) + ".ssid");
|
||||||
wifiap.password = request->getParam("wifi.AP." + String(i) + ".password", true)->value();
|
wifiap.password = getParamStringSafe("wifi.AP." + String(i) + ".password");
|
||||||
|
|
||||||
Config.wifiAPs.push_back(wifiap);
|
Config.wifiAPs.push_back(wifiap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.callsign = request->getParam("callsign", true)->value();
|
Config.startupDelay = getParamIntSafe("startupDelay", Config.startupDelay);
|
||||||
|
|
||||||
Config.wifiAutoAP.password = request->getParam("wifi.autoAP.password", true)->value();
|
Config.callsign = getParamStringSafe("callsign", Config.callsign);
|
||||||
Config.wifiAutoAP.timeout = request->getParam("wifi.autoAP.timeout", true)->value().toInt();
|
|
||||||
|
|
||||||
|
Config.wifiAutoAP.password = getParamStringSafe("wifi.autoAP.password", Config.wifiAutoAP.password);
|
||||||
|
Config.wifiAutoAP.timeout = getParamIntSafe("wifi.autoAP.timeout", Config.wifiAutoAP.timeout);
|
||||||
|
|
||||||
Config.aprs_is.active = request->hasParam("aprs_is.active", true);
|
Config.aprs_is.active = request->hasParam("aprs_is.active", true);
|
||||||
Config.aprs_is.passcode = request->getParam("aprs_is.passcode", true)->value();
|
if (Config.aprs_is.active) {
|
||||||
Config.aprs_is.server = request->getParam("aprs_is.server", true)->value();
|
|
||||||
Config.aprs_is.port = request->getParam("aprs_is.port", true)->value().toInt();
|
|
||||||
Config.aprs_is.filter = request->getParam("aprs_is.filter", true)->value();
|
|
||||||
Config.aprs_is.messagesToRF = request->hasParam("aprs_is.messagesToRF", true);
|
Config.aprs_is.messagesToRF = request->hasParam("aprs_is.messagesToRF", true);
|
||||||
Config.aprs_is.objectsToRF = request->hasParam("aprs_is.objectsToRF", true);
|
Config.aprs_is.objectsToRF = request->hasParam("aprs_is.objectsToRF", true);
|
||||||
|
Config.aprs_is.server = getParamStringSafe("aprs_is.server", Config.aprs_is.server);
|
||||||
|
Config.aprs_is.passcode = getParamStringSafe("aprs_is.passcode", Config.aprs_is.passcode);
|
||||||
|
Config.aprs_is.port = getParamIntSafe("aprs_is.port", Config.aprs_is.port);
|
||||||
|
Config.aprs_is.filter = getParamStringSafe("aprs_is.filter", Config.aprs_is.filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.beacon.interval = getParamIntSafe("beacon.interval", Config.beacon.interval);
|
||||||
Config.beacon.interval = request->getParam("beacon.interval", true)->value().toInt();
|
|
||||||
Config.beacon.sendViaAPRSIS = request->hasParam("beacon.sendViaAPRSIS", true);
|
Config.beacon.sendViaAPRSIS = request->hasParam("beacon.sendViaAPRSIS", true);
|
||||||
Config.beacon.sendViaRF = request->hasParam("beacon.sendViaRF", true);
|
Config.beacon.sendViaRF = request->hasParam("beacon.sendViaRF", true);
|
||||||
Config.beacon.latitude = request->getParam("beacon.latitude", true)->value().toDouble();
|
Config.beacon.beaconFreq = getParamIntSafe("beacon.beaconFreq", Config.beacon.beaconFreq);
|
||||||
Config.beacon.longitude = request->getParam("beacon.longitude", true)->value().toDouble();
|
Config.beacon.latitude = getParamDoubleSafe("beacon.latitude", Config.beacon.latitude);
|
||||||
Config.beacon.comment = request->getParam("beacon.comment", true)->value();
|
Config.beacon.longitude = getParamDoubleSafe("beacon.longitude", Config.beacon.longitude);
|
||||||
Config.beacon.overlay = request->getParam("beacon.overlay", true)->value();
|
Config.beacon.comment = getParamStringSafe("beacon.comment", Config.beacon.comment);
|
||||||
Config.beacon.symbol = request->getParam("beacon.symbol", true)->value();
|
Config.beacon.overlay = getParamStringSafe("beacon.overlay", Config.beacon.overlay);
|
||||||
Config.beacon.path = request->getParam("beacon.path", true)->value();
|
Config.beacon.symbol = getParamStringSafe("beacon.symbol", Config.beacon.symbol);
|
||||||
|
Config.beacon.path = getParamStringSafe("beacon.path", Config.beacon.path);
|
||||||
|
|
||||||
Config.beacon.statusActive = request->hasParam("beacon.statusActive", true);
|
Config.beacon.statusActive = request->hasParam("beacon.statusActive", true);
|
||||||
Config.beacon.statusPacket = request->getParam("beacon.statusPacket", true)->value();
|
if (Config.beacon.statusActive) {
|
||||||
|
Config.beacon.statusPacket = getParamStringSafe("beacon.statusPacket", Config.beacon.statusPacket);
|
||||||
|
}
|
||||||
|
|
||||||
Config.beacon.gpsActive = request->hasParam("beacon.gpsActive", true);
|
Config.beacon.gpsActive = request->hasParam("beacon.gpsActive", true);
|
||||||
Config.beacon.gpsAmbiguity = request->hasParam("beacon.gpsAmbiguity", true);
|
Config.beacon.ambiguityLevel = getParamIntSafe("beacon.ambiguityLevel", Config.beacon.ambiguityLevel);
|
||||||
|
|
||||||
|
Config.personalNote = getParamStringSafe("personalNote", Config.personalNote);
|
||||||
|
|
||||||
|
Config.blacklist = getParamStringSafe("blacklist", Config.blacklist);
|
||||||
|
|
||||||
|
Config.digi.mode = getParamIntSafe("digi.mode", Config.digi.mode);
|
||||||
|
Config.digi.ecoMode = getParamIntSafe("digi.ecoMode", Config.digi.ecoMode);
|
||||||
|
|
||||||
|
|
||||||
Config.digi.mode = request->getParam("digi.mode", true)->value().toInt();
|
|
||||||
Config.digi.ecoMode = request->getParam("digi.ecoMode", true)->value().toInt();;
|
|
||||||
|
|
||||||
|
|
||||||
Config.loramodule.txFreq = request->getParam("lora.txFreq", true)->value().toInt();
|
|
||||||
Config.loramodule.rxFreq = request->getParam("lora.rxFreq", true)->value().toInt();
|
|
||||||
Config.loramodule.spreadingFactor = request->getParam("lora.spreadingFactor", true)->value().toInt();
|
|
||||||
Config.loramodule.signalBandwidth = request->getParam("lora.signalBandwidth", true)->value().toInt();
|
|
||||||
Config.loramodule.codingRate4 = request->getParam("lora.codingRate4", true)->value().toInt();
|
|
||||||
Config.loramodule.power = request->getParam("lora.power", true)->value().toInt();
|
|
||||||
Config.loramodule.txActive = request->hasParam("lora.txActive", true);
|
|
||||||
Config.loramodule.rxActive = request->hasParam("lora.rxActive", true);
|
Config.loramodule.rxActive = request->hasParam("lora.rxActive", true);
|
||||||
|
Config.loramodule.rxFreq = getParamIntSafe("lora.rxFreq", Config.loramodule.rxFreq);
|
||||||
|
Config.loramodule.rxSpreadingFactor = getParamIntSafe("lora.rxSpreadingFactor", Config.loramodule.rxSpreadingFactor);
|
||||||
|
Config.loramodule.rxCodingRate4 = getParamIntSafe("lora.rxCodingRate4", Config.loramodule.rxCodingRate4);
|
||||||
|
Config.loramodule.rxSignalBandwidth = getParamIntSafe("lora.rxSignalBandwidth", Config.loramodule.rxSignalBandwidth);
|
||||||
|
Config.loramodule.txActive = request->hasParam("lora.txActive", true);
|
||||||
|
Config.loramodule.txFreq = getParamIntSafe("lora.txFreq", Config.loramodule.txFreq);
|
||||||
|
Config.loramodule.txSpreadingFactor = getParamIntSafe("lora.txSpreadingFactor", Config.loramodule.txSpreadingFactor);
|
||||||
|
Config.loramodule.txCodingRate4 = getParamIntSafe("lora.txCodingRate4", Config.loramodule.txCodingRate4);
|
||||||
|
Config.loramodule.txSignalBandwidth = getParamIntSafe("lora.txSignalBandwidth", Config.loramodule.txSignalBandwidth);
|
||||||
|
Config.loramodule.power = getParamIntSafe("lora.power", Config.loramodule.power);
|
||||||
|
|
||||||
|
|
||||||
Config.display.alwaysOn = request->hasParam("display.alwaysOn", true);
|
Config.display.alwaysOn = request->hasParam("display.alwaysOn", true);
|
||||||
if (!Config.display.alwaysOn) {
|
if (!Config.display.alwaysOn) {
|
||||||
Config.display.timeout = request->getParam("display.timeout", true)->value().toInt();
|
Config.display.timeout = getParamIntSafe("display.timeout", Config.display.timeout);
|
||||||
}
|
}
|
||||||
Config.display.turn180 = request->hasParam("display.turn180", true);
|
Config.display.turn180 = request->hasParam("display.turn180", true);
|
||||||
|
|
||||||
|
|
||||||
Config.battery.sendInternalVoltage = request->hasParam("battery.sendInternalVoltage", true);
|
Config.battery.sendInternalVoltage = request->hasParam("battery.sendInternalVoltage", true);
|
||||||
Config.battery.monitorInternalVoltage = request->hasParam("battery.monitorInternalVoltage", true);
|
Config.battery.monitorInternalVoltage = request->hasParam("battery.monitorInternalVoltage", true);
|
||||||
Config.battery.internalSleepVoltage = request->getParam("battery.internalSleepVoltage", true)->value().toFloat();
|
if (Config.battery.monitorInternalVoltage) {
|
||||||
|
Config.battery.internalSleepVoltage = getParamFloatSafe("battery.internalSleepVoltage", Config.battery.internalSleepVoltage);
|
||||||
|
}
|
||||||
|
|
||||||
Config.battery.sendExternalVoltage = request->hasParam("battery.sendExternalVoltage", true);
|
Config.battery.sendExternalVoltage = request->hasParam("battery.sendExternalVoltage", true);
|
||||||
if (Config.battery.sendExternalVoltage) {
|
if (Config.battery.sendExternalVoltage) {
|
||||||
Config.battery.externalVoltagePin = request->getParam("battery.externalVoltagePin", true)->value().toInt();
|
Config.battery.useExternalI2CSensor = request->hasParam("battery.useExternalI2CSensor", true);
|
||||||
Config.battery.voltageDividerR1 = request->getParam("battery.voltageDividerR1", true)->value().toFloat();
|
}
|
||||||
Config.battery.voltageDividerR2 = request->getParam("battery.voltageDividerR2", true)->value().toFloat();
|
if (Config.battery.sendExternalVoltage) {
|
||||||
|
Config.battery.externalVoltagePin = getParamIntSafe("battery.externalVoltagePin", Config.battery.externalVoltagePin);
|
||||||
|
Config.battery.voltageDividerR1 = getParamFloatSafe("battery.voltageDividerR1", Config.battery.voltageDividerR1);
|
||||||
|
Config.battery.voltageDividerR2 = getParamFloatSafe("battery.voltageDividerR2", Config.battery.voltageDividerR2);
|
||||||
}
|
}
|
||||||
Config.battery.monitorExternalVoltage = request->hasParam("battery.monitorExternalVoltage", true);
|
Config.battery.monitorExternalVoltage = request->hasParam("battery.monitorExternalVoltage", true);
|
||||||
Config.battery.externalSleepVoltage = request->getParam("battery.externalSleepVoltage", true)->value().toFloat();
|
if (Config.battery.monitorExternalVoltage) {
|
||||||
|
Config.battery.externalSleepVoltage = getParamFloatSafe("battery.externalSleepVoltage", Config.battery.externalSleepVoltage);
|
||||||
|
}
|
||||||
Config.battery.sendVoltageAsTelemetry = request->hasParam("battery.sendVoltageAsTelemetry", true);
|
Config.battery.sendVoltageAsTelemetry = request->hasParam("battery.sendVoltageAsTelemetry", true);
|
||||||
|
|
||||||
|
|
||||||
Config.wxsensor.active = request->hasParam("wxsensor.active", true);
|
Config.wxsensor.active = request->hasParam("wxsensor.active", true);
|
||||||
Config.wxsensor.heightCorrection = request->getParam("wxsensor.heightCorrection", true)->value().toInt();
|
|
||||||
Config.wxsensor.temperatureCorrection = request->getParam("wxsensor.temperatureCorrection", true)->value().toFloat();
|
|
||||||
if (Config.wxsensor.active) {
|
if (Config.wxsensor.active) {
|
||||||
|
Config.wxsensor.heightCorrection = getParamIntSafe("wxsensor.heightCorrection", Config.wxsensor.heightCorrection);
|
||||||
|
Config.wxsensor.temperatureCorrection = getParamFloatSafe("wxsensor.temperatureCorrection", Config.wxsensor.temperatureCorrection);
|
||||||
Config.beacon.symbol = "_";
|
Config.beacon.symbol = "_";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Config.syslog.active = request->hasParam("syslog.active", true);
|
Config.syslog.active = request->hasParam("syslog.active", true);
|
||||||
if (Config.syslog.active) {
|
if (Config.syslog.active) {
|
||||||
Config.syslog.server = request->getParam("syslog.server", true)->value();
|
Config.syslog.server = getParamStringSafe("syslog.server", Config.syslog.server);
|
||||||
Config.syslog.port = request->getParam("syslog.port", true)->value().toInt();
|
Config.syslog.port = getParamIntSafe("syslog.port", Config.syslog.port);
|
||||||
Config.syslog.logBeaconOverTCPIP = request->hasParam("syslog.logBeaconOverTCPIP", true);
|
Config.syslog.logBeaconOverTCPIP = request->hasParam("syslog.logBeaconOverTCPIP", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
|
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
|
||||||
Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true);
|
Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true);
|
||||||
Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true);
|
Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true);
|
||||||
|
Config.tnc.aprsBridgeActive = request->hasParam("tnc.aprsBridgeActive", true);
|
||||||
|
|
||||||
|
|
||||||
|
Config.mqtt.active = request->hasParam("mqtt.active", true);
|
||||||
|
if (Config.mqtt.active) {
|
||||||
|
Config.mqtt.server = getParamStringSafe("mqtt.server", Config.mqtt.server);
|
||||||
|
Config.mqtt.topic = getParamStringSafe("mqtt.topic", Config.mqtt.topic);
|
||||||
|
Config.mqtt.username = getParamStringSafe("mqtt.username", Config.mqtt.username);
|
||||||
|
Config.mqtt.password = getParamStringSafe("mqtt.password", Config.mqtt.password);
|
||||||
|
Config.mqtt.port = getParamIntSafe("mqtt.port", Config.mqtt.port);
|
||||||
|
Config.mqtt.beaconOverMqtt = request->hasParam("mqtt.beaconOverMqtt", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Config.rebootMode = request->hasParam("other.rebootMode", true);
|
Config.rebootMode = request->hasParam("other.rebootMode", true);
|
||||||
Config.rebootModeTime = request->getParam("other.rebootModeTime", true)->value().toInt();
|
if (Config.rebootMode) {
|
||||||
|
Config.rebootModeTime = getParamIntSafe("other.rebootModeTime", Config.rebootModeTime);
|
||||||
|
}
|
||||||
|
|
||||||
Config.ota.username = request->getParam("ota.username", true)->value();
|
Config.ota.username = getParamStringSafe("ota.username", Config.ota.username);
|
||||||
Config.ota.password = request->getParam("ota.password", true)->value();
|
Config.ota.password = getParamStringSafe("ota.password", Config.ota.password);
|
||||||
|
|
||||||
Config.rememberStationTime = request->getParam("other.rememberStationTime", true)->value().toInt();
|
|
||||||
|
|
||||||
Config.backupDigiMode = request->hasParam("other.backupDigiMode", true);
|
|
||||||
|
|
||||||
Config.personalNote = request->getParam("personalNote", true)->value();
|
|
||||||
|
|
||||||
Config.blacklist = request->getParam("blacklist", true)->value();
|
|
||||||
|
|
||||||
Config.webadmin.active = request->hasParam("webadmin.active", true);
|
Config.webadmin.active = request->hasParam("webadmin.active", true);
|
||||||
if (Config.webadmin.active) {
|
if (Config.webadmin.active) {
|
||||||
Config.webadmin.username = request->getParam("webadmin.username", true)->value();
|
Config.webadmin.username = getParamStringSafe("webadmin.username", Config.webadmin.username);
|
||||||
Config.webadmin.password = request->getParam("webadmin.password", true)->value();
|
Config.webadmin.password = getParamStringSafe("webadmin.password", Config.webadmin.password);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.ntp.gmtCorrection = request->getParam("ntp.gmtCorrection", true)->value().toFloat();
|
Config.remoteManagement.managers = getParamStringSafe("remoteManagement.managers", Config.remoteManagement.managers);
|
||||||
|
Config.remoteManagement.rfOnly = request->hasParam("remoteManagement.rfOnly", true);
|
||||||
|
|
||||||
Config.remoteManagement.managers = request->getParam("remoteManagement.managers", true)->value();
|
Config.ntp.server = getParamStringSafe("ntp.server", Config.ntp.server);
|
||||||
Config.remoteManagement.rfOnly = request->getParam("remoteManagement.rfOnly", true);
|
Config.ntp.gmtCorrection = getParamFloatSafe("ntp.gmtCorrection", Config.ntp.gmtCorrection);
|
||||||
|
|
||||||
Config.writeFile();
|
Config.rememberStationTime = getParamIntSafe("other.rememberStationTime", Config.rememberStationTime);
|
||||||
|
|
||||||
|
Config.backupDigiMode = request->hasParam("other.backupDigiMode", true);
|
||||||
|
|
||||||
|
bool saveSuccess = Config.writeFile();
|
||||||
|
|
||||||
|
if (saveSuccess) {
|
||||||
|
Serial.println("Configuration saved successfully");
|
||||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
|
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
|
||||||
response->addHeader("Location", "/");
|
response->addHeader("Location", "/?success=1");
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
|
||||||
displayToggle(false);
|
displayToggle(false);
|
||||||
delay(200);
|
delay(500);
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
|
} else {
|
||||||
|
Serial.println("Error saving configuration!");
|
||||||
|
String errorPage = "<!DOCTYPE html><html><head><title>Error</title></head><body>";
|
||||||
|
errorPage += "<h1>Configuration Error:</h1>";
|
||||||
|
errorPage += "<p>Couldn't save new configuration. Please try again.</p>";
|
||||||
|
errorPage += "<a href='/'>Back</a></body></html>";
|
||||||
|
|
||||||
|
AsyncWebServerResponse *response = request->beginResponse(500, "text/html", errorPage);
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleAction(AsyncWebServerRequest *request) {
|
void handleAction(AsyncWebServerRequest *request) {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace WIFI_Utils {
|
|||||||
Serial.print(millis());
|
Serial.print(millis());
|
||||||
Serial.println("Reconnecting to WiFi...");
|
Serial.println("Reconnecting to WiFi...");
|
||||||
WiFi.disconnect();
|
WiFi.disconnect();
|
||||||
WIFI_Utils::startWiFi();//WiFi.reconnect();
|
WIFI_Utils::startWiFi();
|
||||||
previousWiFiMillis = millis();
|
previousWiFiMillis = millis();
|
||||||
|
|
||||||
if (Config.backupDigiMode) {
|
if (Config.backupDigiMode) {
|
||||||
@@ -132,7 +132,7 @@ namespace WIFI_Utils {
|
|||||||
digitalWrite(INTERNAL_LED_PIN,LOW);
|
digitalWrite(INTERNAL_LED_PIN,LOW);
|
||||||
#endif
|
#endif
|
||||||
if (WiFi.status() == WL_CONNECTED) {
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
Serial.print("Connected as ");
|
Serial.print("\nConnected as ");
|
||||||
Serial.print(WiFi.localIP());
|
Serial.print(WiFi.localIP());
|
||||||
Serial.print(" / MAC Address: ");
|
Serial.print(" / MAC Address: ");
|
||||||
Serial.println(WiFi.macAddress());
|
Serial.println(WiFi.macAddress());
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ float newHum, newTemp, newPress, newGas;
|
|||||||
|
|
||||||
|
|
||||||
Adafruit_BME280 bme280;
|
Adafruit_BME280 bme280;
|
||||||
|
Adafruit_AHTX0 aht20;
|
||||||
#if defined(HELTEC_V3) || defined(HELTEC_V3_2)
|
#if defined(HELTEC_V3) || defined(HELTEC_V3_2)
|
||||||
Adafruit_BMP280 bmp280(&Wire1);
|
Adafruit_BMP280 bmp280(&Wire1);
|
||||||
Adafruit_Si7021 si7021 = Adafruit_Si7021();
|
Adafruit_Si7021 si7021 = Adafruit_Si7021();
|
||||||
@@ -71,6 +72,7 @@ namespace WX_Utils {
|
|||||||
#endif
|
#endif
|
||||||
err = Wire.endTransmission();
|
err = Wire.endTransmission();
|
||||||
#endif
|
#endif
|
||||||
|
delay(5);
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
//Serial.println(addr); //this shows any connected board to I2C
|
//Serial.println(addr); //this shows any connected board to I2C
|
||||||
if (addr == 0x76 || addr == 0x77) { // BME or BMP
|
if (addr == 0x76 || addr == 0x77) { // BME or BMP
|
||||||
@@ -118,9 +120,13 @@ namespace WX_Utils {
|
|||||||
Serial.println("BMP280 sensor found");
|
Serial.println("BMP280 sensor found");
|
||||||
wxModuleType = 2;
|
wxModuleType = 2;
|
||||||
wxModuleFound = true;
|
wxModuleFound = true;
|
||||||
|
if (aht20.begin()) {
|
||||||
|
Serial.println("AHT20 sensor found");
|
||||||
|
if (wxModuleType == 2) wxModuleType = 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (wxModuleAddress == 0x40) {
|
}
|
||||||
|
} else if (wxModuleAddress == 0x40 && Config.battery.useExternalI2CSensor == false) {
|
||||||
if(si7021.begin()) {
|
if(si7021.begin()) {
|
||||||
Serial.println("Si7021 sensor found");
|
Serial.println("Si7021 sensor found");
|
||||||
wxModuleType = 4;
|
wxModuleType = 4;
|
||||||
@@ -264,6 +270,7 @@ namespace WX_Utils {
|
|||||||
newPress = 0;
|
newPress = 0;
|
||||||
break;
|
break;
|
||||||
case 5: // SHTC3
|
case 5: // SHTC3
|
||||||
|
{
|
||||||
#ifdef LIGHTGATEWAY_PLUS_1_0
|
#ifdef LIGHTGATEWAY_PLUS_1_0
|
||||||
sensors_event_t humidity, temp;
|
sensors_event_t humidity, temp;
|
||||||
shtc3.getEvent(&humidity, &temp);
|
shtc3.getEvent(&humidity, &temp);
|
||||||
@@ -271,6 +278,17 @@ namespace WX_Utils {
|
|||||||
newHum = humidity.relative_humidity;
|
newHum = humidity.relative_humidity;
|
||||||
newPress = 0;
|
newPress = 0;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 6: // BMP280 + AHT20
|
||||||
|
{
|
||||||
|
bmp280.takeForcedMeasurement();
|
||||||
|
newTemp = bmp280.readTemperature();
|
||||||
|
newPress = (bmp280.readPressure() / 100.0F);
|
||||||
|
sensors_event_t humidity, temp;
|
||||||
|
aht20.getEvent(&humidity, &temp);
|
||||||
|
newHum = humidity.relative_humidity;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +300,7 @@ namespace WX_Utils {
|
|||||||
String tempStr = generateTempString(((newTemp + Config.wxsensor.temperatureCorrection) * 1.8) + 32);
|
String tempStr = generateTempString(((newTemp + Config.wxsensor.temperatureCorrection) * 1.8) + 32);
|
||||||
|
|
||||||
String humStr;
|
String humStr;
|
||||||
if (wxModuleType == 1 || wxModuleType == 3 || wxModuleType == 4 || wxModuleType == 5) {
|
if (wxModuleType == 1 || wxModuleType == 3 || wxModuleType == 4 || wxModuleType == 5 || wxModuleType == 6) {
|
||||||
humStr = generateHumString(newHum);
|
humStr = generateHumString(newHum);
|
||||||
} else if (wxModuleType == 2) {
|
} else if (wxModuleType == 2) {
|
||||||
humStr = "..";
|
humStr = "..";
|
||||||
|
|||||||
@@ -32,6 +32,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_NUM_3
|
#define GPIO_WAKEUP_PIN GPIO_NUM_3
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ board_build.mcu = esp32c3
|
|||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
${common.usb_flags}
|
${common.usb_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX127X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D ESP32_C3_OctopusLab_LoRa
|
-D ESP32_C3_OctopusLab_LoRa
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
// LoRa Radio
|
// LoRa Radio
|
||||||
#define HAS_SX1268
|
#define HAS_SX1268
|
||||||
#define HAS_1W_LORA
|
#define HAS_1W_LORA
|
||||||
|
#define HAS_TCXO
|
||||||
#define RADIO_SCLK_PIN 18
|
#define RADIO_SCLK_PIN 18
|
||||||
#define RADIO_MISO_PIN 19
|
#define RADIO_MISO_PIN 19
|
||||||
#define RADIO_MOSI_PIN 23
|
#define RADIO_MOSI_PIN 23
|
||||||
@@ -34,6 +35,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX127X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D ESP32_DIY_1W_LoRa
|
-D ESP32_DIY_1W_LoRa
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
// LoRa Radio
|
// LoRa Radio
|
||||||
#define HAS_SX1262
|
#define HAS_SX1262
|
||||||
#define HAS_1W_LORA
|
#define HAS_1W_LORA
|
||||||
|
#define HAS_TCXO
|
||||||
#define RADIO_SCLK_PIN 18
|
#define RADIO_SCLK_PIN 18
|
||||||
#define RADIO_MISO_PIN 19
|
#define RADIO_MISO_PIN 19
|
||||||
#define RADIO_MOSI_PIN 23
|
#define RADIO_MOSI_PIN 23
|
||||||
@@ -34,6 +35,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX127X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D ESP32_DIY_1W_LoRa_915
|
-D ESP32_DIY_1W_LoRa_915
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -34,6 +34,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX127X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D ESP32_DIY_1W_LoRa_LLCC68
|
-D ESP32_DIY_1W_LoRa_LLCC68
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -34,6 +34,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_33
|
#define GPIO_WAKEUP_PIN GPIO_SEL_33
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX127X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D ESP32_DIY_1W_LoRa_Mesh_V1_2
|
-D ESP32_DIY_1W_LoRa_Mesh_V1_2
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX126X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D ESP32_DIY_LoRa
|
-D ESP32_DIY_LoRa
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX126X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D ESP32_DIY_LoRa_915
|
-D ESP32_DIY_LoRa_915
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -28,6 +28,9 @@
|
|||||||
#define RADIO_RST_PIN 0
|
#define RADIO_RST_PIN 0
|
||||||
#define RADIO_BUSY_PIN 32
|
#define RADIO_BUSY_PIN 32
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX126X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D ESP32_DIY_LoRa_A7670
|
-D ESP32_DIY_LoRa_A7670
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -28,6 +28,9 @@
|
|||||||
#define RADIO_RST_PIN 0
|
#define RADIO_RST_PIN 0
|
||||||
#define RADIO_BUSY_PIN 32
|
#define RADIO_BUSY_PIN 32
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX126X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D ESP32_DIY_LoRa_A7670_915
|
-D ESP32_DIY_LoRa_A7670_915
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
50
variants/LoRaHAM_V2/board_pinout.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
|
*
|
||||||
|
* This file is part of LoRa APRS iGate.
|
||||||
|
*
|
||||||
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOARD_PINOUT_H_
|
||||||
|
#define BOARD_PINOUT_H_
|
||||||
|
|
||||||
|
// LoRa Radio
|
||||||
|
#define HAS_SX1278
|
||||||
|
#define RADIO_SCLK_PIN 36
|
||||||
|
#define RADIO_MISO_PIN 37
|
||||||
|
#define RADIO_MOSI_PIN 35
|
||||||
|
#define RADIO_CS_PIN 34
|
||||||
|
#define RADIO_RST_PIN 2
|
||||||
|
#define RADIO_BUSY_PIN 3
|
||||||
|
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||||
|
#define GPIO_WAKEUP_PIN GPIO_SEL_3
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
|
// Display
|
||||||
|
//#define HAS_DISPLAY
|
||||||
|
|
||||||
|
#undef OLED_SDA
|
||||||
|
#undef OLED_SCL
|
||||||
|
#undef OLED_RST
|
||||||
|
|
||||||
|
#define OLED_SDA 21
|
||||||
|
#define OLED_SCL 22
|
||||||
|
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
|
||||||
|
|
||||||
|
// Aditional Config
|
||||||
|
#define INTERNAL_LED_PIN 39
|
||||||
|
|
||||||
|
#endif
|
||||||
11
variants/LoRaHAM_V2/platformio.ini
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[env:LoRaHAM_V2]
|
||||||
|
board = esp32dev
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX126X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
|
-D LoRaHAM_V2
|
||||||
|
lib_deps =
|
||||||
|
${common.lib_deps}
|
||||||
|
${common.display_libs}
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
// LoRa Radio
|
// LoRa Radio
|
||||||
#define HAS_SX1268
|
#define HAS_SX1268
|
||||||
#define HAS_1W_LORA
|
#define HAS_1W_LORA
|
||||||
|
#define HAS_TCXO
|
||||||
#define RADIO_SCLK_PIN 18
|
#define RADIO_SCLK_PIN 18
|
||||||
#define RADIO_MISO_PIN 19
|
#define RADIO_MISO_PIN 19
|
||||||
#define RADIO_MOSI_PIN 23
|
#define RADIO_MOSI_PIN 23
|
||||||
@@ -34,6 +35,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_33
|
#define GPIO_WAKEUP_PIN GPIO_SEL_33
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX127X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D OE5HWN_MeshCom
|
-D OE5HWN_MeshCom
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -34,6 +34,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_5
|
#define GPIO_WAKEUP_PIN GPIO_SEL_5
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ board_build.mcu = esp32s3
|
|||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
${common.usb_flags}
|
${common.usb_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX127X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D LIGHTGATEWAY_1_0
|
-D LIGHTGATEWAY_1_0
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
// LoRa Radio
|
// LoRa Radio
|
||||||
#define HAS_SX1268
|
#define HAS_SX1268
|
||||||
#define HAS_1W_LORA
|
#define HAS_1W_LORA
|
||||||
|
#define HAS_TCXO
|
||||||
#define RADIO_VCC_PIN 21
|
#define RADIO_VCC_PIN 21
|
||||||
#define RADIO_SCLK_PIN 12
|
#define RADIO_SCLK_PIN 12
|
||||||
#define RADIO_MISO_PIN 13
|
#define RADIO_MISO_PIN 13
|
||||||
@@ -35,6 +36,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_5
|
#define GPIO_WAKEUP_PIN GPIO_SEL_5
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ board_build.mcu = esp32s3
|
|||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
${common.usb_flags}
|
${common.usb_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX127X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D LIGHTGATEWAY_PLUS_1_0
|
-D LIGHTGATEWAY_PLUS_1_0
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX126X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D TROY_LoRa_APRS
|
-D TROY_LoRa_APRS
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -31,6 +31,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = wemos_d1_uno32
|
board = wemos_d1_uno32
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX126X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D WEMOS_D1_R32_RA02
|
-D WEMOS_D1_R32_RA02
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_25
|
#define GPIO_WAKEUP_PIN GPIO_SEL_25
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = lolin32
|
board = lolin32
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX126X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D WEMOS_LOLIN32_OLED_DIY_LoRa
|
-D WEMOS_LOLIN32_OLED_DIY_LoRa
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||
@@ -30,6 +30,11 @@
|
|||||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||||
#define GPIO_WAKEUP_PIN GPIO_SEL_38
|
#define GPIO_WAKEUP_PIN GPIO_SEL_38
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_BOARD_I2C_PINS
|
||||||
|
#define BOARD_I2C_SDA 11
|
||||||
|
#define BOARD_I2C_SCL 12
|
||||||
|
|
||||||
// Aditional Config
|
// Aditional Config
|
||||||
#define INTERNAL_LED_PIN 15
|
#define INTERNAL_LED_PIN 15
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
board = lolin_s2_mini
|
board = lolin_s2_mini
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX126X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
-D WEMOS_S2_MINI_DIY_LoRa
|
-D WEMOS_S2_MINI_DIY_LoRa
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
|||||||