Compare commits
57 Commits
before3.1
...
NTP-server
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
4
.github/workflows/build.yml
vendored
@@ -29,6 +29,8 @@ jobs:
|
||||
chip: esp32s3
|
||||
- name: heltec_wireless_stick_lite_v3_display
|
||||
chip: esp32s3
|
||||
- name: heltec_wireless_bridge
|
||||
chip: esp32
|
||||
- name: ESP32_DIY_LoRa
|
||||
chip: esp32
|
||||
- name: ESP32_DIY_LoRa_915
|
||||
@@ -67,7 +69,7 @@ jobs:
|
||||
chip: esp32s3
|
||||
- name: heltec_ht-ct62
|
||||
chip: esp32c3
|
||||
- name: heltec_wireless_paper
|
||||
- name: heltec_wireless_paper_v1
|
||||
chip: esp32s3
|
||||
- name: OE5HWN_MeshCom
|
||||
chip: esp32
|
||||
|
||||
44
README.md
@@ -9,46 +9,38 @@ __(This iGate Firmware works with all LoRa Tracker Firmwares (specially this <a
|
||||
|
||||
____________________________________________________
|
||||
|
||||
# <a href="https://richonguzman.github.io/lora-igate-web-flasher/installer.html" target="_blank">WEB FLASHER/INSTALLER</a>
|
||||
|
||||
|
||||
# <a href="https://github.com/richonguzman/LoRa_APRS_iGate/blob/main/manual/LoRa_APRS_iGate_CA2RXU_Firmware_Manual.pdf" target="_blank">LoRa APRS iGate CA2RXU Firmware Manual</a>
|
||||
|
||||
____________________________________________________
|
||||
|
||||
## You can support this project to continue to grow:
|
||||
|
||||
[<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 />
|
||||
|
||||
# WEB FLASHER/INSTALLER is <a href="https://richonguzman.github.io/lora-igate-web-flasher/installer.html" target="_blank">here</a>
|
||||
|
||||
____________________________________________________
|
||||
|
||||
# WIKI
|
||||
|
||||
### FAQ, BME280, TNC and more --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/00.-FAQ-(frequently-asked-questions)" target="_blank">here</a>.
|
||||
|
||||
### Installation Guide --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/01.-Installation-Guide" target="_blank">here</a>.
|
||||
<br />
|
||||
|
||||
# SUPPORTED BOARDS
|
||||
|
||||
### Buying links --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/108.-Supported-Boards-and-Buying-Links" target="_blank">here</a>.
|
||||
## SUPPORTED BOARDS (<a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/Supported-Boards-and-Buying-Links" target="_blank">Buying links</a>).
|
||||
|
||||
(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 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).
|
||||
|
||||
- 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.
|
||||
|
||||
- Faketec V3 (NRF52840 + Heltec HTRA62 SX1262)
|
||||
|
||||
- ESP32 Wroom + SX1278 LoRa Module or Ebyte 400M30S (or 900M30S) 1W LoRa Module for a DIY Versions.
|
||||
- ESP32 + 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.
|
||||
|
||||
@@ -58,8 +50,14 @@ ____________________________________________________
|
||||
|
||||
<br />
|
||||
|
||||
## Timeline (Versions):
|
||||
|
||||
# Timeline (Versions):
|
||||
- 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 in Digipeater Mode.
|
||||
- 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 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.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"path": "WIDE1-1",
|
||||
"sendViaAPRSIS": false,
|
||||
"sendViaRF": false,
|
||||
"beaconFreq": 1,
|
||||
"statusActive": false,
|
||||
"statusPacket": "",
|
||||
"gpsActive": false,
|
||||
@@ -38,14 +39,17 @@
|
||||
"ecoMode": 0
|
||||
},
|
||||
"lora": {
|
||||
"txFreq": 433775000,
|
||||
"rxActive": true,
|
||||
"rxFreq": 433775000,
|
||||
"spreadingFactor": 12,
|
||||
"signalBandwidth": 125000,
|
||||
"codingRate4": 5,
|
||||
"power": 20,
|
||||
"rxSpreadingFactor": 12,
|
||||
"rxCodingRate4": 5,
|
||||
"rxSignalBandwidth": 125000,
|
||||
"txActive": false,
|
||||
"rxActive": true
|
||||
"txFreq": 433775000,
|
||||
"txSpreadingFactor": 12,
|
||||
"txCodingRate4": 5,
|
||||
"txSignalBandwidth": 125000,
|
||||
"power": 20
|
||||
},
|
||||
"display": {
|
||||
"alwaysOn": true,
|
||||
@@ -86,7 +90,8 @@
|
||||
"topic": "",
|
||||
"username": "",
|
||||
"password": "",
|
||||
"port": 1883
|
||||
"port": 1883,
|
||||
"beaconOverMqtt": false
|
||||
},
|
||||
"ota": {
|
||||
"username": "",
|
||||
@@ -101,12 +106,14 @@
|
||||
"rfOnly": true
|
||||
},
|
||||
"ntp": {
|
||||
"server": "pool.ntp.org",
|
||||
"gmtCorrection": 0.0
|
||||
},
|
||||
"other": {
|
||||
"rememberStationTime": 30,
|
||||
"backupDigiMode": false,
|
||||
"rebootMode": false,
|
||||
"rebootModeTime": 6
|
||||
"rebootModeTime": 6,
|
||||
"startupDelay": 0
|
||||
}
|
||||
}
|
||||
@@ -344,6 +344,28 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 mt-3">
|
||||
<label
|
||||
for="startupDelay"
|
||||
class="form-label"
|
||||
>Startup Delay<small>(To Allow Router/Modem to start WiFiAP before connection)</small></label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="number"
|
||||
name="startupDelay"
|
||||
id="startupDelay"
|
||||
placeholder="0"
|
||||
class="form-control"
|
||||
step="1"
|
||||
min="0"
|
||||
max="5"
|
||||
/>
|
||||
<span class="input-group-text"
|
||||
>minutes</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
@@ -545,12 +567,33 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 d-grid gap-2">
|
||||
<button class="btn btn-primary" id="send-beacon">Send beacon now</button>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-6">
|
||||
<button class="btn btn-primary form-control h-100" id="send-beacon">Send beacon now</button>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="beacon.beaconFreq"
|
||||
class="form-label">
|
||||
<small>(Select LoRa Beacon Frequency)</small>
|
||||
</label>
|
||||
<select
|
||||
class="form-select form-select"
|
||||
name="beacon.beaconFreq"
|
||||
id="beacon.beaconFreq"
|
||||
>
|
||||
<option value="0">
|
||||
Beacon on Rx Freq
|
||||
</option>
|
||||
<option value="1">
|
||||
Beacon on Tx Freq
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4">
|
||||
<div class="col-12">
|
||||
<div class="row mt-3">
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="beacon.interval"
|
||||
class="form-label"
|
||||
@@ -626,7 +669,7 @@
|
||||
</h5>
|
||||
<small>Add Callsigns with space between them to Blacklist them (* wild card allowed)</small>
|
||||
</div>
|
||||
<div class="col-9 mt-2">
|
||||
<div class="col-9">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<label
|
||||
@@ -667,7 +710,7 @@
|
||||
</h5>
|
||||
<small>Define the Digipeater mode</small>
|
||||
</div>
|
||||
<div class="col-9 mt-2">
|
||||
<div class="col-9">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<label
|
||||
@@ -706,13 +749,13 @@
|
||||
id="digi.ecoMode"
|
||||
>
|
||||
<option value="0">
|
||||
OFF (Normal Mode - WiFiAP enabled)
|
||||
OFF (Normal Mode - WiFiAP and Serial Output enabled)
|
||||
</option>
|
||||
<option value="1">
|
||||
Ultra Eco Mode (Sleep till Packet Rx (WiFiAP/WebUI & Display disabled))
|
||||
</option>
|
||||
<option value="2">
|
||||
OFF (Normal Mode - WiFiAP disabled)
|
||||
OFF (Normal Mode - WiFiAP disabled but Serial Output still enabled)
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -744,21 +787,6 @@
|
||||
</div>
|
||||
<div class="col-lg-9 col-sm-12">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="lora.txActive"
|
||||
id="lora.txActive"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="lora.txActive"
|
||||
class="form-label"
|
||||
>Enable LoRa TX</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
@@ -775,6 +803,40 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="lora.txActive"
|
||||
id="lora.txActive"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="lora.txActive"
|
||||
class="form-label"
|
||||
>Enable LoRa TX</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 mt-1">
|
||||
<label
|
||||
for="lora.rxFreq"
|
||||
class="form-label">
|
||||
Rx Frequency
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text"
|
||||
name="lora.rxFreq"
|
||||
id="lora.rxFreq"
|
||||
placeholder="433775000"
|
||||
class="form-control"
|
||||
/>
|
||||
<span class="input-group-text"
|
||||
>Hz
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 mt-1">
|
||||
<label
|
||||
for="lora.txFreq"
|
||||
class="form-label"
|
||||
@@ -802,136 +864,123 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="col-6 mt-3">
|
||||
<label
|
||||
for="lora.rxFreq"
|
||||
class="form-label">
|
||||
Rx Frequency
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text"
|
||||
name="lora.rxFreq"
|
||||
id="lora.rxFreq"
|
||||
placeholder="433775000"
|
||||
class="form-control"
|
||||
/>
|
||||
<span class="input-group-text"
|
||||
>Hz
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4">
|
||||
<div class="col-12 mb-4">
|
||||
<label
|
||||
for="action.speed"
|
||||
for="lora.rxSpreadingFactor"
|
||||
class="form-label"
|
||||
>Predefined speeds
|
||||
>Rx Spreading Factor
|
||||
</label>
|
||||
<select
|
||||
class="form-select form-select"
|
||||
name="action.speed"
|
||||
id="action.speed"
|
||||
>
|
||||
<option value="300">
|
||||
BW 125khz CR 4:5 SF 12 (Slow
|
||||
Standard, 300bps)
|
||||
</option>
|
||||
<option value="244">
|
||||
BW 125khz CR 4:6 SF 12 (244bps)
|
||||
</option>
|
||||
<option value="209">
|
||||
BW 125khz CR 4:7 SF 12 (209bps)
|
||||
</option>
|
||||
<option value="183">
|
||||
BW 125khz CR 4:8 SF 12 (183bps)
|
||||
</option>
|
||||
<option value="610">
|
||||
BW 125khz CR 4:8 SF 10 (610bps)
|
||||
</option>
|
||||
<option value="1200">
|
||||
BW 125khz CR 4:7 SF 9 (Fast
|
||||
Standard, 1200bps)
|
||||
</option>
|
||||
<option value="">
|
||||
User defined
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<label
|
||||
for="lora.signalBandwidth"
|
||||
class="form-label"
|
||||
>Bandwidth
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<select
|
||||
class="form-select form-select"
|
||||
name="lora.signalBandwidth"
|
||||
id="lora.signalBandwidth"
|
||||
required=""
|
||||
>
|
||||
<option value="62500" selected>
|
||||
62.5 kHz
|
||||
</option>
|
||||
<option value="125000" selected>
|
||||
125 kHz
|
||||
</option>
|
||||
<option value="250000">
|
||||
250 kHz
|
||||
</option>
|
||||
<option value="500000">
|
||||
500 kHz
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<label
|
||||
for="lora.spreadingFactor"
|
||||
class="form-label"
|
||||
>Spreading Factor
|
||||
</label>
|
||||
<select
|
||||
class="form-select form-select"
|
||||
name="lora.spreadingFactor"
|
||||
id="lora.spreadingFactor"
|
||||
name="lora.rxSpreadingFactor"
|
||||
id="lora.rxSpreadingFactor"
|
||||
required=""
|
||||
>
|
||||
<option value="7">
|
||||
SF7 - Lowest battery usage
|
||||
</option>
|
||||
<option value="7">SF7 - Lowest battery usage</option>
|
||||
<option value="8">SF8</option>
|
||||
<option value="9">SF9</option>
|
||||
<option value="10">SF10</option>
|
||||
<option value="11">SF11</option>
|
||||
<option value="12" selected>
|
||||
SF12 - Highest sensitivity
|
||||
</option>
|
||||
<option value="12" selected>SF12 - Highest sensitivity</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-6">
|
||||
<div class="col-6 mt-3">
|
||||
<label
|
||||
for="lora.codingRate4"
|
||||
class="form-label">
|
||||
Coding Rate
|
||||
for="lora.txSpreadingFactor"
|
||||
class="form-label"
|
||||
>Tx Spreading Factor
|
||||
</label>
|
||||
<select
|
||||
class="form-select form-select"
|
||||
name="lora.codingRate4"
|
||||
id="lora.codingRate4"
|
||||
name="lora.txSpreadingFactor"
|
||||
id="lora.txSpreadingFactor"
|
||||
required=""
|
||||
>
|
||||
<option value="5">5</option>
|
||||
<option value="7">SF7 - Lowest battery usage</option>
|
||||
<option value="8">SF8</option>
|
||||
<option value="9">SF9</option>
|
||||
<option value="10">SF10</option>
|
||||
<option value="11">SF11</option>
|
||||
<option value="12" selected>SF12 - Highest sensitivity</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6 mt-3">
|
||||
<label
|
||||
for="lora.rxCodingRate4"
|
||||
class="form-label">
|
||||
Rx Coding Rate
|
||||
</label>
|
||||
<select
|
||||
class="form-select form-select"
|
||||
name="lora.rxCodingRate4"
|
||||
id="lora.rxCodingRate4"
|
||||
required=""
|
||||
>
|
||||
<option value="5" selected>5</option>
|
||||
<option value="6">6</option>
|
||||
<option value="7">7</option>
|
||||
<option value="8">8</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="col-6 mt-3">
|
||||
<label
|
||||
for="lora.txCodingRate4"
|
||||
class="form-label">
|
||||
Tx Coding Rate
|
||||
</label>
|
||||
<select
|
||||
class="form-select form-select"
|
||||
name="lora.txCodingRate4"
|
||||
id="lora.txCodingRate4"
|
||||
required=""
|
||||
>
|
||||
<option value="5" selected>5</option>
|
||||
<option value="6">6</option>
|
||||
<option value="7">7</option>
|
||||
<option value="8">8</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6 mt-3">
|
||||
<label
|
||||
for="lora.rxSignalBandwidth"
|
||||
class="form-label"
|
||||
>Rx Signal Bandwidth
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<select
|
||||
class="form-select form-select"
|
||||
name="lora.rxSignalBandwidth"
|
||||
id="lora.rxSignalBandwidth"
|
||||
required=""
|
||||
>
|
||||
<option value="62500">62.5 kHz</option>
|
||||
<option value="125000" selected>125 kHz</option>
|
||||
<option value="250000">250 kHz</option>
|
||||
<option value="500000">500 kHz</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 mt-3">
|
||||
<label
|
||||
for="lora.txSignalBandwidth"
|
||||
class="form-label"
|
||||
>Tx Signal Bandwidth
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<select
|
||||
class="form-select form-select"
|
||||
name="lora.txSignalBandwidth"
|
||||
id="lora.txSignalBandwidth"
|
||||
required=""
|
||||
>
|
||||
<option value="62500">62.5 kHz</option>
|
||||
<option value="125000" selected>125 kHz</option>
|
||||
<option value="250000">250 kHz</option>
|
||||
<option value="500000">500 kHz</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 mt-3">
|
||||
<label
|
||||
for="lora.power"
|
||||
class="form-label">
|
||||
@@ -953,7 +1002,7 @@
|
||||
>dBm</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1013,7 +1062,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="row mt-1">
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="display.timeout"
|
||||
@@ -1092,8 +1141,8 @@
|
||||
Calculate voltage divider accordingly.
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-9 mt-2">
|
||||
<div class="row mt-2">
|
||||
<div class="col-9">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
@@ -1122,7 +1171,7 @@
|
||||
>(Send Voltage As Telemetry)</label
|
||||
>
|
||||
</div>
|
||||
<div class="form-check form-switch mt-3">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="battery.monitorInternalVoltage"
|
||||
@@ -1274,7 +1323,7 @@
|
||||
</h5>
|
||||
<small>Define Wx telemetry</small>
|
||||
</div>
|
||||
<div class="col-9 mt-2">
|
||||
<div class="col-9">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-check form-switch">
|
||||
@@ -1295,7 +1344,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="row mt-2">
|
||||
<div class="col-6">
|
||||
<label for="wxsensor.heightCorrection" class="form-label"
|
||||
>Height Correction (Above Sea-Level)</label
|
||||
@@ -1363,18 +1412,37 @@
|
||||
>
|
||||
</div>
|
||||
<div class="col-lg-9 col-sm-12">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="syslog.active"
|
||||
id="syslog.active"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="syslog.active"
|
||||
class="form-label"
|
||||
>Enable syslog</label
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="syslog.active"
|
||||
id="syslog.active"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="syslog.active"
|
||||
class="form-label"
|
||||
>Enable syslog</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="syslog.logBeaconOverTCPIP"
|
||||
id="syslog.logBeaconOverTCPIP"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="syslog.logBeaconOverTCPIP"
|
||||
class="form-label"
|
||||
>Log Beacon over TCP/IP</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-6">
|
||||
@@ -1405,21 +1473,7 @@
|
||||
class="form-control"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="syslog.logBeaconOverTCPIP"
|
||||
id="syslog.logBeaconOverTCPIP"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="syslog.logBeaconOverTCPIP"
|
||||
class="form-label"
|
||||
>Log Beacon over TPCIP</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1540,7 +1594,7 @@
|
||||
</div>
|
||||
<div class="col-lg-9 col-sm-12">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -1555,7 +1609,24 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="mqtt.beaconOverMqtt"
|
||||
id="mqtt.beaconOverMqtt"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="mqtt.beaconOverMqtt"
|
||||
class="form-label"
|
||||
>Send (also) iGate Beacon</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="mqtt.server"
|
||||
class="form-label"
|
||||
@@ -1570,11 +1641,11 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="mqtt.topic"
|
||||
class="form-label"
|
||||
>Topic</label
|
||||
>Topic <small>(Default is <strong>aprs-igate</strong>)</small></label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
@@ -1585,11 +1656,10 @@
|
||||
placeholder="aprs-igate"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-text">
|
||||
Default is <strong>aprs-igate</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="mqtt.username"
|
||||
class="form-label"
|
||||
@@ -1604,7 +1674,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 mt-3">
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="mqtt.password"
|
||||
class="form-label"
|
||||
@@ -1619,11 +1689,13 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 mt-3">
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="mqtt.port"
|
||||
class="form-label"
|
||||
>Port</label
|
||||
>Port <small>(Default is <strong>1883</strong>)</small></label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
@@ -1637,9 +1709,6 @@
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-text">
|
||||
Default is <strong>1883</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1667,9 +1736,9 @@
|
||||
Reboot Time
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col-9 mt-2">
|
||||
<div class="col-9">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -1684,8 +1753,6 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="other.rebootModeTime"
|
||||
@@ -1740,49 +1807,55 @@
|
||||
WiFi Auto AP
|
||||
</h5>
|
||||
<small
|
||||
>Add your password and WiFi AP timeout to
|
||||
auto access point. Auto AP will start if
|
||||
there is no WiFi connection. Timeout will
|
||||
count from startup or last client
|
||||
disconnected.</small
|
||||
>WiFi AP will start if there is no WiFi
|
||||
connection available. Timeout will count from
|
||||
startup or last client disconnected.</small
|
||||
>
|
||||
</div>
|
||||
<div class="col-lg-9 col-sm-12">
|
||||
<div class="col-12">
|
||||
<label
|
||||
for="wifi.autoAP.password"
|
||||
class="form-label"
|
||||
>Password</label
|
||||
>
|
||||
<input
|
||||
type="password"
|
||||
name="wifi.autoAP.password"
|
||||
id="wifi.autoAP.password"
|
||||
class="form-control"
|
||||
placeholder="1234567890"
|
||||
required=""
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 mt-3">
|
||||
<label
|
||||
for="wifi.autoAP.timeout"
|
||||
class="form-label"
|
||||
>WiFi AP timeout to search again for available WiFi's
|
||||
<small>(in minutes)</small></label
|
||||
>
|
||||
<input
|
||||
type="number"
|
||||
name="wifi.autoAP.timeout"
|
||||
id="wifi.autoAP.timeout"
|
||||
class="form-control"
|
||||
placeholder="10"
|
||||
required=""
|
||||
step="1"
|
||||
min="0"
|
||||
/>
|
||||
<div class="form-text">
|
||||
Set to <strong>0</strong> if you don't
|
||||
want WiFi AP to stop.
|
||||
<div class="col-9">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="wifi.autoAP.password"
|
||||
class="form-label"
|
||||
>Password</label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="password"
|
||||
name="wifi.autoAP.password"
|
||||
id="wifi.autoAP.password"
|
||||
class="form-control"
|
||||
placeholder="1234567890"
|
||||
required=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="wifi.autoAP.timeout"
|
||||
class="form-label"
|
||||
>WiFiAP timeout (to search again)</label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="number"
|
||||
name="wifi.autoAP.timeout"
|
||||
id="wifi.autoAP.timeout"
|
||||
class="form-control"
|
||||
placeholder="10"
|
||||
required=""
|
||||
step="1"
|
||||
min="0"
|
||||
/>
|
||||
<span class="input-group-text"
|
||||
>minutes</span
|
||||
>
|
||||
<div class="form-text">
|
||||
Set to <strong>0</strong> if you don't
|
||||
want WiFi AP to stop.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1813,27 +1886,29 @@
|
||||
>
|
||||
</div>
|
||||
<div class="col-lg-9 col-sm-12">
|
||||
<div class="col-12">
|
||||
<label for="ota.username" class="form-label"
|
||||
>Username</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
name="ota.username"
|
||||
id="ota.username"
|
||||
class="form-control"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 mt-3">
|
||||
<label for="ota.password" class="form-label"
|
||||
>Password</label
|
||||
>
|
||||
<input
|
||||
type="password"
|
||||
name="ota.password"
|
||||
id="ota.password"
|
||||
class="form-control"
|
||||
/>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="ota.username" class="form-label"
|
||||
>Username</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
name="ota.username"
|
||||
id="ota.username"
|
||||
class="form-control"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="ota.password" class="form-label"
|
||||
>Password</label
|
||||
>
|
||||
<input
|
||||
type="password"
|
||||
name="ota.password"
|
||||
id="ota.password"
|
||||
class="form-control"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1863,46 +1938,46 @@
|
||||
>
|
||||
</div>
|
||||
<div class="col-lg-9 col-sm-12">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="webadmin.active"
|
||||
id="webadmin.active"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="webadmin.active"
|
||||
class="form-label"
|
||||
>Web interface authentication</label
|
||||
>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="webadmin.active"
|
||||
id="webadmin.active"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="webadmin.active"
|
||||
class="form-label"
|
||||
>Web interface authentication</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label for="webadmin.username" class="form-label"
|
||||
>Username</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
name="webadmin.username"
|
||||
id="webadmin.username"
|
||||
class="form-control"
|
||||
value="admin"
|
||||
required=""
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 mt-3">
|
||||
<label for="webadmin.password" class="form-label"
|
||||
>Password</label
|
||||
>
|
||||
<input
|
||||
type="password"
|
||||
name="webadmin.password"
|
||||
id="webadmin.password"
|
||||
class="form-control"
|
||||
/>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="webadmin.username" class="form-label"
|
||||
>Username</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
name="webadmin.username"
|
||||
id="webadmin.username"
|
||||
class="form-control"
|
||||
value="admin"
|
||||
required=""
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="webadmin.password" class="form-label"
|
||||
>Password</label
|
||||
>
|
||||
<input
|
||||
type="password"
|
||||
name="webadmin.password"
|
||||
id="webadmin.password"
|
||||
class="form-control"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1946,21 +2021,19 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="remoteManagement.rfOnly"
|
||||
id="remoteManagement.rfOnly"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="remoteManagement.rfOnly"
|
||||
class="form-label"
|
||||
>Managers commands only via RF (not APRS-IS)</label
|
||||
>
|
||||
</div>
|
||||
<div class="col-12 mt-3">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="remoteManagement.rfOnly"
|
||||
id="remoteManagement.rfOnly"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="remoteManagement.rfOnly"
|
||||
class="form-label"
|
||||
>Managers commands only via RF (not APRS-IS)</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1990,26 +2063,43 @@
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-lg-9 col-sm-12">
|
||||
<div class="col-12">
|
||||
<label
|
||||
for="ntp.gmtCorrection"
|
||||
class="form-label"
|
||||
>GMT Time Correction for accurate Local Time</label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="number"
|
||||
name="ntp.gmtCorrection"
|
||||
id="ntp.gmtCorrection"
|
||||
placeholder="0"
|
||||
class="form-control"
|
||||
step="0.25"
|
||||
min="-23.75"
|
||||
max="23.75"
|
||||
/>
|
||||
<span class="input-group-text"
|
||||
>hours</span
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="ntp.server"
|
||||
class="form-label"
|
||||
>NTP Server hostname</label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text"
|
||||
name="ntp.server"
|
||||
id="ntp.server"
|
||||
class="form-control"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label
|
||||
for="ntp.gmtCorrection"
|
||||
class="form-label"
|
||||
>GMT Time Correction Offset</label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="number"
|
||||
name="ntp.gmtCorrection"
|
||||
id="ntp.gmtCorrection"
|
||||
placeholder="0"
|
||||
class="form-control"
|
||||
step="0.25"
|
||||
min="-23.75"
|
||||
max="23.75"
|
||||
/>
|
||||
<span class="input-group-text"
|
||||
>hours</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -95,6 +95,7 @@ function loadSettings(settings) {
|
||||
networksContainer.appendChild(networkElement);
|
||||
networkCount++;
|
||||
});
|
||||
document.getElementById("startupDelay").value = settings.startupDelay;
|
||||
|
||||
// APRS-IS
|
||||
document.getElementById("aprs_is.active").checked = settings.aprs_is.active;
|
||||
@@ -118,7 +119,11 @@ function loadSettings(settings) {
|
||||
document.getElementById("beacon.interval").value = settings.beacon.interval;
|
||||
document.getElementById("other.rememberStationTime").value = settings.other.rememberStationTime;
|
||||
document.getElementById("beacon.sendViaAPRSIS").checked = settings.beacon.sendViaAPRSIS;
|
||||
|
||||
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.statusPacket").value = settings.beacon.statusPacket;
|
||||
@@ -136,13 +141,16 @@ function loadSettings(settings) {
|
||||
document.getElementById("digi.ecoMode").value = settings.digi.ecoMode;
|
||||
|
||||
// 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.spreadingFactor").value = settings.lora.spreadingFactor;
|
||||
document.getElementById("lora.signalBandwidth").value = settings.lora.signalBandwidth;
|
||||
document.getElementById("lora.codingRate4").value = settings.lora.codingRate4;
|
||||
document.getElementById("lora.rxFreq").value = settings.lora.rxFreq;
|
||||
document.getElementById("lora.rxSpreadingFactor").value = settings.lora.rxSpreadingFactor;
|
||||
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;
|
||||
|
||||
// Display
|
||||
@@ -207,12 +215,14 @@ function loadSettings(settings) {
|
||||
document.getElementById("mqtt.username").value = settings.mqtt.username;
|
||||
document.getElementById("mqtt.password").value = settings.mqtt.password;
|
||||
document.getElementById("mqtt.port").value = settings.mqtt.port;
|
||||
MqttCheckbox.checked = settings.mqtt.active;
|
||||
MqttServer.disabled = !MqttCheckbox.check;
|
||||
MqttTopic.disabled = !MqttCheckbox.check;
|
||||
MqttUsername.disabled = !MqttCheckbox.check;
|
||||
MqttPassword.disabled = !MqttCheckbox.check;
|
||||
MqttPort.disabled = !MqttCheckbox.check;
|
||||
document.getElementById("mqtt.beaconOverMqtt").value = settings.mqtt.beaconOverMqtt;
|
||||
MqttCheckbox.checked = settings.mqtt.active;
|
||||
MqttServer.disabled = !MqttCheckbox.check;
|
||||
MqttTopic.disabled = !MqttCheckbox.check;
|
||||
MqttUsername.disabled = !MqttCheckbox.check;
|
||||
MqttPassword.disabled = !MqttCheckbox.check;
|
||||
MqttPort.disabled = !MqttCheckbox.check;
|
||||
MqttBeaconOverMqtt.disabled = !MqttCheckbox.check;
|
||||
|
||||
// Reboot
|
||||
document.getElementById("other.rebootMode").checked = settings.other.rebootMode;
|
||||
@@ -241,13 +251,13 @@ function loadSettings(settings) {
|
||||
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();
|
||||
refreshSpeedStandard();
|
||||
}
|
||||
|
||||
function showToast(message) {
|
||||
@@ -299,6 +309,12 @@ function updateImage() {
|
||||
}
|
||||
}
|
||||
|
||||
// Beaconing Switches
|
||||
const BeaconingViaRFCheckbox = document.querySelector('input[name="beacon.sendViaRF"]');
|
||||
const BeaconingFrequency = document.querySelector('select[name="beacon.beaconFreq"]');
|
||||
BeaconingViaRFCheckbox.addEventListener("change", function() {
|
||||
BeaconingFrequency.disabled = !this.checked;
|
||||
});
|
||||
|
||||
// Status Switch
|
||||
const StatusCheckbox = document.querySelector('input[name="beacon.statusActive"]');
|
||||
@@ -379,12 +395,14 @@ 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
|
||||
@@ -451,65 +469,6 @@ document
|
||||
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");
|
||||
|
||||
|
||||
|
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 symbol;
|
||||
String path;
|
||||
bool sendViaRF;
|
||||
bool sendViaAPRSIS;
|
||||
bool gpsActive;
|
||||
bool gpsAmbiguity;
|
||||
bool sendViaRF;
|
||||
int beaconFreq;
|
||||
bool statusActive;
|
||||
String statusPacket;
|
||||
bool gpsActive;
|
||||
bool gpsAmbiguity;
|
||||
};
|
||||
|
||||
class APRS_IS {
|
||||
@@ -67,18 +68,21 @@ public:
|
||||
class DIGI {
|
||||
public:
|
||||
int mode;
|
||||
int ecoMode; // 0 = Not Active | 1 = Ultra EcoMode | 2 = Not Active (WiFi OFF, Serial ON)
|
||||
int ecoMode; // 0 = Not Active | 1 = Ultra EcoMode | 2 = Not Active (WiFi OFF, Serial ON)
|
||||
};
|
||||
|
||||
class LoraModule {
|
||||
public:
|
||||
long txFreq;
|
||||
long rxFreq;
|
||||
bool txActive;
|
||||
bool rxActive;
|
||||
int spreadingFactor;
|
||||
long signalBandwidth;
|
||||
int codingRate4;
|
||||
long rxFreq;
|
||||
int rxSpreadingFactor;
|
||||
int rxCodingRate4;
|
||||
long rxSignalBandwidth;
|
||||
bool txActive;
|
||||
long txFreq;
|
||||
int txSpreadingFactor;
|
||||
int txCodingRate4;
|
||||
long txSignalBandwidth;
|
||||
int power;
|
||||
};
|
||||
|
||||
@@ -140,6 +144,7 @@ public:
|
||||
|
||||
class NTP {
|
||||
public:
|
||||
String server;
|
||||
float gmtCorrection;
|
||||
};
|
||||
|
||||
@@ -157,6 +162,7 @@ public:
|
||||
String username;
|
||||
String password;
|
||||
int port;
|
||||
bool beaconOverMqtt;
|
||||
};
|
||||
|
||||
class Configuration {
|
||||
@@ -166,6 +172,7 @@ public:
|
||||
bool backupDigiMode;
|
||||
bool rebootMode;
|
||||
int rebootModeTime;
|
||||
int startupDelay;
|
||||
String personalNote;
|
||||
String blacklist;
|
||||
std::vector<WiFi_AP> wifiAPs;
|
||||
@@ -185,8 +192,8 @@ public:
|
||||
REMOTE_MANAGEMENT remoteManagement;
|
||||
MQTT mqtt;
|
||||
|
||||
void init();
|
||||
void writeFile();
|
||||
void setDefaultValues();
|
||||
bool writeFile();
|
||||
Configuration();
|
||||
|
||||
private:
|
||||
|
||||
@@ -23,12 +23,6 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
struct Packet25SegBuffer {
|
||||
uint32_t receivedTime;
|
||||
String station;
|
||||
String payload;
|
||||
};
|
||||
|
||||
struct LastHeardStation {
|
||||
uint32_t lastHeardTime;
|
||||
String station;
|
||||
@@ -47,7 +41,7 @@ namespace STATION_Utils {
|
||||
bool check25SegBuffer(const String& station, const String& textMessage);
|
||||
void processOutputPacketBufferUltraEcoMode();
|
||||
void processOutputPacketBuffer();
|
||||
void addToOutputPacketBuffer(const String& packet);
|
||||
void addToOutputPacketBuffer(const String& packet, bool flag = false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Utils {
|
||||
void processStatus();
|
||||
String getLocalIP();
|
||||
void setupDisplay();
|
||||
void activeStations();
|
||||
void showActiveStations();
|
||||
void checkBeaconInterval();
|
||||
void checkDisplayInterval();
|
||||
void validateFreqs();
|
||||
@@ -46,6 +46,7 @@ namespace Utils {
|
||||
void checkRebootTime();
|
||||
void checkSleepByLowBatteryVoltage(uint8_t mode);
|
||||
bool checkValidCallsign(const String& callsign);
|
||||
void startupDelay();
|
||||
|
||||
}
|
||||
|
||||
|
||||
BIN
manual/LoRa_APRS_iGate_CA2RXU_Firmware_Manual.pdf
Normal file
@@ -33,7 +33,7 @@
|
||||
╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝
|
||||
|
||||
|
||||
Ricardo Guzman - CA2RXU
|
||||
Ricardo Guzman - CA2RXU
|
||||
https://github.com/richonguzman/LoRa_APRS_iGate
|
||||
(donations : http://paypal.me/richonguzman)
|
||||
___________________________________________________________________*/
|
||||
@@ -67,8 +67,8 @@ ___________________________________________________________________*/
|
||||
#endif
|
||||
|
||||
|
||||
String versionDate = "2025-09-02";
|
||||
String versionNumber = "3.1";
|
||||
String versionDate = "2025-10-15";
|
||||
String versionNumber = "3.1.4";
|
||||
Configuration Config;
|
||||
WiFiClient aprsIsClient;
|
||||
WiFiClient mqttClient;
|
||||
@@ -97,7 +97,6 @@ bool modemLoggedToAPRSIS = false;
|
||||
std::vector<ReceivedPacket> receivedPackets;
|
||||
|
||||
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
|
||||
//#define STARTUP_DELAY 5 //min
|
||||
|
||||
|
||||
void setup() {
|
||||
@@ -108,12 +107,7 @@ void setup() {
|
||||
Utils::validateFreqs();
|
||||
GPS_Utils::setup();
|
||||
STATION_Utils::loadBlacklistAndManagers();
|
||||
|
||||
#ifdef STARTUP_DELAY // (TEST) just to wait for WiFi init of Routers
|
||||
displayShow("", " STARTUP DELAY ...", "", "", 0);
|
||||
delay(STARTUP_DELAY * 60 * 1000);
|
||||
#endif
|
||||
|
||||
Utils::startupDelay();
|
||||
SLEEP_Utils::setup();
|
||||
WIFI_Utils::setup();
|
||||
NTP_Utils::setup();
|
||||
|
||||
@@ -26,138 +26,157 @@
|
||||
bool shouldSleepStop = true;
|
||||
|
||||
|
||||
void Configuration::writeFile() {
|
||||
Serial.println("Saving config...");
|
||||
bool Configuration::writeFile() {
|
||||
Serial.println("Saving configuration...");
|
||||
|
||||
StaticJsonDocument<2560> data;
|
||||
StaticJsonDocument<3584> data;
|
||||
File configFile = SPIFFS.open("/igate_conf.json", "w");
|
||||
|
||||
if (wifiAPs[0].ssid != "") { // We don't want to save Auto AP empty SSID
|
||||
for (int i = 0; i < wifiAPs.size(); i++) {
|
||||
data["wifi"]["AP"][i]["ssid"] = wifiAPs[i].ssid;
|
||||
data["wifi"]["AP"][i]["password"] = wifiAPs[i].password;
|
||||
}
|
||||
if (!configFile) {
|
||||
Serial.println("Error: Could not open config file for writing");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
|
||||
data["wifi"]["autoAP"]["password"] = wifiAutoAP.password;
|
||||
data["wifi"]["autoAP"]["timeout"] = wifiAutoAP.timeout;
|
||||
if (wifiAPs[0].ssid != "") { // We don't want to save Auto AP empty SSID
|
||||
for (int i = 0; i < wifiAPs.size(); i++) {
|
||||
data["wifi"]["AP"][i]["ssid"] = wifiAPs[i].ssid;
|
||||
data["wifi"]["AP"][i]["password"] = wifiAPs[i].password;
|
||||
}
|
||||
}
|
||||
|
||||
data["callsign"] = callsign;
|
||||
data["other"]["startupDelay"] = startupDelay;
|
||||
|
||||
data["aprs_is"]["active"] = aprs_is.active;
|
||||
data["aprs_is"]["passcode"] = aprs_is.passcode;
|
||||
data["aprs_is"]["server"] = aprs_is.server;
|
||||
data["aprs_is"]["port"] = aprs_is.port;
|
||||
data["aprs_is"]["filter"] = aprs_is.filter;
|
||||
data["aprs_is"]["messagesToRF"] = aprs_is.messagesToRF;
|
||||
data["aprs_is"]["objectsToRF"] = aprs_is.objectsToRF;
|
||||
data["wifi"]["autoAP"]["password"] = wifiAutoAP.password;
|
||||
data["wifi"]["autoAP"]["timeout"] = wifiAutoAP.timeout;
|
||||
|
||||
data["beacon"]["comment"] = beacon.comment;
|
||||
data["beacon"]["interval"] = beacon.interval;
|
||||
data["beacon"]["latitude"] = beacon.latitude;
|
||||
data["beacon"]["longitude"] = beacon.longitude;
|
||||
data["beacon"]["overlay"] = beacon.overlay;
|
||||
data["beacon"]["symbol"] = beacon.symbol;
|
||||
data["beacon"]["sendViaAPRSIS"] = beacon.sendViaAPRSIS;
|
||||
data["beacon"]["sendViaRF"] = beacon.sendViaRF;
|
||||
data["beacon"]["path"] = beacon.path;
|
||||
callsign.trim();
|
||||
callsign.toUpperCase();
|
||||
data["callsign"] = callsign;
|
||||
|
||||
data["beacon"]["statusActive"] = beacon.statusActive;
|
||||
data["beacon"]["statusPacket"] = beacon.statusPacket;
|
||||
data["aprs_is"]["active"] = aprs_is.active;
|
||||
data["aprs_is"]["passcode"] = aprs_is.passcode;
|
||||
data["aprs_is"]["server"] = aprs_is.server;
|
||||
data["aprs_is"]["port"] = aprs_is.port;
|
||||
data["aprs_is"]["filter"] = aprs_is.filter;
|
||||
data["aprs_is"]["messagesToRF"] = aprs_is.messagesToRF;
|
||||
data["aprs_is"]["objectsToRF"] = aprs_is.objectsToRF;
|
||||
|
||||
data["beacon"]["gpsActive"] = beacon.gpsActive;
|
||||
data["beacon"]["gpsAmbiguity"] = beacon.gpsAmbiguity;
|
||||
data["beacon"]["comment"] = beacon.comment;
|
||||
data["beacon"]["interval"] = beacon.interval;
|
||||
data["beacon"]["latitude"] = beacon.latitude;
|
||||
data["beacon"]["longitude"] = beacon.longitude;
|
||||
data["beacon"]["overlay"] = beacon.overlay;
|
||||
data["beacon"]["symbol"] = beacon.symbol;
|
||||
data["beacon"]["path"] = beacon.path;
|
||||
|
||||
data["personalNote"] = personalNote;
|
||||
data["beacon"]["sendViaAPRSIS"] = beacon.sendViaAPRSIS;
|
||||
data["beacon"]["sendViaRF"] = beacon.sendViaRF;
|
||||
data["beacon"]["beaconFreq"] = beacon.beaconFreq;
|
||||
|
||||
data["blacklist"] = blacklist;
|
||||
data["beacon"]["statusActive"] = beacon.statusActive;
|
||||
data["beacon"]["statusPacket"] = beacon.statusPacket;
|
||||
|
||||
data["digi"]["mode"] = digi.mode;
|
||||
data["digi"]["ecoMode"] = digi.ecoMode;
|
||||
#if defined(HAS_A7670)
|
||||
if (digi.ecoMode == 1) data["digi"]["ecoMode"] = 2;
|
||||
#endif
|
||||
data["beacon"]["gpsActive"] = beacon.gpsActive;
|
||||
data["beacon"]["gpsAmbiguity"] = beacon.gpsAmbiguity;
|
||||
|
||||
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["personalNote"] = personalNote;
|
||||
|
||||
data["display"]["alwaysOn"] = display.alwaysOn;
|
||||
data["display"]["timeout"] = display.timeout;
|
||||
data["display"]["turn180"] = display.turn180;
|
||||
data["blacklist"] = blacklist;
|
||||
|
||||
data["battery"]["sendInternalVoltage"] = battery.sendInternalVoltage;
|
||||
data["battery"]["monitorInternalVoltage"] = battery.monitorInternalVoltage;
|
||||
data["battery"]["internalSleepVoltage"] = battery.internalSleepVoltage;
|
||||
data["digi"]["mode"] = digi.mode;
|
||||
data["digi"]["ecoMode"] = digi.ecoMode;
|
||||
#if defined(HAS_A7670)
|
||||
if (digi.ecoMode == 1) data["digi"]["ecoMode"] = 2;
|
||||
#endif
|
||||
|
||||
data["battery"]["sendExternalVoltage"] = battery.sendExternalVoltage;
|
||||
data["battery"]["externalVoltagePin"] = battery.externalVoltagePin;
|
||||
data["battery"]["monitorExternalVoltage"] = battery.monitorExternalVoltage;
|
||||
data["battery"]["externalSleepVoltage"] = battery.externalSleepVoltage;
|
||||
data["battery"]["voltageDividerR1"] = battery.voltageDividerR1;
|
||||
data["battery"]["voltageDividerR2"] = battery.voltageDividerR2;
|
||||
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["battery"]["sendVoltageAsTelemetry"] = battery.sendVoltageAsTelemetry;
|
||||
data["display"]["alwaysOn"] = display.alwaysOn;
|
||||
data["display"]["timeout"] = display.timeout;
|
||||
data["display"]["turn180"] = display.turn180;
|
||||
|
||||
data["wxsensor"]["active"] = wxsensor.active;
|
||||
data["wxsensor"]["heightCorrection"] = wxsensor.heightCorrection;
|
||||
data["wxsensor"]["temperatureCorrection"] = wxsensor.temperatureCorrection;
|
||||
data["battery"]["sendInternalVoltage"] = battery.sendInternalVoltage;
|
||||
data["battery"]["monitorInternalVoltage"] = battery.monitorInternalVoltage;
|
||||
data["battery"]["internalSleepVoltage"] = battery.internalSleepVoltage;
|
||||
|
||||
data["syslog"]["active"] = syslog.active;
|
||||
data["syslog"]["server"] = syslog.server;
|
||||
data["syslog"]["port"] = syslog.port;
|
||||
data["syslog"]["logBeaconOverTCPIP"] = syslog.logBeaconOverTCPIP;
|
||||
data["battery"]["sendExternalVoltage"] = battery.sendExternalVoltage;
|
||||
data["battery"]["externalVoltagePin"] = battery.externalVoltagePin;
|
||||
data["battery"]["monitorExternalVoltage"] = battery.monitorExternalVoltage;
|
||||
data["battery"]["externalSleepVoltage"] = battery.externalSleepVoltage;
|
||||
data["battery"]["voltageDividerR1"] = battery.voltageDividerR1;
|
||||
data["battery"]["voltageDividerR2"] = battery.voltageDividerR2;
|
||||
|
||||
data["tnc"]["enableServer"] = tnc.enableServer;
|
||||
data["tnc"]["enableSerial"] = tnc.enableSerial;
|
||||
data["tnc"]["acceptOwn"] = tnc.acceptOwn;
|
||||
data["battery"]["sendVoltageAsTelemetry"] = battery.sendVoltageAsTelemetry;
|
||||
|
||||
data["mqtt"]["active"] = mqtt.active;
|
||||
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["wxsensor"]["active"] = wxsensor.active;
|
||||
data["wxsensor"]["heightCorrection"] = wxsensor.heightCorrection;
|
||||
data["wxsensor"]["temperatureCorrection"] = wxsensor.temperatureCorrection;
|
||||
|
||||
data["ota"]["username"] = ota.username;
|
||||
data["ota"]["password"] = ota.password;
|
||||
data["syslog"]["active"] = syslog.active;
|
||||
data["syslog"]["server"] = syslog.server;
|
||||
data["syslog"]["port"] = syslog.port;
|
||||
data["syslog"]["logBeaconOverTCPIP"] = syslog.logBeaconOverTCPIP;
|
||||
|
||||
data["webadmin"]["active"] = webadmin.active;
|
||||
data["webadmin"]["username"] = webadmin.username;
|
||||
data["webadmin"]["password"] = webadmin.password;
|
||||
data["tnc"]["enableServer"] = tnc.enableServer;
|
||||
data["tnc"]["enableSerial"] = tnc.enableSerial;
|
||||
data["tnc"]["acceptOwn"] = tnc.acceptOwn;
|
||||
|
||||
data["remoteManagement"]["managers"] = remoteManagement.managers;
|
||||
data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly;
|
||||
data["mqtt"]["active"] = mqtt.active;
|
||||
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["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
|
||||
data["ota"]["username"] = ota.username;
|
||||
data["ota"]["password"] = ota.password;
|
||||
|
||||
data["other"]["rebootMode"] = rebootMode;
|
||||
data["other"]["rebootModeTime"] = rebootModeTime;
|
||||
data["webadmin"]["active"] = webadmin.active;
|
||||
data["webadmin"]["username"] = webadmin.username;
|
||||
data["webadmin"]["password"] = webadmin.password;
|
||||
|
||||
data["other"]["rememberStationTime"] = rememberStationTime;
|
||||
data["remoteManagement"]["managers"] = remoteManagement.managers;
|
||||
data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly;
|
||||
|
||||
data["other"]["backupDigiMode"] = backupDigiMode;
|
||||
data["ntp"]["server"] = ntp.server;
|
||||
data["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
|
||||
|
||||
serializeJson(data, configFile);
|
||||
data["other"]["rebootMode"] = rebootMode;
|
||||
data["other"]["rebootModeTime"] = rebootModeTime;
|
||||
|
||||
configFile.close();
|
||||
data["other"]["rememberStationTime"] = rememberStationTime;
|
||||
|
||||
Serial.println("Config saved");
|
||||
delay(200);
|
||||
data["other"]["backupDigiMode"] = backupDigiMode;
|
||||
|
||||
serializeJson(data, configFile);
|
||||
configFile.close();
|
||||
return true;
|
||||
} catch (...) {
|
||||
Serial.println("Error: Exception occurred while saving config");
|
||||
configFile.close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Configuration::readFile() {
|
||||
Serial.println("Reading config..");
|
||||
|
||||
File configFile = SPIFFS.open("/igate_conf.json", "r");
|
||||
|
||||
if (configFile) {
|
||||
StaticJsonDocument<2560> data;
|
||||
bool needsRewrite = false;
|
||||
StaticJsonDocument<3584> data;
|
||||
|
||||
DeserializationError error = deserializeJson(data, configFile);
|
||||
if (error) {
|
||||
@@ -173,12 +192,24 @@ bool Configuration::readFile() {
|
||||
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.timeout = data["wifi"]["autoAP"]["timeout"] | 10;
|
||||
|
||||
if (!data.containsKey("callsign")) needsRewrite = true;
|
||||
callsign = data["callsign"] | "NOCALL-10";
|
||||
|
||||
|
||||
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";
|
||||
@@ -187,7 +218,20 @@ bool Configuration::readFile() {
|
||||
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("gpsAmbiguity")) needsRewrite = true;
|
||||
beacon.latitude = data["beacon"]["latitude"] | 0.0;
|
||||
beacon.longitude = data["beacon"]["longitude"] | 0.0;
|
||||
beacon.comment = data["beacon"]["comment"] | "LoRa APRS";
|
||||
@@ -197,88 +241,147 @@ bool Configuration::readFile() {
|
||||
beacon.path = data["beacon"]["path"] | "WIDE1-1";
|
||||
beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"] | false;
|
||||
beacon.sendViaRF = data["beacon"]["sendViaRF"] | false;
|
||||
|
||||
beacon.beaconFreq = data["beacon"]["beaconFreq"] | 1;
|
||||
beacon.statusActive = data["beacon"]["statusActive"] | false;
|
||||
beacon.statusPacket = data["beacon"]["statusPacket"] | "";
|
||||
|
||||
beacon.gpsActive = data["beacon"]["gpsActive"] | false;
|
||||
beacon.gpsAmbiguity = data["beacon"]["gpsAmbiguity"] | false;
|
||||
|
||||
if (!data.containsKey("personalNote")) needsRewrite = true;
|
||||
personalNote = data["personalNote"] | "personal note here";
|
||||
|
||||
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.ecoMode = data["digi"]["ecoMode"] | 0;
|
||||
if (digi.ecoMode == 1) shouldSleepStop = false;
|
||||
|
||||
#if defined(HAS_A7670)
|
||||
if (digi.ecoMode == 1) digi.ecoMode = 2;
|
||||
#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.spreadingFactor = data["lora"]["spreadingFactor"] | 12;
|
||||
loramodule.signalBandwidth = data["lora"]["signalBandwidth"] | 125000;
|
||||
loramodule.codingRate4 = data["lora"]["codingRate4"] | 5;
|
||||
loramodule.power = data["lora"]["power"] | 20;
|
||||
loramodule.rxSpreadingFactor = data["lora"]["rxSpreadingFactor"] | 12;
|
||||
loramodule.rxCodingRate4 = data["lora"]["rxCodingRate4"] | 5;
|
||||
loramodule.rxSignalBandwidth = data["lora"]["rxSignalBandwidth"] | 125000;
|
||||
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;
|
||||
display.alwaysOn = data["display"]["alwaysOn"] | true;
|
||||
display.timeout = data["display"]["timeout"] | 4;
|
||||
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("externalVoltagePin") ||
|
||||
!data["battery"].containsKey("monitorExternalVoltage") ||
|
||||
!data["battery"].containsKey("externalSleepVoltage") ||
|
||||
!data["battery"].containsKey("voltageDividerR1") ||
|
||||
!data["battery"].containsKey("voltageDividerR2") ||
|
||||
!data["battery"].containsKey("sendVoltageAsTelemetry")) needsRewrite = true;
|
||||
battery.sendInternalVoltage = data["battery"]["sendInternalVoltage"] | false;
|
||||
battery.monitorInternalVoltage = data["battery"]["monitorInternalVoltage"] | false;
|
||||
battery.internalSleepVoltage = data["battery"]["internalSleepVoltage"] | 2.9;
|
||||
|
||||
battery.sendExternalVoltage = data["battery"]["sendExternalVoltage"] | false;
|
||||
battery.externalVoltagePin = data["battery"]["externalVoltagePin"] | 34;
|
||||
battery.monitorExternalVoltage = data["battery"]["monitorExternalVoltage"] | false;
|
||||
battery.externalSleepVoltage = data["battery"]["externalSleepVoltage"] | 10.9;
|
||||
battery.voltageDividerR1 = data["battery"]["voltageDividerR1"] | 100.0;
|
||||
battery.voltageDividerR2 = data["battery"]["voltageDividerR2"] | 27.0;
|
||||
|
||||
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.heightCorrection = data["wxsensor"]["heightCorrection"] | 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.server = data["syslog"]["server"] | "lora.link9.net";
|
||||
syslog.port = data["syslog"]["port"] | 1514;
|
||||
syslog.logBeaconOverTCPIP = data["syslog"]["logBeaconOverTCPIP"] | false;
|
||||
|
||||
if (!data["tnc"].containsKey("enableServer") ||
|
||||
!data["tnc"].containsKey("enableSerial") ||
|
||||
!data["tnc"].containsKey("acceptOwn")) needsRewrite = true;
|
||||
tnc.enableServer = data["tnc"]["enableServer"] | false;
|
||||
tnc.enableSerial = data["tnc"]["enableSerial"] | false;
|
||||
tnc.acceptOwn = data["tnc"]["acceptOwn"] | 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.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.username = data["webadmin"]["username"] | "admin";
|
||||
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;
|
||||
|
||||
if (!data["other"].containsKey("rebootMode") ||
|
||||
!data["other"].containsKey("rebootModeTime")) needsRewrite = true;
|
||||
rebootMode = data["other"]["rebootMode"] | false;
|
||||
rebootModeTime = data["other"]["rebootModeTime"] | 6;
|
||||
|
||||
if (!data["other"].containsKey("rememberStationTime")) needsRewrite = true;
|
||||
rememberStationTime = data["other"]["rememberStationTime"] | 30;
|
||||
|
||||
if (!data["other"].containsKey("backupDigiMode")) needsRewrite = true;
|
||||
backupDigiMode = data["other"]["backupDigiMode"] | false;
|
||||
|
||||
if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP
|
||||
@@ -289,6 +392,13 @@ bool Configuration::readFile() {
|
||||
wifiAPs.push_back(wifiap);
|
||||
}
|
||||
configFile.close();
|
||||
|
||||
if (needsRewrite) {
|
||||
Serial.println("Config JSON incomplete, rewriting...");
|
||||
writeFile();
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
}
|
||||
Serial.println("Config read successfuly");
|
||||
return true;
|
||||
} else {
|
||||
@@ -297,7 +407,7 @@ bool Configuration::readFile() {
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::init() {
|
||||
void Configuration::setDefaultValues() {
|
||||
|
||||
WiFi_AP wifiap;
|
||||
wifiap.ssid = "";
|
||||
@@ -305,6 +415,8 @@ void Configuration::init() {
|
||||
|
||||
wifiAPs.push_back(wifiap);
|
||||
|
||||
startupDelay = 0;
|
||||
|
||||
wifiAutoAP.password = "1234567890";
|
||||
wifiAutoAP.timeout = 10;
|
||||
|
||||
@@ -324,10 +436,12 @@ void Configuration::init() {
|
||||
beacon.interval = 15;
|
||||
beacon.overlay = "L";
|
||||
beacon.symbol = "a";
|
||||
beacon.sendViaAPRSIS = true;
|
||||
beacon.sendViaRF = false;
|
||||
beacon.path = "WIDE1-1";
|
||||
|
||||
beacon.sendViaAPRSIS = true;
|
||||
beacon.sendViaRF = false;
|
||||
beacon.beaconFreq = 1;
|
||||
|
||||
beacon.statusActive = false;
|
||||
beacon.statusPacket = "";
|
||||
|
||||
@@ -341,14 +455,17 @@ void Configuration::init() {
|
||||
digi.mode = 0;
|
||||
digi.ecoMode = 0;
|
||||
|
||||
loramodule.txFreq = 433775000;
|
||||
loramodule.rxFreq = 433775000;
|
||||
loramodule.spreadingFactor = 12;
|
||||
loramodule.signalBandwidth = 125000;
|
||||
loramodule.codingRate4 = 5;
|
||||
loramodule.power = 20;
|
||||
loramodule.txActive = false;
|
||||
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.timeout = 4;
|
||||
@@ -386,6 +503,7 @@ void Configuration::init() {
|
||||
mqtt.username = "";
|
||||
mqtt.password = "";
|
||||
mqtt.port = 1883;
|
||||
mqtt.beaconOverMqtt = false;
|
||||
|
||||
ota.username = "";
|
||||
ota.password = "";
|
||||
@@ -397,6 +515,7 @@ void Configuration::init() {
|
||||
remoteManagement.managers = "";
|
||||
remoteManagement.rfOnly = true;
|
||||
|
||||
ntp.server = "pool.ntp.org";
|
||||
ntp.gmtCorrection = 0.0;
|
||||
|
||||
rebootMode = false;
|
||||
@@ -419,8 +538,9 @@ Configuration::Configuration() {
|
||||
|
||||
bool exists = SPIFFS.exists("/igate_conf.json");
|
||||
if (!exists) {
|
||||
init();
|
||||
setDefaultValues();
|
||||
writeFile();
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
extern Configuration Config;
|
||||
extern uint32_t lastRxTime;
|
||||
extern bool packetIsBeacon;
|
||||
|
||||
extern std::vector<ReceivedPacket> receivedPackets;
|
||||
|
||||
@@ -92,10 +93,10 @@ namespace LoRa_Utils {
|
||||
#if defined(HAS_SX1278) || defined(HAS_SX1276)
|
||||
radio.setDio0Action(setFlag, RISING);
|
||||
#endif
|
||||
radio.setSpreadingFactor(Config.loramodule.spreadingFactor);
|
||||
float signalBandwidth = Config.loramodule.signalBandwidth/1000;
|
||||
radio.setBandwidth(signalBandwidth);
|
||||
radio.setCodingRate(Config.loramodule.codingRate4);
|
||||
radio.setSpreadingFactor(Config.loramodule.rxSpreadingFactor);
|
||||
radio.setCodingRate(Config.loramodule.rxCodingRate4);
|
||||
float signalBandwidth = Config.loramodule.rxSignalBandwidth/1000;
|
||||
radio.setBandwidth(signalBandwidth);
|
||||
radio.setCRC(true);
|
||||
|
||||
#if (defined(RADIO_RXEN) && defined(RADIO_TXEN)) // QRP Labs LightGateway has 400M22S (SX1268)
|
||||
@@ -128,22 +129,30 @@ namespace LoRa_Utils {
|
||||
}
|
||||
|
||||
void changeFreqTx() {
|
||||
delay(500);
|
||||
delay(300);
|
||||
float freq = (float)Config.loramodule.txFreq / 1000000;
|
||||
radio.setFrequency(freq);
|
||||
radio.setSpreadingFactor(Config.loramodule.txSpreadingFactor);
|
||||
radio.setCodingRate(Config.loramodule.txCodingRate4);
|
||||
radio.setBandwidth(Config.loramodule.txSignalBandwidth);
|
||||
}
|
||||
|
||||
void changeFreqRx() {
|
||||
delay(500);
|
||||
delay(300);
|
||||
float freq = (float)Config.loramodule.rxFreq / 1000000;
|
||||
radio.setFrequency(freq);
|
||||
radio.setSpreadingFactor(Config.loramodule.rxSpreadingFactor);
|
||||
radio.setCodingRate(Config.loramodule.rxCodingRate4);
|
||||
radio.setBandwidth(Config.loramodule.rxSignalBandwidth);
|
||||
}
|
||||
|
||||
void sendNewPacket(const String& newPacket) {
|
||||
if (!Config.loramodule.txActive) return;
|
||||
|
||||
if (Config.loramodule.txFreq != Config.loramodule.rxFreq) {
|
||||
changeFreqTx();
|
||||
if (!packetIsBeacon || (packetIsBeacon && Config.beacon.beaconFreq == 1)) {
|
||||
changeFreqTx();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef INTERNAL_LED_PIN
|
||||
@@ -165,7 +174,9 @@ namespace LoRa_Utils {
|
||||
if (Config.digi.ecoMode != 1) digitalWrite(INTERNAL_LED_PIN, LOW); // disabled in Ultra Eco Mode
|
||||
#endif
|
||||
if (Config.loramodule.txFreq != Config.loramodule.rxFreq) {
|
||||
changeFreqRx();
|
||||
if (!packetIsBeacon || (packetIsBeacon && Config.beacon.beaconFreq == 1)) {
|
||||
changeFreqRx();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
extern Configuration Config;
|
||||
|
||||
WiFiUDP ntpUDP;
|
||||
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 15 * 60 * 1000); // Update interval 15 min
|
||||
NTPClient* timeClient;
|
||||
|
||||
|
||||
namespace NTP_Utils {
|
||||
@@ -35,17 +35,17 @@ namespace NTP_Utils {
|
||||
void setup() {
|
||||
if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") {
|
||||
int gmt = Config.ntp.gmtCorrection * 3600;
|
||||
timeClient.setTimeOffset(gmt);
|
||||
timeClient.begin();
|
||||
timeClient = new NTPClient(ntpUDP, Config.ntp.server.c_str(), gmt, 15 * 60 * 1000); // Update interval 15 min
|
||||
timeClient->begin();
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
if (Config.digi.ecoMode == 0) return timeClient.getFormattedTime();
|
||||
if (Config.digi.ecoMode == 0) return timeClient->getFormattedTime();
|
||||
return "DigiEcoMode Active";
|
||||
}
|
||||
|
||||
|
||||
@@ -296,18 +296,6 @@ namespace POWER_Utils {
|
||||
adc_ctrl_OFF();
|
||||
#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_V1) || 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)
|
||||
pinMode(BOARD_POWERON, OUTPUT);
|
||||
digitalWrite(BOARD_POWERON, HIGH);
|
||||
@@ -321,9 +309,20 @@ namespace POWER_Utils {
|
||||
digitalWrite(TFT_CS, HIGH);
|
||||
|
||||
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);
|
||||
#endif
|
||||
|
||||
#ifdef USE_WIRE1_WITH_BOARD_I2C_PINS
|
||||
Wire1.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
|
||||
#endif
|
||||
|
||||
delay(1000);
|
||||
BATTERY_Utils::setup();
|
||||
BATTERY_Utils::startupBatteryHealth();
|
||||
|
||||
@@ -33,13 +33,26 @@ extern bool shouldSleepLowVoltage;
|
||||
|
||||
uint32_t lastTxTime = millis();
|
||||
std::vector<LastHeardStation> lastHeardStations;
|
||||
std::vector<String> outputPacketBuffer;
|
||||
std::vector<Packet25SegBuffer> packet25SegBuffer;
|
||||
std::vector<String> blacklist;
|
||||
std::vector<String> managers;
|
||||
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 packetIsBeacon = false;
|
||||
|
||||
|
||||
namespace STATION_Utils {
|
||||
@@ -138,7 +151,7 @@ namespace STATION_Utils {
|
||||
}
|
||||
}
|
||||
if (!stationHeard) lastHeardStations.emplace_back(LastHeardStation{millis(), station});
|
||||
Utils::activeStations();
|
||||
Utils::showActiveStations();
|
||||
}
|
||||
|
||||
bool wasHeard(const String& station) {
|
||||
@@ -171,7 +184,9 @@ namespace STATION_Utils {
|
||||
size_t currentIndex = 0;
|
||||
while (currentIndex < outputPacketBuffer.size()) { // this sends all packets from output buffer
|
||||
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++;
|
||||
}
|
||||
outputPacketBuffer.clear();
|
||||
@@ -190,13 +205,17 @@ namespace STATION_Utils {
|
||||
uint32_t lastRx = millis() - lastRxTime;
|
||||
uint32_t lastTx = millis() - lastTxTime;
|
||||
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());
|
||||
lastTxTime = millis();
|
||||
}
|
||||
if (shouldSleepLowVoltage) {
|
||||
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());
|
||||
delay(4000);
|
||||
}
|
||||
@@ -209,8 +228,12 @@ namespace STATION_Utils {
|
||||
}
|
||||
}
|
||||
|
||||
void addToOutputPacketBuffer(const String& packet) {
|
||||
outputPacketBuffer.push_back(packet);
|
||||
void addToOutputPacketBuffer(const String& packet, bool flag) {
|
||||
OutputPacketBuffer entry;
|
||||
entry.packet = packet;
|
||||
entry.isBeacon = flag;
|
||||
|
||||
outputPacketBuffer.push_back(entry);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,10 +17,12 @@
|
||||
*/
|
||||
|
||||
#include <WiFi.h>
|
||||
#include "ESPmDNS.h"
|
||||
#include "configuration.h"
|
||||
#include "station_utils.h"
|
||||
#include "kiss_protocol.h"
|
||||
#include "kiss_utils.h"
|
||||
#include "tnc_utils.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
@@ -45,6 +47,17 @@ namespace TNC_Utils {
|
||||
if (Config.tnc.enableServer && Config.digi.ecoMode == 0) {
|
||||
tncServer.stop();
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Utils {
|
||||
if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) {
|
||||
status.concat(":>");
|
||||
status.concat(Config.beacon.statusPacket);
|
||||
STATION_Utils::addToOutputPacketBuffer(status);
|
||||
STATION_Utils::addToOutputPacketBuffer(status, true); // treated also as beacon on Tx Freq
|
||||
statusAfterBoot = false;
|
||||
}
|
||||
}
|
||||
@@ -127,7 +127,7 @@ namespace Utils {
|
||||
seventhLine = " listening...";
|
||||
}
|
||||
|
||||
void activeStations() {
|
||||
void showActiveStations() {
|
||||
char buffer[30]; // Adjust size as needed
|
||||
sprintf(buffer, "Stations (%dmin) = %2d", Config.rememberStationTime, lastHeardStations.size());
|
||||
fourthLine = buffer;
|
||||
@@ -159,7 +159,7 @@ namespace Utils {
|
||||
|
||||
STATION_Utils::deleteNotHeard();
|
||||
|
||||
activeStations();
|
||||
showActiveStations();
|
||||
|
||||
beaconPacket = iGateBeaconPacket;
|
||||
secondaryBeaconPacket = iGateLoRaBeaconPacket;
|
||||
@@ -259,7 +259,7 @@ namespace Utils {
|
||||
Utils::println("-- Sending Beacon to RF --");
|
||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING DIGI BEACON", 0);
|
||||
seventhLine = " listening...";
|
||||
STATION_Utils::addToOutputPacketBuffer(secondaryBeaconPacket);
|
||||
STATION_Utils::addToOutputPacketBuffer(secondaryBeaconPacket, true);
|
||||
}
|
||||
|
||||
lastBeaconTx = millis();
|
||||
@@ -284,6 +284,7 @@ namespace Utils {
|
||||
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);
|
||||
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();
|
||||
ESP.restart();
|
||||
}
|
||||
@@ -436,4 +437,11 @@ namespace Utils {
|
||||
return true;
|
||||
}
|
||||
|
||||
void startupDelay() {
|
||||
if (Config.startupDelay > 0) {
|
||||
displayShow("", " STARTUP DELAY ...", "", "", 0);
|
||||
delay(Config.startupDelay * 60 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -115,159 +115,208 @@ namespace WEB_Utils {
|
||||
}
|
||||
|
||||
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 = {};
|
||||
|
||||
for (int i=0; i<networks; i++) {
|
||||
for (int i = 0; i < networks; i++) {
|
||||
WiFi_AP wifiap;
|
||||
wifiap.ssid = request->getParam("wifi.AP." + String(i) + ".ssid", true)->value();
|
||||
wifiap.password = request->getParam("wifi.AP." + String(i) + ".password", true)->value();
|
||||
wifiap.ssid = getParamStringSafe("wifi.AP." + String(i) + ".ssid");
|
||||
wifiap.password = getParamStringSafe("wifi.AP." + String(i) + ".password");
|
||||
|
||||
Config.wifiAPs.push_back(wifiap);
|
||||
}
|
||||
|
||||
Config.callsign = request->getParam("callsign", true)->value();
|
||||
|
||||
Config.wifiAutoAP.password = request->getParam("wifi.autoAP.password", true)->value();
|
||||
Config.wifiAutoAP.timeout = request->getParam("wifi.autoAP.timeout", true)->value().toInt();
|
||||
Config.startupDelay = getParamIntSafe("startupDelay", Config.startupDelay);
|
||||
|
||||
Config.callsign = getParamStringSafe("callsign", Config.callsign);
|
||||
|
||||
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);
|
||||
if (Config.aprs_is.active) {
|
||||
Config.aprs_is.messagesToRF = request->hasParam("aprs_is.messagesToRF", true);
|
||||
Config.aprs_is.objectsToRF = request->hasParam("aprs_is.objectsToRF", true);
|
||||
Config.aprs_is.server = request->getParam("aprs_is.server", true)->value();
|
||||
Config.aprs_is.passcode = request->getParam("aprs_is.passcode", 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.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 = request->getParam("beacon.interval", true)->value().toInt();
|
||||
Config.beacon.interval = getParamIntSafe("beacon.interval", Config.beacon.interval);
|
||||
Config.beacon.sendViaAPRSIS = request->hasParam("beacon.sendViaAPRSIS", true);
|
||||
Config.beacon.sendViaRF = request->hasParam("beacon.sendViaRF", true);
|
||||
Config.beacon.latitude = request->getParam("beacon.latitude", true)->value().toDouble();
|
||||
Config.beacon.longitude = request->getParam("beacon.longitude", true)->value().toDouble();
|
||||
Config.beacon.comment = request->getParam("beacon.comment", true)->value();
|
||||
Config.beacon.overlay = request->getParam("beacon.overlay", true)->value();
|
||||
Config.beacon.symbol = request->getParam("beacon.symbol", true)->value();
|
||||
Config.beacon.path = request->getParam("beacon.path", true)->value();
|
||||
Config.beacon.beaconFreq = getParamIntSafe("beacon.beaconFreq", Config.beacon.beaconFreq);
|
||||
Config.beacon.latitude = getParamDoubleSafe("beacon.latitude", Config.beacon.latitude);
|
||||
Config.beacon.longitude = getParamDoubleSafe("beacon.longitude", Config.beacon.longitude);
|
||||
Config.beacon.comment = getParamStringSafe("beacon.comment", Config.beacon.comment);
|
||||
Config.beacon.overlay = getParamStringSafe("beacon.overlay", Config.beacon.overlay);
|
||||
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);
|
||||
if (Config.beacon.statusActive) {
|
||||
Config.beacon.statusPacket = request->getParam("beacon.statusPacket", true)->value();
|
||||
Config.beacon.statusPacket = getParamStringSafe("beacon.statusPacket", Config.beacon.statusPacket);
|
||||
}
|
||||
|
||||
Config.beacon.gpsActive = request->hasParam("beacon.gpsActive", true);
|
||||
Config.beacon.gpsAmbiguity = request->hasParam("beacon.gpsAmbiguity", true);
|
||||
|
||||
Config.personalNote = request->getParam("personalNote", true)->value();
|
||||
Config.personalNote = getParamStringSafe("personalNote", Config.personalNote);
|
||||
|
||||
Config.blacklist = request->getParam("blacklist", true)->value();
|
||||
Config.blacklist = getParamStringSafe("blacklist", Config.blacklist);
|
||||
|
||||
Config.digi.mode = request->getParam("digi.mode", true)->value().toInt();
|
||||
Config.digi.ecoMode = request->getParam("digi.ecoMode", true)->value().toInt();;
|
||||
Config.digi.mode = getParamIntSafe("digi.mode", Config.digi.mode);
|
||||
Config.digi.ecoMode = getParamIntSafe("digi.ecoMode", Config.digi.ecoMode);
|
||||
|
||||
|
||||
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.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);
|
||||
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.battery.sendInternalVoltage = request->hasParam("battery.sendInternalVoltage", true);
|
||||
Config.battery.monitorInternalVoltage = request->hasParam("battery.monitorInternalVoltage", true);
|
||||
Config.battery.sendInternalVoltage = request->hasParam("battery.sendInternalVoltage", true);
|
||||
Config.battery.monitorInternalVoltage = request->hasParam("battery.monitorInternalVoltage", true);
|
||||
if (Config.battery.monitorInternalVoltage) {
|
||||
Config.battery.internalSleepVoltage = request->getParam("battery.internalSleepVoltage", true)->value().toFloat();
|
||||
}
|
||||
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) {
|
||||
Config.battery.externalVoltagePin = request->getParam("battery.externalVoltagePin", true)->value().toInt();
|
||||
Config.battery.voltageDividerR1 = request->getParam("battery.voltageDividerR1", true)->value().toFloat();
|
||||
Config.battery.voltageDividerR2 = request->getParam("battery.voltageDividerR2", true)->value().toFloat();
|
||||
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);
|
||||
if (Config.battery.monitorExternalVoltage) {
|
||||
Config.battery.externalSleepVoltage = request->getParam("battery.externalSleepVoltage", true)->value().toFloat();
|
||||
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);
|
||||
if (Config.wxsensor.active) {
|
||||
Config.wxsensor.heightCorrection = request->getParam("wxsensor.heightCorrection", true)->value().toInt();
|
||||
Config.wxsensor.temperatureCorrection = request->getParam("wxsensor.temperatureCorrection", true)->value().toFloat();
|
||||
Config.wxsensor.heightCorrection = getParamIntSafe("wxsensor.heightCorrection", Config.wxsensor.heightCorrection);
|
||||
Config.wxsensor.temperatureCorrection = getParamFloatSafe("wxsensor.temperatureCorrection", Config.wxsensor.temperatureCorrection);
|
||||
Config.beacon.symbol = "_";
|
||||
}
|
||||
|
||||
|
||||
Config.syslog.active = request->hasParam("syslog.active", true);
|
||||
if (Config.syslog.active) {
|
||||
Config.syslog.server = request->getParam("syslog.server", true)->value();
|
||||
Config.syslog.port = request->getParam("syslog.port", true)->value().toInt();
|
||||
Config.syslog.server = getParamStringSafe("syslog.server", Config.syslog.server);
|
||||
Config.syslog.port = getParamIntSafe("syslog.port", Config.syslog.port);
|
||||
Config.syslog.logBeaconOverTCPIP = request->hasParam("syslog.logBeaconOverTCPIP", true);
|
||||
}
|
||||
|
||||
|
||||
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
|
||||
Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true);
|
||||
Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true);
|
||||
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
|
||||
Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true);
|
||||
Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true);
|
||||
|
||||
|
||||
Config.mqtt.active = request->hasParam("mqtt.active", true);
|
||||
Config.mqtt.active = request->hasParam("mqtt.active", true);
|
||||
if (Config.mqtt.active) {
|
||||
Config.mqtt.server = request->getParam("mqtt.server", true)->value();
|
||||
Config.mqtt.topic = request->getParam("mqtt.topic", true)->value();
|
||||
Config.mqtt.username = request->getParam("mqtt.username", true)->value();
|
||||
Config.mqtt.password = request->getParam("mqtt.password", true)->value();
|
||||
Config.mqtt.port = request->getParam("mqtt.port", true)->value().toInt();
|
||||
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);
|
||||
if (Config.rebootMode) {
|
||||
Config.rebootModeTime = request->getParam("other.rebootModeTime", true)->value().toInt();
|
||||
Config.rebootModeTime = getParamIntSafe("other.rebootModeTime", Config.rebootModeTime);
|
||||
}
|
||||
|
||||
Config.ota.username = request->getParam("ota.username", true)->value();
|
||||
Config.ota.password = request->getParam("ota.password", true)->value();
|
||||
Config.ota.username = getParamStringSafe("ota.username", Config.ota.username);
|
||||
Config.ota.password = getParamStringSafe("ota.password", Config.ota.password);
|
||||
|
||||
Config.webadmin.active = request->hasParam("webadmin.active", true);
|
||||
if (Config.webadmin.active) {
|
||||
Config.webadmin.username = request->getParam("webadmin.username", true)->value();
|
||||
Config.webadmin.password = request->getParam("webadmin.password", true)->value();
|
||||
Config.webadmin.username = getParamStringSafe("webadmin.username", Config.webadmin.username);
|
||||
Config.webadmin.password = getParamStringSafe("webadmin.password", Config.webadmin.password);
|
||||
}
|
||||
|
||||
Config.remoteManagement.managers = request->getParam("remoteManagement.managers", true)->value();
|
||||
Config.remoteManagement.managers = getParamStringSafe("remoteManagement.managers", Config.remoteManagement.managers);
|
||||
Config.remoteManagement.rfOnly = request->hasParam("remoteManagement.rfOnly", true);
|
||||
|
||||
Config.ntp.gmtCorrection = request->getParam("ntp.gmtCorrection", true)->value().toFloat();
|
||||
Config.ntp.server = getParamStringSafe("ntp.server", Config.ntp.server);
|
||||
Config.ntp.gmtCorrection = getParamFloatSafe("ntp.gmtCorrection", Config.ntp.gmtCorrection);
|
||||
|
||||
Config.rememberStationTime = request->getParam("other.rememberStationTime", true)->value().toInt();
|
||||
Config.rememberStationTime = getParamIntSafe("other.rememberStationTime", Config.rememberStationTime);
|
||||
|
||||
Config.backupDigiMode = request->hasParam("other.backupDigiMode", true);
|
||||
|
||||
bool saveSuccess = Config.writeFile();
|
||||
|
||||
Config.writeFile();
|
||||
|
||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
|
||||
response->addHeader("Location", "/");
|
||||
request->send(response);
|
||||
displayToggle(false);
|
||||
delay(200);
|
||||
ESP.restart();
|
||||
if (saveSuccess) {
|
||||
Serial.println("Configuration saved successfully");
|
||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
|
||||
response->addHeader("Location", "/?success=1");
|
||||
request->send(response);
|
||||
|
||||
displayToggle(false);
|
||||
delay(500);
|
||||
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) {
|
||||
|
||||
@@ -71,6 +71,7 @@ namespace WX_Utils {
|
||||
#endif
|
||||
err = Wire.endTransmission();
|
||||
#endif
|
||||
delay(5);
|
||||
if (err == 0) {
|
||||
//Serial.println(addr); //this shows any connected board to I2C
|
||||
if (addr == 0x76 || addr == 0x77) { // BME or BMP
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_NUM_3
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -34,8 +34,11 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
#define HAS_DISPLAY
|
||||
|
||||
#undef OLED_SDA
|
||||
#undef OLED_SCL
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_33
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#define RADIO_RST_PIN 0
|
||||
#define RADIO_BUSY_PIN 32
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#define RADIO_RST_PIN 0
|
||||
#define RADIO_BUSY_PIN 32
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
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
|
||||
8
variants/LoRaHAM_V2/platformio.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[env:LoRaHAM_V2]
|
||||
board = esp32dev
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
-D LoRaHAM_V2
|
||||
lib_deps =
|
||||
${common.lib_deps}
|
||||
${common.display_libs}
|
||||
@@ -34,6 +34,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_33
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_5
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_5
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -30,7 +30,10 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_25
|
||||
|
||||
// Display
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
#undef OLED_SDA
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||
#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
|
||||
#define INTERNAL_LED_PIN 15
|
||||
|
||||
|
||||
@@ -36,5 +36,10 @@
|
||||
|
||||
#define BUTTON_PIN 21
|
||||
#define INTERNAL_LED_PIN 48
|
||||
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
#define OLED_SDA 5
|
||||
#define OLED_SCL 6
|
||||
|
||||
#endif
|
||||
@@ -30,6 +30,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_14
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
#define USE_WIRE1_WITH_BOARD_I2C_PINS
|
||||
#define BOARD_I2C_SDA 41
|
||||
#define BOARD_I2C_SCL 42
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
@@ -48,7 +54,5 @@
|
||||
#define BATTERY_PIN 1
|
||||
#define VEXT_CTRL 36
|
||||
#define ADC_CTRL 37
|
||||
#define BOARD_I2C_SDA 41
|
||||
#define BOARD_I2C_SCL 42
|
||||
|
||||
#endif
|
||||
@@ -31,6 +31,12 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_14
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
#define USE_WIRE1_WITH_BOARD_I2C_PINS
|
||||
#define BOARD_I2C_SDA 41
|
||||
#define BOARD_I2C_SCL 42
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
@@ -48,7 +54,5 @@
|
||||
#define BATTERY_PIN 1
|
||||
#define VEXT_CTRL 36
|
||||
#define ADC_CTRL 37
|
||||
#define BOARD_I2C_SDA 41
|
||||
#define BOARD_I2C_SCL 42
|
||||
|
||||
#endif
|
||||
55
variants/heltec_wireless_bridge/board_pinout.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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_SX1276
|
||||
#define RADIO_SCLK_PIN 5
|
||||
#define RADIO_MISO_PIN 19
|
||||
#define RADIO_MOSI_PIN 27
|
||||
#define RADIO_CS_PIN 18
|
||||
#define RADIO_RST_PIN 14
|
||||
#define RADIO_BUSY_PIN 26
|
||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
||||
|
||||
// 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
|
||||
|
||||
// Aditional Config
|
||||
#define INTERNAL_LED_PIN 16
|
||||
/*
|
||||
Green LED (Lora): PIN 22 / GPIO2
|
||||
Yellow LED (Wifi): PIN 23 / GPIO0
|
||||
Blue LED (BT/BLE): PIN 25 / GPIO16
|
||||
*/
|
||||
|
||||
#endif
|
||||
8
variants/heltec_wireless_bridge/platformio.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[env:heltec_wireless_bridge]
|
||||
board = esp32dev
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
-D HELTEC_WIRELESS_BRIDGE
|
||||
lib_deps =
|
||||
${common.lib_deps}
|
||||
${common.display_libs}
|
||||
@@ -31,6 +31,11 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_14
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE1_WITH_BOARD_I2C_PINS
|
||||
#define BOARD_I2C_SDA 37
|
||||
#define BOARD_I2C_SCL 36
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
#define HAS_EPAPER
|
||||
@@ -46,7 +51,5 @@
|
||||
#define BATTERY_PIN 20
|
||||
#define ADC_CTRL 19
|
||||
#define VEXT_CTRL 45
|
||||
#define BOARD_I2C_SDA 37
|
||||
#define BOARD_I2C_SCL 36
|
||||
|
||||
#endif
|
||||
@@ -31,6 +31,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_14
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -31,12 +31,15 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_14
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE1_WITH_BOARD_I2C_PINS
|
||||
#define BOARD_I2C_SDA 41
|
||||
#define BOARD_I2C_SCL 42
|
||||
|
||||
// Aditional Config
|
||||
#define INTERNAL_LED_PIN 35
|
||||
#define BATTERY_PIN 1
|
||||
#define VEXT_CTRL 36
|
||||
#define ADC_CTRL 37
|
||||
#define BOARD_I2C_SDA 41
|
||||
#define BOARD_I2C_SCL 42
|
||||
|
||||
#endif
|
||||
@@ -31,6 +31,11 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_14
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE1_WITH_BOARD_I2C_PINS
|
||||
#define BOARD_I2C_SDA 41
|
||||
#define BOARD_I2C_SCL 42
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
|
||||
@@ -40,7 +45,5 @@
|
||||
#define BATTERY_PIN 1
|
||||
#define VEXT_CTRL 36
|
||||
#define ADC_CTRL 37
|
||||
#define BOARD_I2C_SDA 41
|
||||
#define BOARD_I2C_SCL 42
|
||||
|
||||
#endif
|
||||
@@ -30,6 +30,11 @@
|
||||
#define RADIO_BUSY_PIN 13 // SX1262 BUSY
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_14
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_BOARD_I2C_PINS
|
||||
#define BOARD_I2C_SDA 7
|
||||
#define BOARD_I2C_SCL 6
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
@@ -40,8 +45,6 @@
|
||||
#define BATTERY_PIN 1
|
||||
#define ADC_CTRL 2 // HELTEC Wireless Tracker ADC_CTRL = HIGH powers the voltage divider to read BatteryPin. Only on V05 = V1.1
|
||||
#define VEXT_CTRL 3 // To turn on GPS and TFT
|
||||
#define BOARD_I2C_SDA 7
|
||||
#define BOARD_I2C_SCL 6
|
||||
|
||||
// GPS
|
||||
#define HAS_GPS
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
@@ -43,7 +46,7 @@
|
||||
|
||||
// Aditional Config
|
||||
#define INTERNAL_LED_PIN 25 // Green Led
|
||||
#define BATTERY_PIN 35
|
||||
#define HAS_ADC_CALIBRATION
|
||||
#define BATTERY_PIN 35
|
||||
#define HAS_ADC_CALIBRATION
|
||||
|
||||
#endif
|
||||
@@ -30,6 +30,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_BUSY_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_26
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_33
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_OLED_PINS
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_45
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_BOARD_I2C_PINS
|
||||
#define BOARD_I2C_SDA 18
|
||||
#define BOARD_I2C_SCL 8
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
#define HAS_TFT
|
||||
@@ -50,7 +55,4 @@
|
||||
#define BOARD_SDCARD_CS 39
|
||||
#define BOARD_BL_PIN 42
|
||||
|
||||
#define BOARD_I2C_SDA 18
|
||||
#define BOARD_I2C_SCL 8
|
||||
|
||||
#endif
|
||||
@@ -31,6 +31,11 @@
|
||||
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||
#define GPIO_WAKEUP_PIN GPIO_SEL_45
|
||||
|
||||
// I2C
|
||||
#define USE_WIRE_WITH_BOARD_I2C_PINS
|
||||
#define BOARD_I2C_SDA 18
|
||||
#define BOARD_I2C_SCL 8
|
||||
|
||||
// Display
|
||||
#define HAS_DISPLAY
|
||||
#define HAS_TFT
|
||||
@@ -51,7 +56,4 @@
|
||||
#define BOARD_SDCARD_CS 39
|
||||
#define BOARD_BL_PIN 42
|
||||
|
||||
#define BOARD_I2C_SDA 18
|
||||
#define BOARD_I2C_SCL 8
|
||||
|
||||
#endif
|
||||