Compare commits

...

89 Commits

Author SHA1 Message Date
richonguzman 61db6c3132 backUpDigiMode and BME for HWSL v3 fix 2024-08-13 17:56:27 -04:00
richonguzman 9521a357b1 readmeUpdate 2024-08-13 14:49:30 -04:00
richonguzman ee95931f00 web user and password 2024-08-13 14:48:08 -04:00
richonguzman 60aa2b05ac more boards update 2024-08-13 12:46:20 -04:00
richonguzman bc5183a192 Ht-ct62 updates 2024-08-13 12:36:37 -04:00
richonguzman 1019306c7c wide2-n fix 2024-08-12 13:49:58 -04:00
richonguzman fbe00903ad version Date on footer added 2024-08-12 11:01:35 -04:00
richonguzman 291a6bc80e added mesh - diy board v1-2 2024-08-12 10:35:45 -04:00
richonguzman 3b550c7f81 mode3 fix WIDE2-2 2024-08-06 10:57:00 -04:00
richonguzman 4659f8b2ff mode3start 2024-08-06 10:11:50 -04:00
richonguzman 62d157d7f0 state add at boot 2024-08-06 09:12:01 -04:00
richonguzman b0e116ee1d Readme Update Digis 2024-08-05 17:42:59 -04:00
richonguzman 00b12c2bf5 version update 2024-08-05 15:43:42 -04:00
richonguzman 85b21565db index fix 2024-08-05 15:43:02 -04:00
richonguzman b9e2c0e8f0 digimode 3 improvement 2024-08-05 15:42:33 -04:00
richonguzman b763b4af78 RNAAAA add + WIDE2 description in index 2024-08-05 15:20:58 -04:00
richonguzman 5553e7ae5c added mode 3 for digirepeater 2024-08-05 14:37:16 -04:00
richonguzman 1afd039c3f digi mode 3 added 2024-08-03 21:55:32 -04:00
richonguzman 1888084f31 WSL v3 wire1 add 2024-08-02 16:15:10 -04:00
richonguzman dc92b822c8 fixed missing wire begin 2024-08-02 15:28:31 -04:00
richonguzman 3c305259e0 update to recover from wifi AP 2024-08-02 13:08:54 -04:00
richonguzman 497d648c17 ready for testing 2024-07-18 14:41:09 -04:00
richonguzman d267f6699c HWSL_V3_Display add 2024-07-17 16:20:20 -04:00
richonguzman 16ce6bc6d2 a7670 voltage calibration fix 2024-07-17 10:47:42 -04:00
richonguzman 008b6250ea Non Ham mods only for Rx 2024-07-10 15:13:57 -04:00
richonguzman ddb83d1368 voltageCalibrationCorrection 2024-07-10 09:49:13 -04:00
richonguzman 26e2dec2b2 font size update 2024-07-09 10:41:26 -04:00
richonguzman 174507377b fix for other boards 2024-07-09 08:39:59 -04:00
richonguzman 864ed44a5d favicon and battery adc calibration 2024-07-08 23:29:04 -04:00
richonguzman 5d69cfbe1c 1 2024-07-08 23:06:03 -04:00
richonguzman e57d356fd1 new ADC calibration test 2024-07-08 23:02:45 -04:00
richonguzman 8381f0916c variable name change 2024-07-05 13:12:21 -04:00
richonguzman beca09293a queryUppercase fix 2024-07-05 11:58:18 -04:00
richonguzman dcca18eeac readme Update 2024-07-01 18:30:11 -04:00
richonguzman 2494acea55 espacio en blanco 2024-06-30 10:36:15 -04:00
richonguzman 0c50ce8de4 tyeofpacket update 2024-06-30 09:24:21 -04:00
richonguzman 2f07d35861 readmeupdate7 2024-06-28 16:20:07 -04:00
richonguzman 91240c5be6 readmeupdate6 2024-06-28 16:19:18 -04:00
richonguzman b4308a95d5 readmeupdate5 2024-06-28 16:18:41 -04:00
richonguzman 6c301795d6 readmeupdate4 2024-06-28 16:18:13 -04:00
richonguzman 5f0c6f4986 readmeupdate3 2024-06-28 16:15:56 -04:00
richonguzman 7c989e6e9e readmeupdate2 2024-06-28 16:15:22 -04:00
richonguzman 2bcda6d3a4 readme update 2024-06-28 16:14:42 -04:00
richonguzman 848492dc36 updated QueryAnswer for 3rdPartyPacket 2024-06-28 16:05:04 -04:00
richonguzman 413bef67fb readme update 2024-06-27 16:25:58 -04:00
richonguzman 3fa4c9371a new battery web config 2024-06-27 16:02:20 -04:00
richonguzman e846c38f97 externalBatdivider 2024-06-27 15:39:53 -04:00
richonguzman b8446e3f1d bat and sh gone 2024-06-27 13:19:51 -04:00
richonguzman c3984bc8da casi listo para prueba 2024-06-26 23:42:24 -04:00
richonguzman 601b72da9f funciona 2024-06-26 18:13:02 -04:00
richonguzman 5d9493314d casi 2024-06-26 17:56:11 -04:00
richonguzman 86cf12d6c1 carga datos base 2024-06-26 17:10:07 -04:00
richonguzman e5e2c6a980 readmeUpdate 2024-06-26 13:26:17 -04:00
richonguzman 3b9d49c5f9 personalNote implementation 2024-06-26 13:24:36 -04:00
richonguzman ab9443140b personalNote1 2024-06-26 13:05:45 -04:00
richonguzman ad1129c588 callsign validation process fix 2024-06-25 16:36:49 -04:00
richonguzman 8bb0b0446c more 3rd party filtering 2024-06-24 13:25:30 -04:00
richonguzman 6b1d319901 fix firstColon on last position 2024-06-24 11:36:40 -04:00
richonguzman 1ceaf159ba colonIndex fix3 2024-06-24 11:18:42 -04:00
richonguzman f1de8d2df0 colonIndex upload fix 2024-06-24 11:16:52 -04:00
richonguzman b9b4f46c66 typeOfPacket fix3 2024-06-24 11:02:38 -04:00
richonguzman 22b2c679d2 typeofPacket initial fix 2024-06-24 10:54:21 -04:00
richonguzman 7baa98bf7e first 3rdparty correction 2024-06-24 10:32:58 -04:00
richonguzman 35e79709e3 HeltecWSL V3 battery reading fix 2024-06-21 15:33:56 -04:00
richonguzman f4bae74c26 build fix 2024-06-21 11:38:54 -04:00
richonguzman 04e721ac5a build correction 2024-06-21 11:15:52 -04:00
richonguzman 1922d7453b readmeUpdate 3rd Party 2024-06-21 11:11:40 -04:00
richonguzman f1bd751585 readmeUpdate3rdParty 2024-06-21 11:02:34 -04:00
richonguzman c346bc0f39 version and readme update 2024-06-21 10:58:54 -04:00
richonguzman bbc1996918 update const String 2024-06-21 02:13:34 -04:00
richonguzman 505bb3d5a4 version update 2024-06-20 21:14:30 -04:00
richonguzman b97457146a many updates const String and 3rd party 2024-06-20 21:12:54 -04:00
richonguzman 64b51fea72 first test with new 3rdParty 2024-06-20 14:06:14 -04:00
richonguzman d82cf9235d starting with builing Tx packet 2024-06-18 23:42:09 -04:00
richonguzman d83bb19bc8 A7670 code cleanup 2024-06-18 19:55:33 -04:00
richonguzman 0feb0045d0 build update 2024-06-18 19:36:17 -04:00
richonguzman 4999c89820 all boards with 915 versions added 2024-06-18 19:30:34 -04:00
richonguzman f5048edf84 all sx1276 added 2024-06-18 18:43:25 -04:00
richonguzman 691f60925a only digi with packetbuffer25seg 2024-06-18 16:45:01 -04:00
richonguzman 4bf4e781df not callsign filtering from aprs-is feed 2024-06-18 15:29:00 -04:00
richonguzman 0c09f5a934 callsign filter changed 2024-06-18 15:15:27 -04:00
richonguzman 494be4a393 readmeupdate5 2024-06-17 21:41:29 -04:00
richonguzman 16e79d291c readmeupdate4 2024-06-17 21:40:54 -04:00
richonguzman c9a52d5b61 readmeupdate3 2024-06-17 21:40:30 -04:00
richonguzman 7d813524e3 readme update2 2024-06-17 21:39:26 -04:00
richonguzman 2d7d02f2df update readme 2024-06-17 21:37:53 -04:00
richonguzman 562b0a46ea update of Configuration images 2024-06-17 20:32:39 -04:00
richonguzman 69c074a834 readmeMods 2024-06-16 20:55:54 -04:00
richonguzman bf04507ed0 new webflasher image 2024-06-16 20:53:36 -04:00
60 changed files with 1192 additions and 648 deletions
+25 -7
View File
@@ -13,6 +13,8 @@ jobs:
target: target:
- name: ttgo-lora32-v21 - name: ttgo-lora32-v21
chip: esp32 chip: esp32
- name: ttgo-lora32-v21_915
chip: esp32
- name: heltec-lora32-v2 - name: heltec-lora32-v2
chip: esp32 chip: esp32
- name: heltec_wifi_lora_32_V3 - name: heltec_wifi_lora_32_V3
@@ -21,34 +23,50 @@ jobs:
chip: esp32s3 chip: esp32s3
- name: heltec_wireless_stick_lite_v3 - name: heltec_wireless_stick_lite_v3
chip: esp32s3 chip: esp32s3
- name: heltec_wireless_stick_lite_v3_display
chip: esp32s3
- name: ESP32_DIY_LoRa - name: ESP32_DIY_LoRa
chip: esp32 chip: esp32
- name: ESP32_DIY_LoRa_915
chip: esp32
- name: ESP32_DIY_1W_LoRa - name: ESP32_DIY_1W_LoRa
chip: esp32 chip: esp32
- name: ESP32_DIY_1W_LoRa_915
chip: esp32
- name: ESP32_DIY_1W_LoRa_Mesh_V1_2
chip: esp32
- name: ttgo-t-beam-v1_2 - name: ttgo-t-beam-v1_2
chip: esp32 chip: esp32
- name: ttgo-t-beam-v1_2_915
chip: esp32
- name: ttgo-t-beam-v1 - name: ttgo-t-beam-v1
chip: esp32 chip: esp32
- name: ttgo-t-beam-v1_915
chip: esp32
- name: ttgo-t-beam-v1_SX1268 - name: ttgo-t-beam-v1_SX1268
chip: esp32 chip: esp32
- name: ttgo-t-beam-v1_2_SX1262 - name: ttgo-t-beam-v1_2_SX1262
chip: esp32 chip: esp32
- name: ESP32_DIY_LoRa_A7670 - name: ESP32_DIY_LoRa_A7670
chip: esp32 chip: esp32
- name: ESP32_DIY_LoRa_A7670_915
chip: esp32
- name: heltec_wireless_tracker - name: heltec_wireless_tracker
chip: esp32s3 chip: esp32s3
- name: heltec_ht-ct62
chip: esp32c3
- name: OE5HWN_MeshCom - name: OE5HWN_MeshCom
chip: esp32 chip: esp32
- name: WEMOS-LOLIN32-OLED-DIY - name: WEMOS-LOLIN32-OLED-DIY
chip: esp32 chip: esp32
- name: WEMOS-D1-R32-RA02 - name: WEMOS-D1-R32-RA02
chip: esp32 chip: esp32
- name: ttgo-lora32-v21-915
chip: esp32
- name: heltec_ht-ct62
chip: esp32c3
- name: esp32c3_DIY_1W_LoRa - name: esp32c3_DIY_1W_LoRa
chip: esp32c3 chip: esp32c3
- name: esp32c3_DIY_1W_LoRa_915
chip: esp32c3
- name: ESP32_C3_OctopusLab_LoRa
chip: esp32c3
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@@ -81,7 +99,7 @@ jobs:
run: | run: |
if [ "${{ matrix.target.chip }}" == "esp32" ]; then if [ "${{ matrix.target.chip }}" == "esp32" ]; then
python installer/bin/esptool/esptool.py --chip esp32 merge_bin \ python installer/bin/esptool/esptool.py --chip esp32 merge_bin \
-o installer/web_factory_${{ matrix.target.name }}.bin \ -o installer/web_factory.bin \
--flash_mode dio \ --flash_mode dio \
--flash_freq 40m \ --flash_freq 40m \
--flash_size 4MB \ --flash_size 4MB \
@@ -92,7 +110,7 @@ jobs:
0x3D0000 installer/firmware/spiffs.bin 0x3D0000 installer/firmware/spiffs.bin
elif [ "${{ matrix.target.chip }}" == "esp32s3" ]; then elif [ "${{ matrix.target.chip }}" == "esp32s3" ]; then
python installer/bin/esptool/esptool.py --chip esp32s3 merge_bin \ python installer/bin/esptool/esptool.py --chip esp32s3 merge_bin \
-o installer/web_factory_${{ matrix.target.name }}.bin \ -o installer/web_factory.bin \
--flash_mode dio \ --flash_mode dio \
--flash_freq 40m \ --flash_freq 40m \
--flash_size 8MB \ --flash_size 8MB \
@@ -103,7 +121,7 @@ jobs:
0x3D0000 installer/firmware/spiffs.bin 0x3D0000 installer/firmware/spiffs.bin
elif [ "${{ matrix.target.chip }}" == "esp32c3" ]; then elif [ "${{ matrix.target.chip }}" == "esp32c3" ]; then
python installer/bin/esptool/esptool.py --chip esp32c3 merge_bin \ python installer/bin/esptool/esptool.py --chip esp32c3 merge_bin \
-o installer/web_factory_${{ matrix.target.name }}.bin \ -o installer/web_factory.bin \
--flash_mode dio \ --flash_mode dio \
--flash_freq 40m \ --flash_freq 40m \
--flash_size 4MB \ --flash_size 4MB \
+29 -25
View File
@@ -1,58 +1,62 @@
# Richonguzman / CA2RXU LoRa APRS iGate/Digirepeater # CA2RXU LoRa APRS iGate/Digirepeater
This firmware is for using ESP32 based boards with LoRa Modules and GPS to live in the APRS world. This firmware is for using ESP32 based boards with LoRa Modules and GPS to live in the APRS world.
![Screenshot](https://github.com/richonguzman/LoRa_APRS_iGate/blob/main/images/iGateOledScreen.jpeg) ![Screenshot](https://github.com/richonguzman/LoRa_APRS_iGate/blob/main/images/iGateOledScreen.jpeg)
__(NOTE: This iGate Firmware was develop to work with all LoRa APRS Trackers and specially with this firmware <a href="https://github.com/richonguzman/LoRa_APRS_Tracker" target="_blank">LoRa APRS Tracker</a>)__ __(This iGate Firmware works with all LoRa Tracker Firmwares (specially this <a href="https://github.com/richonguzman/LoRa_APRS_Tracker" target="_blank">LoRa APRS Tracker Firmware</a>))__
<br />
___________________________________________________
## You can support this project to continue to grow: ## 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) [<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 INSTALLER # WEB FLASHER/INSTALLER is <a href="https://richonguzman.github.io/lora-igate-web-flasher/installer.html" target="_blank">here</a>
<br />
As easy as it gets, the new <a href="https://sq2cpa.github.io/lora-flasher/ca2rxu.html" target="_blank">Web Installer</a> (thanks Damian SQ2CPA) # WIKI
[<img src="https://github.com/richonguzman/LoRa_APRS_iGate/blob/main/images/WebFlasher.png">](https://sq2cpa.github.io/lora-flasher/ca2rxu.html) ### 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 # SUPPORTED BOARDS
- TTGO Lilygo LoRa32 v2.1 / v1.6 (they work the same) ### Buying links --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/108.-Supported-Boards-and-Buying-Links" target="_blank">here</a>.
- TTGO T-Beam v1.0 , v1.1, v1.2 (also variations with SX1262 and SX1268 LoRa Modules) (NOTE: all boards with 433-868-915 MHz versions)
- HELTEC V2, V3 , Wireless Stick, HT-CT62, Wireless Tracker - TTGO Lilygo LoRa32 v2.1 / v1.6 (they work the same).
- ESP32 Wroom + SX1278 LoRa Module or 400M30S 1W LoRa Module for a DIY Versions. - TTGO T-Beam v1.0 , v1.1, v1.2 (also variations with SX1262 and SX1268 LoRa Modules).
- HELTEC V2, V3 , Wireless Stick, Wireless Stick Lite, HT-CT62, Wireless Tracker.
- ESP32 Wroom + SX1278 LoRa Module or Ebyte 400M30S (or 900M30S) 1W LoRa Module for a DIY Versions.
- ESP32C3 + Ebyte 400M30S(or 900M30S) 1W LoRa Module for another DIY version.
- ESP32 + 4G/LTE A7670 Modem + SX1278 DIY Version. - ESP32 + 4G/LTE A7670 Modem + SX1278 DIY Version.
- Wemos Lolin32 Oled + SX1278 DIY Version. - Wemos Lolin32 Oled + SX1278 DIY Version.
<br />
### Buying links --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/Z.-------Supported-Boards-and-Buying-Links" target="_blank">here</a>.
____________________________________________________
# WIKI
### Installation Guide --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/01.-Installation-Guide" target="_blank">here</a>.
*(Wiki has all configuration explanation, supported boards list, adding BME/BMP Wx modules and more)*
____________________________________________________
## Timeline (Versions): ## Timeline (Versions):
- 2024.08.13 Web Authentication for WebUI. Thanks Mitja S57PNX.
- 2024.08.05 WIDE2-n added to WIDE1-n in Digirepeater Modes.
- 2024.06.27 External Voltage Divider Resistor configuration on WebUI. Thanks Tilen S54B.
- 2024.06.26 Personal Note information on WebUI for the Station. Thanks Tilen S54B.
- 2024.06.24 Callsign Validation fix. Thanks Helge SA7SKY.
- 2024.06.21 Tx packets coming from APRS-IS are (now) formatted into 3rd Party (as they should have been since the beginning). Thanks Lynn KJ4ERJ and Geoffrey F4FXL.
- 2024.06.18 All boards with 433 / 868 / 915 MHz versions.
- 2024.06.10 ESP32C3 + 1W LoRa Module (E22 400M30S) support added. - 2024.06.10 ESP32C3 + 1W LoRa Module (E22 400M30S) support added.
- 2024.06.09 Si7021 module added (with autodetected I2C Address) - 2024.06.09 Si7021 module added (with autodetected I2C Address)
- 2024.06.08 Callsign Validation for all Rx and Tx Station that iGate/Digi hears. - 2024.06.08 Callsign Validation for all Station that iGate/Digi hears.
- 2024.05.27 Battery Monitor for internal and External Voltages (to make board sleep and avoid low discharge of batterys) T-Beam boards now with Battery readings as well. - 2024.05.27 Battery Monitor for internal and External Voltages (to make board sleep and avoid low discharge of batterys) T-Beam boards now with Battery readings as well.
- 2024.05.23 Forced Reboot Mode added. - 2024.05.23 Forced Reboot Mode added.
- 2024.05.22 Experimental backup-Digirepeater-Mode when "only" iGate mode loses WiFi connection added. - 2024.05.22 Experimental backup-Digirepeater-Mode when "only" iGate mode loses WiFi connection added.
+9 -2
View File
@@ -52,7 +52,9 @@
"sendExternalVoltage": false, "sendExternalVoltage": false,
"externalVoltagePin": 34, "externalVoltagePin": 34,
"monitorExternalVoltage": false, "monitorExternalVoltage": false,
"externalSleepVoltage": 10.9 "externalSleepVoltage": 10.9,
"voltageDividerR1": 100.0,
"voltageDividerR2": 27.0
}, },
"bme": { "bme": {
"active": false, "active": false,
@@ -73,6 +75,10 @@
"username": "", "username": "",
"password": "" "password": ""
}, },
"webadmin": {
"username": "admin",
"password": ""
},
"other": { "other": {
"rememberStationTime": 30, "rememberStationTime": 30,
"lowPowerMode": false, "lowPowerMode": false,
@@ -80,5 +86,6 @@
"backupDigiMode": false, "backupDigiMode": false,
"rebootMode": false, "rebootMode": false,
"rebootModeTime": 6 "rebootModeTime": 6
} },
"personalNote": ""
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

+194 -65
View File
@@ -6,6 +6,7 @@
<title>LoRa iGate & Digi software &minus; Ricardo Guzman CA2RXU</title> <title>LoRa iGate & Digi software &minus; Ricardo Guzman CA2RXU</title>
<link rel="stylesheet" href="/bootstrap.css" /> <link rel="stylesheet" href="/bootstrap.css" />
<link rel="stylesheet" href="/style.css" /> <link rel="stylesheet" href="/style.css" />
<link rel="icon" href="/favicon.png" type="image/x-icon">
</head> </head>
<body class="bg-body-tertiary"> <body class="bg-body-tertiary">
<input type="file" accept="text/json,.json" style="display: none" /> <input type="file" accept="text/json,.json" style="display: none" />
@@ -15,7 +16,7 @@
> >
<div class="container"> <div class="container">
<a class="navbar-brand" href="" <a class="navbar-brand" href=""
>CA2RXU's LoRa</a >CA2RXU's LoRa iGate</a
> >
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor01" aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor01" aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
@@ -107,10 +108,14 @@
Station Station
</h5> </h5>
<small <small
>Add your ham callsign and SSID. Optionally, >Add your Ham callsign and SSID.
you can leave a comment describing your <br>
station.</small <br>
> You can leave a comment describing your station.
<br>
<br>
In the bottom there is a field for personal note that can only be seen in WEB GUI.
</small>
</div> </div>
<div class="col-lg-9 col-sm-12"> <div class="col-lg-9 col-sm-12">
<div class="row"> <div class="row">
@@ -237,6 +242,20 @@
class="form-control" class="form-control"
/> />
</div> </div>
<div class="col-12 mt-3">
<label
for="personalNote"
class="form-label"
>Personal Note</label
>
<input
type="text"
name="personalNote"
id="personalNote"
class="form-control"
placeholder="A Couple of words."
/>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -474,8 +493,8 @@
for="beacon.sendViaAPRSIS" for="beacon.sendViaAPRSIS"
class="form-label" class="form-label"
>Send our beacon to >Send our beacon to
APRS-IS</label APRS-IS
> </label>
</div> </div>
</div> </div>
<div class="col-6"> <div class="col-6">
@@ -489,8 +508,8 @@
<label <label
for="beacon.sendViaRF" for="beacon.sendViaRF"
class="form-label" class="form-label"
>Send beacon via RF</label >Send beacon via RF
> </label>
</div> </div>
</div> </div>
<div class="col-6 d-grid gap-2"> <div class="col-6 d-grid gap-2">
@@ -502,8 +521,8 @@
<label <label
for="beacon.interval" for="beacon.interval"
class="form-label" class="form-label"
>Interval</label >Interval
> </label>
<div class="input-group"> <div class="input-group">
<input <input
type="number" type="number"
@@ -516,8 +535,8 @@
min="1" min="1"
/> />
<span class="input-group-text" <span class="input-group-text"
>minutes</span >minutes
> </span>
</div> </div>
</div> </div>
</div> </div>
@@ -561,6 +580,9 @@
<option value="2"> <option value="2">
WIDE1 (fill-in) Digi WIDE1 (fill-in) Digi
</option> </option>
<option value="3">
WIDE2 (+WIDE1) Digi
</option>
</select> </select>
</div> </div>
</div> </div>
@@ -625,8 +647,8 @@
<label <label
for="lora.txFreq" for="lora.txFreq"
class="form-label" class="form-label"
>Tx Frequency</label >Tx Frequency
> </label>
<div class="input-group"> <div class="input-group">
<input <input
type="text" type="text"
@@ -644,17 +666,17 @@
class="form-control" class="form-control"
required="" required=""
/> />
<span class="input-group-text" <span class="input-group-text">
>Hz</span Hz
> </span>
</div> </div>
</div> </div>
<div class="col-6"> <div class="col-6">
<label <label
for="lora.rxFreq" for="lora.rxFreq"
class="form-label" class="form-label">
>Rx Frequency</label Rx Frequency
> </label>
<div class="input-group"> <div class="input-group">
<input <input
type="text" type="text"
@@ -664,8 +686,8 @@
class="form-control" class="form-control"
/> />
<span class="input-group-text" <span class="input-group-text"
>Hz</span >Hz
> </span>
</div> </div>
</div> </div>
</div> </div>
@@ -674,8 +696,8 @@
<label <label
for="action.speed" for="action.speed"
class="form-label" class="form-label"
>Predefined speeds</label >Predefined speeds
> </label>
<select <select
class="form-select form-select" class="form-select form-select"
name="action.speed" name="action.speed"
@@ -710,8 +732,8 @@
<label <label
for="lora.signalBandwidth" for="lora.signalBandwidth"
class="form-label" class="form-label"
>Bandwidth</label >Bandwidth
> </label>
<div class="input-group"> <div class="input-group">
<select <select
class="form-select form-select" class="form-select form-select"
@@ -735,8 +757,8 @@
<label <label
for="lora.spreadingFactor" for="lora.spreadingFactor"
class="form-label" class="form-label"
>Spreading Factor</label >Spreading Factor
> </label>
<select <select
class="form-select form-select" class="form-select form-select"
name="lora.spreadingFactor" name="lora.spreadingFactor"
@@ -760,9 +782,9 @@
<div class="col-6"> <div class="col-6">
<label <label
for="lora.codingRate4" for="lora.codingRate4"
class="form-label" class="form-label">
>Coding Rate</label Coding Rate
> </label>
<select <select
class="form-select form-select" class="form-select form-select"
name="lora.codingRate4" name="lora.codingRate4"
@@ -779,9 +801,9 @@
<div class="col-6"> <div class="col-6">
<label <label
for="lora.power" for="lora.power"
class="form-label" class="form-label">
>Power</label Power
> </label>
<div class="input-group"> <div class="input-group">
<input <input
type="number" type="number"
@@ -925,7 +947,15 @@
</svg> </svg>
Battery Battery
</h5> </h5>
<small>Battery Monitor & Health</small> <small>
Battery Monitor & Health
<br>
<br>
Max Voltage on input pin is 3.3V.
<br>
<br>
Calculate voltage divider accordingly.
</small>
</div> </div>
<div class="col-9 mt-2"> <div class="col-9 mt-2">
<div class="row mt-2"> <div class="row mt-2">
@@ -943,19 +973,6 @@
>Send Internal Voltage</label >Send Internal Voltage</label
> >
</div> </div>
<div class="form-check form-switch">
<input
type="checkbox"
name="battery.sendExternalVoltage"
id="battery.sendExternalVoltage"
class="form-check-input"
/>
<label
for="battery.sendExternalVoltage"
class="form-label"
>Send External Voltage</label
>
</div>
<div class="form-check form-switch mt-3"> <div class="form-check form-switch mt-3">
<input <input
type="checkbox" type="checkbox"
@@ -991,21 +1008,20 @@
</div> </div>
</div> </div>
<div class="col-6"> <div class="col-6">
<div class="form-floating col-7"> <div class="form-check form-switch">
<input <input
type="text" type="checkbox"
name="battery.externalVoltagePin" name="battery.sendExternalVoltage"
id="battery.externalVoltagePin" id="battery.sendExternalVoltage"
value="34" class="form-check-input"
class="form-control"
/> />
<label <label
for="battery.externalVoltagePin" for="battery.sendExternalVoltage"
class="form-label" class="form-label"
>External Voltage Pin</label >Send External Voltage</label
> >
</div> </div>
<div class="form-check form-switch mt-4"> <div class="form-check form-switch mt-3">
<input <input
type="checkbox" type="checkbox"
name="battery.monitorExternalVoltage" name="battery.monitorExternalVoltage"
@@ -1038,6 +1054,52 @@
> >
</div> </div>
</div> </div>
<div class="form-floating col-7 mt-3">
<input
type="text"
name="battery.externalVoltagePin"
id="battery.externalVoltagePin"
value="34"
class="form-control"
/>
<label
for="battery.externalVoltagePin"
class="form-label"
>External Voltage Pin</label
>
</div>
<div class="col">
<label for="battery.voltageDividerR1" class="form-label">External Voltage divider R1</label>
<div class="input-group">
<input
type="number"
name="battery.voltageDividerR1"
id="battery.voltageDividerR1"
placeholder="100.0"
class="form-control"
step="0.1"
min="1"
max="1000"
/>
<span class="input-group-text">kOhm</span>
</div>
</div>
<div class="col">
<label for="battery.voltageDividerR2" class="form-label">External Voltage divider R2</label>
<div class="input-group">
<input
type="number"
name="battery.voltageDividerR2"
id="battery.voltageDividerR2"
placeholder="27.0"
class="form-control"
step="0.1"
min="1"
max="1000"
/>
<span class="input-group-text">kOhm</span>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -1061,7 +1123,7 @@
</svg> </svg>
Telemetry Telemetry
</h5> </h5>
<small>Define the telemetry</small> <small>Define Wx telemetry</small>
</div> </div>
<div class="col-9 mt-2"> <div class="col-9 mt-2">
<div class="row"> <div class="row">
@@ -1078,9 +1140,7 @@
class="form-label" class="form-label"
><b>Activate Wx Telemetry</b> ><b>Activate Wx Telemetry</b>
<small <small
>Requires a BME/BMP280 or >Requires a BME/BMP280, BME680 or Si7021 sensor installed</small
BME680 sensor
installed</small
></label ></label
> >
</div> </div>
@@ -1339,7 +1399,7 @@
type="number" type="number"
name="other.rebootModeTime" name="other.rebootModeTime"
id="other.rebootModeTime" id="other.rebootModeTime"
placeholder="0" placeholder="6"
class="form-control" class="form-control"
step="6" step="6"
min="6" min="6"
@@ -1481,6 +1541,75 @@
</div> </div>
<hr /> <hr />
<div class="row my-5 d-flex align-items-top">
<div class="col-lg-3 col-sm-12">
<h5>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
class="bi bi-cloud-upload-fill"
viewBox="0 0 16 16"
>
<path
fill-rule="evenodd"
d="M8 0a5.53 5.53 0 0 0-3.594 1.342c-.766.66-1.321 1.52-1.464 2.383C1.266 4.095 0 5.555 0 7.318 0 9.366 1.708 11 3.781 11H7.5V5.707L5.354 7.854a.5.5 0 1 1-.708-.708l3-3a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707V11h4.188C14.502 11 16 9.57 16 7.773c0-1.636-1.242-2.969-2.834-3.194C12.923 1.999 10.69 0 8 0m-.5 14.5V11h1v3.5a.5.5 0 0 1-1 0"
/>
</svg>
Admin
</h5>
<small
>Set your username and password to allow
access to the web interface.</small
>
</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>
</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>
</div>
</div>
<hr />
<div class="row my-5 d-flex align-items-top"> <div class="row my-5 d-flex align-items-top">
<div class="col-lg-3 col-sm-12"> <div class="col-lg-3 col-sm-12">
<h5> <h5>
@@ -1537,7 +1666,7 @@
<label <label
for="other.lowPowerMode" for="other.lowPowerMode"
class="form-label" class="form-label"
>Low power mode</label >Low power mode (only for HT-CT62)</label
> >
</div> </div>
</div> </div>
@@ -1702,4 +1831,4 @@
</body> </body>
<script src="/bootstrap.js"></script> <script src="/bootstrap.js"></script>
<script src="/script.js"></script> <script src="/script.js"></script>
</html> </html>
+51 -3
View File
@@ -79,7 +79,7 @@ function loadSettings(settings) {
document.getElementById("beacon.path").value = settings.beacon.path; document.getElementById("beacon.path").value = settings.beacon.path;
document.getElementById("beacon.symbol").value = settings.beacon.symbol; document.getElementById("beacon.symbol").value = settings.beacon.symbol;
document.getElementById("beacon.overlay").value = settings.beacon.overlay; document.getElementById("beacon.overlay").value = settings.beacon.overlay;
document.getElementById("personalNote").value = settings.personalNote;
document.getElementById("action.symbol").value = settings.beacon.overlay + settings.beacon.symbol; document.getElementById("action.symbol").value = settings.beacon.overlay + settings.beacon.symbol;
document.querySelector(".list-networks").innerHTML = ""; document.querySelector(".list-networks").innerHTML = "";
@@ -162,6 +162,8 @@ function loadSettings(settings) {
document.getElementById("battery.internalSleepVoltage").value = settings.battery.internalSleepVoltage.toFixed(1); document.getElementById("battery.internalSleepVoltage").value = settings.battery.internalSleepVoltage.toFixed(1);
document.getElementById("battery.sendExternalVoltage").checked = settings.battery.sendExternalVoltage; document.getElementById("battery.sendExternalVoltage").checked = settings.battery.sendExternalVoltage;
document.getElementById("battery.externalVoltagePin").value = settings.battery.externalVoltagePin; document.getElementById("battery.externalVoltagePin").value = settings.battery.externalVoltagePin;
document.getElementById("battery.voltageDividerR1").value = settings.battery.voltageDividerR1.toFixed(1);
document.getElementById("battery.voltageDividerR2").value = settings.battery.voltageDividerR2.toFixed(1);
document.getElementById("battery.monitorExternalVoltage").checked = settings.battery.monitorExternalVoltage; document.getElementById("battery.monitorExternalVoltage").checked = settings.battery.monitorExternalVoltage;
document.getElementById("battery.externalSleepVoltage").value = settings.battery.externalSleepVoltage.toFixed(1); document.getElementById("battery.externalSleepVoltage").value = settings.battery.externalSleepVoltage.toFixed(1);
@@ -199,6 +201,11 @@ function loadSettings(settings) {
document.getElementById("ota.username").value = settings.ota.username; document.getElementById("ota.username").value = settings.ota.username;
document.getElementById("ota.password").value = settings.ota.password; document.getElementById("ota.password").value = settings.ota.password;
// Webadmin
document.getElementById("webadmin.active").checked = settings.webadmin.active;
document.getElementById("webadmin.username").value = settings.webadmin.username;
document.getElementById("webadmin.password").value = settings.webadmin.password;
// Experimental // Experimental
document.getElementById("other.backupDigiMode").checked = settings.other.backupDigiMode; document.getElementById("other.backupDigiMode").checked = settings.other.backupDigiMode;
@@ -271,8 +278,23 @@ function toggleFields() {
'input[name="battery.externalVoltagePin"]' 'input[name="battery.externalVoltagePin"]'
); );
externalVoltagePinInput.disabled = externalVoltagePinInput.disabled = !sendExternalVoltageCheckbox.checked;
!sendExternalVoltageCheckbox.checked; voltageDividerR1.disabled = !sendExternalVoltageCheckbox.checked;
voltageDividerR2.disabled = !sendExternalVoltageCheckbox.checked;
const WebadminCheckbox = document.querySelector(
'input[name="webadmin.active"]'
);
const WebadminUsername = document.querySelector(
'input[name="webadmin.username"]'
);
const WebadminPassword = document.querySelector(
'input[name="webadmin.password"]'
);
WebadminUsername.disabled = !WebadminCheckbox.checked;
WebadminPassword.disabled = !WebadminCheckbox.checked;
} }
const sendExternalVoltageCheckbox = document.querySelector( const sendExternalVoltageCheckbox = document.querySelector(
@@ -282,8 +304,34 @@ const externalVoltagePinInput = document.querySelector(
'input[name="battery.externalVoltagePin"]' 'input[name="battery.externalVoltagePin"]'
); );
const voltageDividerR1 = document.querySelector(
'input[name="battery.voltageDividerR1"]'
);
const voltageDividerR2 = document.querySelector(
'input[name="battery.voltageDividerR2"]'
);
sendExternalVoltageCheckbox.addEventListener("change", function () { sendExternalVoltageCheckbox.addEventListener("change", function () {
externalVoltagePinInput.disabled = !this.checked; externalVoltagePinInput.disabled = !this.checked;
voltageDividerR1.disabled = !this.checked;
voltageDividerR2.disabled = !this.checked;
});
const WebadminCheckbox = document.querySelector(
'input[name="webadmin.active"]'
);
const WebadminUsername = document.querySelector(
'input[name="webadmin.username"]'
);
const WebadminPassword = document.querySelector(
'input[name="webadmin.password"]'
);
WebadminCheckbox.addEventListener("change", function () {
WebadminUsername.disabled = !this.checked;
WebadminPassword.disabled = !this.checked;
}); });
document.querySelector(".new button").addEventListener("click", function () { document.querySelector(".new button").addEventListener("click", function () {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

-39
View File
@@ -1,39 +0,0 @@
@echo off
echo Loading...
where /q python.exe
if %errorlevel% neq 0 (
echo "Python is not installed. Please install it and try again."
exit /b
)
where /q pip
if %errorlevel% neq 0 (
echo "pip is not installed. Please install it and try again."
exit /b
)
pip show pyserial >nul 2>&1
if %errorlevel% neq 0 (
echo "Installing pyserial..."
pip install pyserial
)
echo Your firmware will be upgraded without factory reset.
echo:
echo IF THIS IS YOUR FIRST FLASH ON THIS BOARD PLEASE USE install_with_factory_reset.bat INSTEAD!
echo:
echo Available COM ports:
python.exe -c "import serial.tools.list_ports; print('\n'.join([str(c) for c in serial.tools.list_ports.comports()]))"
echo:
set /p port="Enter COM port (for example COM5): "
python.exe ./bin/esptool/esptool.py --chip esp32 --port "%port%" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 firmware/bootloader.bin 0x8000 firmware/partitions.bin 0xe000 firmware/boot_app0.bin 0x10000 firmware/firmware.bin
pause
-15
View File
@@ -1,15 +0,0 @@
#!/bin/bash
echo "Your firmware will be upgraded without factory reset."
echo "IF THIS IS YOUR FIRST FLASH ON THIS BOARD PLEASE USE install_with_factory_reset.sh INSTEAD!"
read -p "Enter COM port (for example /dev/ttyS5): " port
PYTHON_CMD=python
if command -v python3 &> /dev/null
then
PYTHON_CMD=python3
fi
PYTHON_CMD ./bin/esptool/esptool.py --chip esp32 --port "$port" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 firmware/bootloader.bin 0x8000 firmware/partitions.bin 0xe000 firmware/boot_app0.bin 0x10000 firmware/firmware.bin
echo "Firmware flashed"
-44
View File
@@ -1,44 +0,0 @@
@echo off
echo Loading...
where /q python.exe
if %errorlevel% neq 0 (
echo "Python is not installed. Please install it and try again."
exit /b
)
where /q pip
if %errorlevel% neq 0 (
echo "pip is not installed. Please install it and try again."
exit /b
)
pip show pyserial >nul 2>&1
if %errorlevel% neq 0 (
echo "Installing pyserial..."
pip install pyserial
)
echo Your current configuration will be LOST!!!
echo Your current configuration will be LOST!!!
echo Your current configuration will be LOST!!!
echo:
echo If you already have this board flashed with our firmware please use install_upgrade.bat instead!
echo:
echo Available COM ports:
python.exe -c "import serial.tools.list_ports; print('\n'.join([str(c) for c in serial.tools.list_ports.comports()]))"
echo:
set /p port="Enter COM port (for example COM5): "
python.exe bin/esptool/esptool.py --chip esp32 --port "%port%" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 2686976 firmware/spiffs.bin
python.exe bin/esptool/esptool.py --chip esp32 --port "%port%" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 firmware/bootloader.bin 0x8000 firmware/partitions.bin 0xe000 firmware/boot_app0.bin 0x10000 firmware/firmware.bin
pause
-17
View File
@@ -1,17 +0,0 @@
#!/bin/bash
echo "Your firmware will be upgraded without factory reset."
echo "IF THIS IS YOUR FIRST FLASH ON THIS BOARD PLEASE USE install_with_factory_reset.sh INSTEAD!"
read -p "Enter COM port (for example /dev/ttyS5): " port
PYTHON_CMD=python
if command -v python3 &> /dev/null
then
PYTHON_CMD=python3
fi
$PYTHON_CMD ./bin/esptool/esptool.py --chip esp32 --port "$port" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 2686976 firmware/spiffs.bin
$PYTHON_CMD ./bin/esptool/esptool.py --chip esp32 --port "$port" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 firmware/bootloader.bin 0x8000 firmware/partitions.bin 0xe000 firmware/boot_app0.bin 0x10000 firmware/firmware.bin
echo "Firmware flashed"
+151 -20
View File
@@ -22,6 +22,7 @@ board_build.embed_files =
data_embed/script.js.gz data_embed/script.js.gz
data_embed/bootstrap.css.gz data_embed/bootstrap.css.gz
data_embed/bootstrap.js.gz data_embed/bootstrap.js.gz
data_embed/favicon.png.gz
extra_scripts = extra_scripts =
pre:tools/compress.py pre:tools/compress.py
debug_tool = esp-prog debug_tool = esp-prog
@@ -46,11 +47,25 @@ build_flags =
-Werror -Wall -Werror -Wall
-DTTGO_T_LORA32_V2_1 -DTTGO_T_LORA32_V2_1
-DHAS_SX1278 -DHAS_SX1278
-DHAS_ADC_CALIBRATION
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps = lib_deps =
${common.lib_deps} ${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9 adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10 adafruit/Adafruit SSD1306 @ 2.5.10
[env:ttgo-lora32-v21_915]
board = ttgo-lora32-v21
build_flags =
-Werror -Wall
-DTTGO_T_LORA32_V2_1_915
-DHAS_SX1276
-DHAS_ADC_CALIBRATION
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:heltec-lora32-v2] [env:heltec-lora32-v2]
board = ttgo-lora32-v21 board = ttgo-lora32-v21
@@ -101,18 +116,16 @@ build_flags =
lib_deps = lib_deps =
${common.lib_deps} ${common.lib_deps}
[env:heltec_ht-ct62] [env:heltec_wireless_stick_lite_v3_display]
board = heltec_wireless_stick_lite board = esp32-s3-devkitc-1
board_build.mcu = esp32c3 board_build.mcu = esp32s3
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DHELTEC_HTCT62 -DHELTEC_WSL_V3_DISPLAY
-DHAS_SX1262 -DHAS_SX1262
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps = lib_deps =
${common.lib_deps} ${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_DIY_LoRa] [env:ESP32_DIY_LoRa]
board = esp32dev board = esp32dev
@@ -126,18 +139,58 @@ lib_deps =
adafruit/Adafruit GFX Library @ 1.11.9 adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10 adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_DIY_LoRa_915]
board = esp32dev
build_flags =
-Werror -Wall
-DESP32_DIY_LoRa_915
-DHAS_SX1276
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_DIY_1W_LoRa] [env:ESP32_DIY_1W_LoRa]
board = esp32dev board = esp32dev
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DESP32_DIY_1W_LoRa -DESP32_DIY_1W_LoRa
-DHAS_SX1268 -DHAS_SX1268
-DHAS_1W_LORA
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps = lib_deps =
${common.lib_deps} ${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9 adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10 adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_DIY_1W_LoRa_915]
board = esp32dev
build_flags =
-Werror -Wall
-DESP32_DIY_1W_LoRa_915
-DHAS_SX1262
-DHAS_1W_LORA
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_DIY_1W_LoRa_Mesh_V1_2]
board = esp32dev
build_flags =
-Werror -Wall
-DESP32_DIY_1W_LoRa_Mesh_V1_2
-DHAS_SX1268
-DHAS_1W_LORA
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ttgo-t-beam-v1_2] [env:ttgo-t-beam-v1_2]
board = ttgo-t-beam board = ttgo-t-beam
build_flags = build_flags =
@@ -152,6 +205,20 @@ lib_deps =
adafruit/Adafruit SSD1306 @ 2.5.10 adafruit/Adafruit SSD1306 @ 2.5.10
lewisxhe/XPowersLib @ 0.2.4 lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_2_915]
board = ttgo-t-beam
build_flags =
-Werror -Wall
-DTTGO_T_Beam_V1_2_915
-DHAS_SX1276
-DHAS_AXP2101
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1] [env:ttgo-t-beam-v1]
board = ttgo-t-beam board = ttgo-t-beam
build_flags = build_flags =
@@ -166,6 +233,20 @@ lib_deps =
adafruit/Adafruit SSD1306 @ 2.5.10 adafruit/Adafruit SSD1306 @ 2.5.10
lewisxhe/XPowersLib @ 0.2.4 lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_915]
board = ttgo-t-beam
build_flags =
-Werror -Wall
-DTTGO_T_Beam_V1_0_915
-DHAS_SX1276
-DHAS_AXP192
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_SX1268] [env:ttgo-t-beam-v1_SX1268]
board = ttgo-t-beam board = ttgo-t-beam
build_flags = build_flags =
@@ -200,6 +281,22 @@ build_flags =
-Werror -Wall -Werror -Wall
-DESP32_DIY_LoRa_A7670 -DESP32_DIY_LoRa_A7670
-DHAS_SX1278 -DHAS_SX1278
-DHAS_A7670
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
vshymanskyy/TinyGSM @ 0.12.0
vshymanskyy/StreamDebugger @ 1.0.1
[env:ESP32_DIY_LoRa_A7670_915]
board = esp32dev
build_flags =
-Werror -Wall
-DESP32_DIY_LoRa_A7670_915
-DHAS_SX1276
-DHAS_A7670
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps = lib_deps =
${common.lib_deps} ${common.lib_deps}
@@ -245,12 +342,26 @@ lib_deps =
${common.lib_deps} ${common.lib_deps}
bodmer/TFT_eSPI @ 2.5.43 bodmer/TFT_eSPI @ 2.5.43
[env:heltec_ht-ct62]
board = heltec_wireless_stick_lite
board_build.mcu = esp32c3
build_flags =
-Werror -Wall
-DHELTEC_HTCT62
-DHAS_SX1262
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:OE5HWN_MeshCom] [env:OE5HWN_MeshCom]
board = esp32dev board = esp32dev
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DOE5HWN_MeshCom -DOE5HWN_MeshCom
-DHAS_SX1268 -DHAS_SX1268
-DHAS_1W_LORA
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps = lib_deps =
${common.lib_deps} ${common.lib_deps}
@@ -281,26 +392,46 @@ lib_deps =
adafruit/Adafruit GFX Library @ 1.11.9 adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10 adafruit/Adafruit SSD1306 @ 2.5.10
[env:ttgo-lora32-v21-915]
board = ttgo-lora32-v21
build_flags =
-Werror -Wall
-DTTGO_T_LORA32_V2_1_915
-DHAS_SX1276
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:esp32c3_DIY_1W_LoRa] [env:esp32c3_DIY_1W_LoRa]
extends = env:esp32
board = esp32-c3-devkitm-1 board = esp32-c3-devkitm-1
board_build.mcu = esp32c3 board_build.mcu = esp32c3
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DESP32C3_DIY_1W_LoRa -DESP32C3_DIY_1W_LoRa
-DHAS_SX1268 -DHAS_SX1268
-DHAS_1W_LORA
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:esp32c3_DIY_1W_LoRa_915]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
-Werror -Wall
-DESP32C3_DIY_1W_LoRa_915
-DHAS_SX1262
-DHAS_1W_LORA
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_C3_OctopusLab_LoRa]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
-Werror -Wall
-DESP32_C3_OctopusLab_LoRa
-DHAS_SX1268
-DRADIO_HAS_XTAL
-DARDUINO_USB_MODE=1 -DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_USB_CDC_ON_BOOT=1
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
+7 -2
View File
@@ -6,7 +6,7 @@
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
#if defined(ESP32_DIY_LoRa_A7670) #ifdef HAS_A7670
#define TINY_GSM_MODEM_SIM7600 //The AT instruction of A7670 is compatible with SIM7600 #define TINY_GSM_MODEM_SIM7600 //The AT instruction of A7670 is compatible with SIM7600
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb #define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define SerialAT Serial1 #define SerialAT Serial1
@@ -146,7 +146,12 @@
} }
void APRS_IS_connect() { void APRS_IS_connect() {
String loginInfo = "user " + Config.callsign + " pass " + String(Config.aprs_is.passcode) + " vers CA2RXU_LoRa_iGate 1.3 filter " + Config.aprs_is.filter; String loginInfo = "user ";
loginInfo += Config.callsign;
loginInfo += " pass ";
loginInfo += String(Config.aprs_is.passcode);
loginInfo += " vers CA2RXU_LoRa_iGate 1.3 filter ";
loginInfo += Config.aprs_is.filter;
Serial.println("-----> Connecting to APRS IS"); Serial.println("-----> Connecting to APRS IS");
while (!modemStartUp) { while (!modemStartUp) {
Serial.print("Opening Port... "); Serial.print("Opening Port... ");
+11 -9
View File
@@ -21,6 +21,7 @@ ________________________________________________________________________________
#include "aprs_is_utils.h" #include "aprs_is_utils.h"
#include "station_utils.h" #include "station_utils.h"
#include "boards_pinout.h" #include "boards_pinout.h"
#include "battery_utils.h"
#include "syslog_utils.h" #include "syslog_utils.h"
#include "query_utils.h" #include "query_utils.h"
#include "power_utils.h" #include "power_utils.h"
@@ -33,11 +34,11 @@ ________________________________________________________________________________
#include "tnc_utils.h" #include "tnc_utils.h"
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
#ifdef ESP32_DIY_LoRa_A7670 #ifdef HAS_A7670
#include "A7670_utils.h" #include "A7670_utils.h"
#endif #endif
String versionDate = "2024.06.15"; String versionDate = "2024.08.13";
Configuration Config; Configuration Config;
WiFiClient espClient; WiFiClient espClient;
@@ -60,6 +61,7 @@ String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seven
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
POWER_Utils::setup(); POWER_Utils::setup();
BATTERY_Utils::setup();
Utils::setupDisplay(); Utils::setupDisplay();
Config.check(); Config.check();
LoRa_Utils::setup(); LoRa_Utils::setup();
@@ -96,7 +98,7 @@ void setup() {
String comment = Config.beacon.comment; String comment = Config.beacon.comment;
if (Config.battery.sendInternalVoltage) comment += " Batt=" + String(BATTERY_Utils::checkInternalVoltage(),2) + "V"; if (Config.battery.sendInternalVoltage) comment += " Batt=" + String(BATTERY_Utils::checkInternalVoltage(),2) + "V";
if (Config.battery.sendExternalVoltage) comment += " Ext=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V"; if (Config.battery.sendExternalVoltage) comment += " Ext=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V";
STATION_Utils::addToOutputPacketBuffer(GPS_Utils::getiGateLoRaBeaconPacket() + comment); LoRa_Utils::sendNewPacket(GPS_Utils::getiGateLoRaBeaconPacket() + comment);
lastBeacon = time; lastBeacon = time;
} }
@@ -116,7 +118,7 @@ void setup() {
BME_Utils::setup(); BME_Utils::setup();
WEB_Utils::setup(); WEB_Utils::setup();
TNC_Utils::setup(); TNC_Utils::setup();
#ifdef ESP32_DIY_LoRa_A7670 #ifdef HAS_A7670
A7670_Utils::setup(); A7670_Utils::setup();
#endif #endif
Utils::checkRebootMode(); Utils::checkRebootMode();
@@ -138,7 +140,7 @@ void loop() {
WIFI_Utils::checkWiFi(); // Always use WiFi, not related to IGate/Digi mode WIFI_Utils::checkWiFi(); // Always use WiFi, not related to IGate/Digi mode
#ifdef ESP32_DIY_LoRa_A7670 #ifdef HAS_A7670
if (Config.aprs_is.active && !modemLoggedToAPRSIS) A7670_Utils::APRS_IS_connect(); if (Config.aprs_is.active && !modemLoggedToAPRSIS) A7670_Utils::APRS_IS_connect();
#else #else
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) APRS_IS_Utils::connect(); if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) APRS_IS_Utils::connect();
@@ -161,8 +163,9 @@ void loop() {
APRS_IS_Utils::processLoRaPacket(packet); // Send received packet to APRSIS APRS_IS_Utils::processLoRaPacket(packet); // Send received packet to APRSIS
} }
if (Config.digi.mode == 2 || backUpDigiMode) { // If Digi enabled if (Config.digi.mode == 2 || Config.digi.mode == 3 || backUpDigiMode) { // If Digi enabled
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi STATION_Utils::clean25SegBuffer();
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi
} }
if (Config.tnc.enableServer) { // If TNC server enabled if (Config.tnc.enableServer) { // If TNC server enabled
@@ -176,9 +179,8 @@ void loop() {
if (Config.aprs_is.active) { // If APRSIS enabled if (Config.aprs_is.active) { // If APRSIS enabled
APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS
} }
STATION_Utils::processOutputPacketBuffer(); STATION_Utils::processOutputPacketBuffer();
STATION_Utils::clean25SegBuffer();
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0); show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
Utils::checkRebootTime(); Utils::checkRebootTime();
+180 -153
View File
@@ -24,7 +24,7 @@ extern bool backUpDigiMode;
uint32_t lastRxTime = millis(); uint32_t lastRxTime = millis();
#ifdef ESP32_DIY_LoRa_A7670 #ifdef HAS_A7670
extern bool stationBeacon; extern bool stationBeacon;
#endif #endif
@@ -36,9 +36,8 @@ namespace APRS_IS_Utils {
} }
void connect() { void connect() {
uint8_t count = 0;
String aprsauth;
Serial.print("Connecting to APRS-IS ... "); Serial.print("Connecting to APRS-IS ... ");
uint8_t count = 0;
while (!espClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) { while (!espClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) {
Serial.println("Didn't connect with server..."); Serial.println("Didn't connect with server...");
delay(1000); delay(1000);
@@ -54,11 +53,15 @@ namespace APRS_IS_Utils {
} }
else { else {
Serial.println("Connected!\n(Server: " + String(Config.aprs_is.server) + " / Port: " + String(Config.aprs_is.port) + ")"); Serial.println("Connected!\n(Server: " + String(Config.aprs_is.server) + " / Port: " + String(Config.aprs_is.port) + ")");
// String filter = "t/m/" + Config.callsign + "/" + (String)Config.aprs_is.reportingDistance; // String filter = "t/m/" + Config.callsign + "/" + (String)Config.aprs_is.reportingDistance;
aprsauth = "user " + Config.callsign + " pass " + Config.aprs_is.passcode + " vers CA2RXU_LoRa_iGate 1.3 filter " + Config.aprs_is.filter; String aprsAuth = "user ";
upload(aprsauth); aprsAuth += Config.callsign;
aprsAuth += " pass ";
aprsAuth += Config.aprs_is.passcode;
aprsAuth += " vers CA2RXU_LoRa_iGate 1.4 filter ";
aprsAuth += Config.aprs_is.filter;
upload(aprsAuth);
delay(200); delay(200);
} }
} }
@@ -82,7 +85,7 @@ namespace APRS_IS_Utils {
if (!Config.aprs_is.active) { if (!Config.aprs_is.active) {
aprsisState = "OFF"; aprsisState = "OFF";
} else { } else {
#ifdef ESP32_DIY_LoRa_A7670 #ifdef HAS_A7670
if (modemLoggedToAPRSIS) { if (modemLoggedToAPRSIS) {
aprsisState = "OK"; aprsisState = "OK";
} else { } else {
@@ -106,24 +109,123 @@ namespace APRS_IS_Utils {
secondLine += aprsisState; secondLine += aprsisState;
} }
String buildPacketToUpload(const String& packet) { String checkForStartingBytes(const String& packet) {
String payload = packet.substring(packet.indexOf(":")); if (packet.indexOf("\x3c\xff\x01") != -1) {
if (payload.indexOf("\x3c\xff\x01") != -1) { return packet.substring(0, packet.indexOf("\x3c\xff\x01"));
payload = payload.substring(0, payload.indexOf("\x3c\xff\x01"));
}
if (!(Config.aprs_is.active && Config.digi.mode == 0)) { // Check if NOT only IGate
return packet.substring(3, packet.indexOf(":")) + ",qAR," + Config.callsign + payload;
} else { } else {
return packet.substring(3, packet.indexOf(":")) + ",qAO," + Config.callsign + payload; return packet;
}
}
String buildPacketToUpload(const String& packet) {
String buildedPacket = packet.substring(3, packet.indexOf(":"));
if (!(Config.aprs_is.active && Config.digi.mode == 0)) { // Check if NOT only IGate
buildedPacket += ",qAR,";
} else {
buildedPacket += ",qAO,";
}
buildedPacket += Config.callsign;
buildedPacket += checkForStartingBytes(packet.substring(packet.indexOf(":")));
return buildedPacket;
}
bool processReceivedLoRaMessage(const String& sender, const String& packet, bool thirdParty) {
String receivedMessage;
if (packet.indexOf("{") > 0) { // ack?
String ackMessage = "ack";
ackMessage.concat(packet.substring(packet.indexOf("{") + 1));
ackMessage.trim();
//Serial.println(ackMessage);
String addToBuffer = Config.callsign;
addToBuffer += ">APLRG1,RFONLY";
if (Config.beacon.path != "") {
addToBuffer += ",";
addToBuffer += Config.beacon.path;
}
addToBuffer += "::";
String processedSender = sender;
for (int i = sender.length(); i < 9; i++) {
processedSender += ' ';
}
addToBuffer += processedSender;
addToBuffer += ":";
addToBuffer += ackMessage;
STATION_Utils::addToOutputPacketBuffer(addToBuffer);
receivedMessage = packet.substring(packet.indexOf(":") + 1, packet.indexOf("{"));
} else {
receivedMessage = packet.substring(packet.indexOf(":") + 1);
}
if (receivedMessage.indexOf("?") == 0) {
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
display_toggle(true);
}
STATION_Utils::addToOutputPacketBuffer(QUERY_Utils::process(receivedMessage, sender, false, thirdParty));
lastScreenOn = millis();
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, "Callsign = " + sender, "TYPE --> QUERY", 0);
return true;
}
else {
return false;
}
}
void processLoRaPacket(const String& packet) {
if (espClient.connected() || modemLoggedToAPRSIS) {
if (packet != "") {
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) {
int firstColonIndex = packet.indexOf(":");
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) {
const String& Sender = packet.substring(3, packet.indexOf(">"));
if (Sender != Config.callsign && Utils::checkValidCallsign(Sender)) {
STATION_Utils::updateLastHeard(Sender);
Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
bool queryMessage = false;
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false);
}
if (!queryMessage) {
const String& aprsPacket = buildPacketToUpload(packet);
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
display_toggle(true);
}
lastScreenOn = millis();
#ifdef HAS_A7670
stationBeacon = true;
A7670_Utils::uploadToAPRSIS(aprsPacket);
stationBeacon = false;
#else
upload(aprsPacket);
#endif
Utils::println("---> Uploaded to APRS-IS");
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
}
}
}
}
}
} }
} }
String buildPacketToTx(const String& aprsisPacket, uint8_t packetType) { String buildPacketToTx(const String& aprsisPacket, uint8_t packetType) {
String packet = aprsisPacket; String packet = aprsisPacket;
packet.trim(); packet.trim();
String outputPacket = packet.substring(0, packet.indexOf(",")); String outputPacket = Config.callsign;
outputPacket.concat(",TCPIP,WIDE1-1,"); outputPacket += ">APLRG1";
if (Config.beacon.path != "") {
outputPacket += ",";
outputPacket += Config.beacon.path;
}
outputPacket += ":}";
outputPacket += packet.substring(0, packet.indexOf(",")); // Callsign>Tocall
outputPacket.concat(",TCPIP,");
outputPacket.concat(Config.callsign); outputPacket.concat(Config.callsign);
outputPacket.concat("*");
switch (packetType) { switch (packetType) {
case 0: // gps case 0: // gps
if (packet.indexOf(":=") > 0) { if (packet.indexOf(":=") > 0) {
@@ -155,148 +257,73 @@ namespace APRS_IS_Utils {
return outputPacket; return outputPacket;
} }
bool processReceivedLoRaMessage(const String& sender, const String& packet) {
String receivedMessage;
if (packet.indexOf("{") > 0) { // ack?
String ackMessage = "ack";
ackMessage.concat(packet.substring(packet.indexOf("{") + 1));
ackMessage.trim();
//Serial.println(ackMessage);
String processedSender = sender;
for (int i = sender.length(); i < 9; i++) {
processedSender += ' ';
}
if (Config.beacon.path == "") {
STATION_Utils::addToOutputPacketBuffer(Config.callsign + ">APLRG1,RFONLY::" + processedSender + ":" + ackMessage);
} else {
STATION_Utils::addToOutputPacketBuffer(Config.callsign + ">APLRG1,RFONLY," + Config.beacon.path + "::" + processedSender + ":" + ackMessage);
}
receivedMessage = packet.substring(packet.indexOf(":") + 1, packet.indexOf("{"));
} else {
receivedMessage = packet.substring(packet.indexOf(":") + 1);
}
if (receivedMessage.indexOf("?") == 0) {
delay(2000);
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
display_toggle(true);
}
STATION_Utils::addToOutputPacketBuffer(QUERY_Utils::process(receivedMessage, sender, 0)); // LoRa
lastScreenOn = millis();
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, "Callsign = " + sender, "TYPE --> QUERY", 0);
return true;
}
else {
return false;
}
}
void processLoRaPacket(const String& packet) {
if (espClient.connected() || modemLoggedToAPRSIS) {
bool queryMessage = false;
String aprsPacket, Sender, AddresseeAndMessage, Addressee;
if (packet != "") {
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("TCPIP") == -1) && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) {
Sender = packet.substring(3, packet.indexOf(">"));
if (Sender != Config.callsign && Utils::checkValidCallsign(Sender)) {
if (STATION_Utils::check25SegBuffer(Sender, packet.substring(packet.indexOf(":")+2))) {
STATION_Utils::updateLastHeard(Sender);
Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS
AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
if (AddresseeAndMessage.indexOf("\x3c\xff\x01") != -1) {
AddresseeAndMessage = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf("\x3c\xff\x01"));
}
queryMessage = processReceivedLoRaMessage(Sender, AddresseeAndMessage);
}
if (!queryMessage) {
aprsPacket = buildPacketToUpload(packet);
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
display_toggle(true);
}
lastScreenOn = millis();
#ifdef ESP32_DIY_LoRa_A7670
stationBeacon = true;
A7670_Utils::uploadToAPRSIS(aprsPacket);
stationBeacon = false;
#else
upload(aprsPacket);
#endif
Utils::println("---> Uploaded to APRS-IS");
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
}
}
}
}
}
}
}
void processAPRSISPacket(const String& packet) { void processAPRSISPacket(const String& packet) {
String Sender, AddresseeAndMessage, Addressee, receivedMessage;
if (!packet.startsWith("#")) { if (!packet.startsWith("#")) {
if (Config.aprs_is.messagesToRF && packet.indexOf("::") > 0) { if (Config.aprs_is.messagesToRF && packet.indexOf("::") > 0) {
Sender = packet.substring(0, packet.indexOf(">")); String Sender = packet.substring(0, packet.indexOf(">"));
if (Utils::checkValidCallsign(Sender)) { const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2); String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":")); Addressee.trim();
Addressee.trim(); if (Addressee == Config.callsign) { // its for me!
if (Addressee == Config.callsign) { // its for me! String receivedMessage;
if (AddresseeAndMessage.indexOf("{") > 0) { // ack? if (AddresseeAndMessage.indexOf("{") > 0) { // ack?
String ackMessage = "ack" + AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{") + 1); String ackMessage = "ack";
ackMessage.trim(); ackMessage += AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{") + 1);
delay(4000); ackMessage.trim();
for (int i = Sender.length(); i < 9; i++) { delay(4000);
Sender += ' '; for (int i = Sender.length(); i < 9; i++) {
} Sender += ' ';
String ackPacket = Config.callsign + ">APLRG1,TCPIP,qAC::" + Sender + ":" + ackMessage;
#ifdef ESP32_DIY_LoRa_A7670
A7670_Utils::uploadToAPRSIS(ackPacket);
#else
upload(ackPacket);
#endif
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{"));
} else {
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1);
}
if (receivedMessage.indexOf("?") == 0) {
Utils::println("Received Query APRS-IS : " + packet);
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, 1); // APRSIS
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
display_toggle(true);
}
lastScreenOn = millis();
delay(500);
#ifdef ESP32_DIY_LoRa_A7670
A7670_Utils::uploadToAPRSIS(queryAnswer);
#else
upload(queryAnswer);
#endif
SYSLOG_Utils::log(2, queryAnswer, 0, 0.0, 0); // APRSIS TX
fifthLine = "APRS-IS ----> APRS-IS";
sixthLine = Config.callsign;
for (int j = sixthLine.length();j < 9;j++) {
sixthLine += " ";
}
sixthLine += "> ";
sixthLine += Sender;
seventhLine = "QUERY = ";
seventhLine += receivedMessage;
} }
String ackPacket = Config.callsign;
ackPacket += ">APLRG1,TCPIP,qAC::";
ackPacket += Sender;
ackPacket += ":";
ackPacket += ackMessage;
#ifdef HAS_A7670
A7670_Utils::uploadToAPRSIS(ackPacket);
#else
upload(ackPacket);
#endif
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{"));
} else { } else {
Utils::print("Received Message from APRS-IS : " + packet); receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1);
if (STATION_Utils::wasHeard(Addressee) && Utils::checkValidCallsign(Addressee)) { }
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1)); if (receivedMessage.indexOf("?") == 0) {
display_toggle(true); Utils::println("Received Query APRS-IS : " + packet);
lastScreenOn = millis(); String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
Utils::typeOfPacket(packet, 1); // APRS-LoRa //Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
} if (!Config.display.alwaysOn && Config.display.timeout != 0) {
display_toggle(true);
}
lastScreenOn = millis();
delay(500);
#ifdef HAS_A7670
A7670_Utils::uploadToAPRSIS(queryAnswer);
#else
upload(queryAnswer);
#endif
SYSLOG_Utils::log(2, queryAnswer, 0, 0.0, 0); // APRSIS TX
fifthLine = "APRS-IS ----> APRS-IS";
sixthLine = Config.callsign;
for (int j = sixthLine.length();j < 9;j++) {
sixthLine += " ";
}
sixthLine += "> ";
sixthLine += Sender;
seventhLine = "QUERY = ";
seventhLine += receivedMessage;
}
} else {
Utils::print("Received Message from APRS-IS : " + packet);
if (STATION_Utils::wasHeard(Addressee)) {
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1));
display_toggle(true);
lastScreenOn = millis();
Utils::typeOfPacket(packet, 1); // APRS-LoRa
} }
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} }
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) { } else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
Utils::println("Received Object from APRS-IS : " + packet); Utils::println("Received Object from APRS-IS : " + packet);
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5)); STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5));
@@ -308,7 +335,7 @@ namespace APRS_IS_Utils {
} }
void listenAPRSIS() { void listenAPRSIS() {
#ifdef ESP32_DIY_LoRa_A7670 #ifdef HAS_A7670
A7670_Utils::listenAPRSIS(); A7670_Utils::listenAPRSIS();
#else #else
if (espClient.connected()) { if (espClient.connected()) {
+5 -2
View File
@@ -9,10 +9,13 @@ namespace APRS_IS_Utils {
void upload(const String& line); void upload(const String& line);
void connect(); void connect();
void checkStatus(); void checkStatus();
String checkForStartingBytes(const String& packet);
String buildPacketToUpload(const String& packet); String buildPacketToUpload(const String& packet);
String buildPacketToTx(const String& aprsisPacket, uint8_t packetType); bool processReceivedLoRaMessage(const String& sender, const String& packet, bool thirdParty);
bool processReceivedLoRaMessage(const String& sender, const String& packet);
void processLoRaPacket(const String& packet); void processLoRaPacket(const String& packet);
String buildPacketToTx(const String& aprsisPacket, uint8_t packetType);
void processAPRSISPacket(const String& packet); void processAPRSISPacket(const String& packet);
void listenAPRSIS(); void listenAPRSIS();
+128 -30
View File
@@ -5,19 +5,41 @@
#include "power_utils.h" #include "power_utils.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern uint32_t lastBatteryCheck; extern uint32_t lastBatteryCheck;
bool shouldSleepLowVoltage = false; bool shouldSleepLowVoltage = false;
float adcReadingTransformation = (3.3/4095); float adcReadingTransformation = (3.3/4095);
float voltageDividerCorrection = 0.288; float voltageDividerCorrection = 0.288;
float readingCorrection = 0.125;
float multiplyCorrection = 0.035;
// for External Voltage Measurment (MAX = 15Volts !!!) float voltageDividerTransformation = 0.0;
float R1 = 100.000; //in Kilo-Ohms
float R2 = 27.000; //in Kilo-Ohms
float readingCorrection = 0.125; #ifdef HAS_ADC_CALIBRATION
float multiplyCorrection = 0.035; #include <esp_adc_cal.h>
#if defined(TTGO_T_LORA32_V2_1) || defined(TTGO_T_LORA32_V2_1_915)
#define InternalBattery_ADC_Channel ADC1_CHANNEL_7 // t_lora32 pin35
#define ExternalVoltage_ADC_Channel ADC1_CHANNEL_6 // t_lora32 pin34
#endif
#if CONFIG_IDF_TARGET_ESP32
#define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_VREF
#elif CONFIG_IDF_TARGET_ESP32S2
#define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP
#elif CONFIG_IDF_TARGET_ESP32C3
#define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP
#elif CONFIG_IDF_TARGET_ESP32S3
#define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP_FIT
#endif
esp_adc_cal_characteristics_t adc_chars;
#endif
bool calibrationEnable = false;
namespace BATTERY_Utils { namespace BATTERY_Utils {
@@ -26,6 +48,46 @@ namespace BATTERY_Utils {
return (voltage - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; return (voltage - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
} }
void adcCalibration() {
#ifdef HAS_ADC_CALIBRATION
if (calibrationEnable) {
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(InternalBattery_ADC_Channel, ADC_ATTEN_DB_12);
adc1_config_channel_atten(ExternalVoltage_ADC_Channel, ADC_ATTEN_DB_12);
}
#endif
}
void adcCalibrationCheck() {
#ifdef HAS_ADC_CALIBRATION
esp_err_t ret;
ret = esp_adc_cal_check_efuse(ADC_EXAMPLE_CALI_SCHEME);
/*if (ret == ESP_ERR_NOT_SUPPORTED) {
Serial.println("Calibration scheme not supported, skip software calibration");
} else if (ret == ESP_ERR_INVALID_VERSION) {
Serial.println("eFuse not burnt, skip software calibration");
} else */
if (ret == ESP_OK) {
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_12, 1100, &adc_chars);
//Serial.printf("eFuse Vref:%u mV\n", adc_chars.vref);
calibrationEnable = true;
} /*else {
Serial.println("Invalid Calibration Arg");
}*/
#endif
}
void setup() {
if ((Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) && Config.battery.voltageDividerR2 != 0) voltageDividerTransformation = (Config.battery.voltageDividerR1 + Config.battery.voltageDividerR2) / Config.battery.voltageDividerR2;
#if defined(HAS_ADC_CALIBRATION)
if (Config.battery.sendInternalVoltage || Config.battery.monitorInternalVoltage || Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) {
adcCalibrationCheck();
adcCalibration();
}
#endif
}
float checkInternalVoltage() { float checkInternalVoltage() {
#if defined(HAS_AXP192) || defined(HAS_AXP2101) #if defined(HAS_AXP192) || defined(HAS_AXP2101)
if(POWER_Utils::isBatteryConnected()) { if(POWER_Utils::isBatteryConnected()) {
@@ -37,38 +99,59 @@ namespace BATTERY_Utils {
int sample; int sample;
int sampleSum = 0; int sampleSum = 0;
#ifdef ADC_CTRL #ifdef ADC_CTRL
#if defined(HELTEC_WSL_V3) || defined(HELTEC_WIRELESS_TRACKER) #if defined(HELTEC_WIRELESS_TRACKER)
digitalWrite(ADC_CTRL, HIGH); digitalWrite(ADC_CTRL, HIGH);
#endif #endif
#if defined(HELTEC_V3) || defined(HELTEC_V2) #if defined(HELTEC_V3) || defined(HELTEC_V2) || defined(HELTEC_WSL_V3)
digitalWrite(ADC_CTRL, LOW); digitalWrite(ADC_CTRL, LOW);
#endif #endif
#endif #endif
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
#ifdef BATTERY_PIN #if defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_LoRa_915) || defined(ESP32_DIY_1W_LoRa) || defined(ESP32_DIY_1W_LoRa_915)
sample = analogRead(BATTERY_PIN);
#endif
#if defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
sample = 0; sample = 0;
#endif #else
#ifdef HAS_ADC_CALIBRATION
if (calibrationEnable){
sample = adc1_get_raw(InternalBattery_ADC_Channel);
} else {
sample = analogRead(BATTERY_PIN);
}
#else
#ifdef BATTERY_PIN
sample = analogRead(BATTERY_PIN);
#else
sample = 0;
#endif
#endif
#endif
sampleSum += sample; sampleSum += sample;
delayMicroseconds(50); delayMicroseconds(50);
} }
#ifdef ADC_CTRL #ifdef ADC_CTRL
#if defined(HELTEC_WSL_V3) || defined(HELTEC_WIRELESS_TRACKER) #if defined(HELTEC_WIRELESS_TRACKER)
digitalWrite(ADC_CTRL, LOW); digitalWrite(ADC_CTRL, LOW);
#endif #endif
#if defined(HELTEC_V3) || defined(HELTEC_V2) #if defined(HELTEC_V3) || defined(HELTEC_V2) || defined(HELTEC_WSL_V3)
digitalWrite(ADC_CTRL, HIGH); digitalWrite(ADC_CTRL, HIGH);
#endif #endif
double inputDivider = (1.0 / (390.0 + 100.0)) * 100.0; // The voltage divider is a 390k + 100k resistor in series, 100k on the low side. double inputDivider = (1.0 / (390.0 + 100.0)) * 100.0; // The voltage divider is a 390k + 100k resistor in series, 100k on the low side.
return (((sampleSum/100) * adcReadingTransformation) / inputDivider) + 0.285; // Yes, this offset is excessive, but the ADC on the ESP32s3 is quite inaccurate and noisy. Adjust to own measurements. return (((sampleSum/100) * adcReadingTransformation) / inputDivider) + 0.285; // Yes, this offset is excessive, but the ADC on the ESP32s3 is quite inaccurate and noisy. Adjust to own measurements.
#else #else
return (2 * (sampleSum/100) * adcReadingTransformation) + voltageDividerCorrection; // raw voltage without mapping #ifdef HAS_ADC_CALIBRATION
if (calibrationEnable){
float voltage = esp_adc_cal_raw_to_voltage(sampleSum / 100, &adc_chars);
voltage *= 2; // for 100K/100K voltage divider
voltage /= 1000;
return voltage;
} else {
return (2 * (sampleSum/100) * adcReadingTransformation) + voltageDividerCorrection; // raw voltage without mapping
}
#else
return (2 * (sampleSum/100) * adcReadingTransformation) + voltageDividerCorrection; // raw voltage without mapping
#endif
#endif #endif
// return mapVoltage(voltage, 3.34, 4.71, 3.0, 4.2); // mapped voltage // return mapVoltage(voltage, 3.34, 4.71, 3.0, 4.2); // mapped voltage
#endif #endif
} }
@@ -77,25 +160,40 @@ namespace BATTERY_Utils {
int sample; int sample;
int sampleSum = 0; int sampleSum = 0;
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
sample = analogRead(Config.battery.externalVoltagePin); #ifdef HAS_ADC_CALIBRATION
if (calibrationEnable){
sample = adc1_get_raw(ExternalVoltage_ADC_Channel);
} else {
sample = analogRead(Config.battery.externalVoltagePin);
}
#else
sample = analogRead(Config.battery.externalVoltagePin);
#endif
sampleSum += sample; sampleSum += sample;
delayMicroseconds(50); delayMicroseconds(50);
} }
float voltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * ((R1+R2)/R2)) - multiplyCorrection; float extVoltage;
#ifdef HAS_ADC_CALIBRATION
if (calibrationEnable){
extVoltage = esp_adc_cal_raw_to_voltage(sampleSum / 100, &adc_chars) * voltageDividerTransformation; // in mV
extVoltage /= 1000;
} else {
extVoltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection;
}
#else
extVoltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection;
#endif
return voltage; // raw voltage without mapping return extVoltage; // raw voltage without mapping
// return mapVoltage(voltage, 5.05, 6.32, 4.5, 5.5); // mapped voltage // return mapVoltage(voltage, 5.05, 6.32, 4.5, 5.5); // mapped voltage
} }
void checkIfShouldSleep() { void checkIfShouldSleep() {
if (lastBatteryCheck == 0 || millis() - lastBatteryCheck >= 15 * 60 * 1000) { if (lastBatteryCheck == 0 || millis() - lastBatteryCheck >= 15 * 60 * 1000) {
lastBatteryCheck = millis(); lastBatteryCheck = millis();
if (checkInternalVoltage() < Config.lowVoltageCutOff) {
float voltage = checkInternalVoltage();
if (voltage < Config.lowVoltageCutOff) {
ESP.deepSleep(1800000000); // 30 min sleep (60s = 60e6) ESP.deepSleep(1800000000); // 30 min sleep (60s = 60e6)
} }
} }
+3
View File
@@ -6,6 +6,9 @@
namespace BATTERY_Utils { namespace BATTERY_Utils {
void adcCalibration();
void adcCalibrationCheck();
void setup();
float checkInternalVoltage(); float checkInternalVoltage();
float checkExternalVoltage(); float checkExternalVoltage();
void checkIfShouldSleep(); // ???? void checkIfShouldSleep(); // ????
+13 -13
View File
@@ -32,7 +32,7 @@ namespace BME_Utils {
void getWxModuleAddres() { void getWxModuleAddres() {
uint8_t err, addr; uint8_t err, addr;
for(addr = 1; addr < 0x7F; addr++) { for(addr = 1; addr < 0x7F; addr++) {
#ifdef HELTEC_V3 #if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
Wire1.beginTransmission(addr); Wire1.beginTransmission(addr);
err = Wire1.endTransmission(); err = Wire1.endTransmission();
#else #else
@@ -58,12 +58,12 @@ namespace BME_Utils {
if (wxModuleAddress != 0x00) { if (wxModuleAddress != 0x00) {
bool wxModuleFound = false; bool wxModuleFound = false;
if (wxModuleAddress == 0x76 || wxModuleAddress == 0x77) { if (wxModuleAddress == 0x76 || wxModuleAddress == 0x77) {
#ifdef HELTEC_V3 #if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
if (bme280.begin(wxModuleAddress, &Wire1)) { if (bme280.begin(wxModuleAddress, &Wire1)) {
Serial.println("BME280 sensor found"); Serial.println("BME280 sensor found");
wxModuleType = 1; wxModuleType = 1;
wxModuleFound = true; wxModuleFound = true;
} }
#else #else
if (bme280.begin(wxModuleAddress)) { if (bme280.begin(wxModuleAddress)) {
Serial.println("BME280 sensor found"); Serial.println("BME280 sensor found");
@@ -130,8 +130,7 @@ namespace BME_Utils {
} }
String generateTempString(const float bmeTemp) { String generateTempString(const float bmeTemp) {
String strTemp; String strTemp = String((int)bmeTemp);
strTemp = String((int)bmeTemp);
switch (strTemp.length()) { switch (strTemp.length()) {
case 1: case 1:
return "00" + strTemp; return "00" + strTemp;
@@ -145,8 +144,7 @@ namespace BME_Utils {
} }
String generateHumString(const float bmeHum) { String generateHumString(const float bmeHum) {
String strHum; String strHum = String((int)bmeHum);
strHum = String((int)bmeHum);
switch (strHum.length()) { switch (strHum.length()) {
case 1: case 1:
return "0" + strHum; return "0" + strHum;
@@ -183,7 +181,6 @@ namespace BME_Utils {
} }
String readDataSensor() { String readDataSensor() {
String wx, tempStr, humStr, presStr;
switch (wxModuleType) { switch (wxModuleType) {
case 1: // BME280 case 1: // BME280
bme280.takeForcedMeasurement(); bme280.takeForcedMeasurement();
@@ -216,20 +213,23 @@ namespace BME_Utils {
break; break;
} }
String wx;
if (isnan(newTemp) || isnan(newHum) || isnan(newPress)) { if (isnan(newTemp) || isnan(newHum) || isnan(newPress)) {
Serial.println("BME/BMP/Si7021 Module data failed"); Serial.println("BME/BMP/Si7021 Module data failed");
wx = ".../...g...t...r...p...P...h..b....."; wx = ".../...g...t...r...p...P...h..b.....";
fifthLine = ""; fifthLine = "";
return wx; return wx;
} else { } else {
tempStr = generateTempString(((newTemp + Config.bme.temperatureCorrection) * 1.8) + 32); String tempStr = generateTempString(((newTemp + Config.bme.temperatureCorrection) * 1.8) + 32);
String humStr;
if (wxModuleType == 1 || wxModuleType == 3 || wxModuleType == 4) { if (wxModuleType == 1 || wxModuleType == 3 || wxModuleType == 4) {
humStr = generateHumString(newHum); humStr = generateHumString(newHum);
} else if (wxModuleType == 2) { } else if (wxModuleType == 2) {
humStr = ".."; humStr = "..";
} }
String presStr;
if (wxModuleAddress == 4) { if (wxModuleAddress == 4) {
presStr = "....."; presStr = ".....";
} else { } else {
+51 -22
View File
@@ -9,7 +9,7 @@
// LORA MODULES // LORA MODULES
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(ESP32_DIY_LoRa) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA32_V2_1_915) #if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(ESP32_DIY_LoRa) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA32_V2_1_915) || defined(ESP32_DIY_LoRa_915) || defined(TTGO_T_Beam_V1_2_915) || defined(TTGO_T_Beam_V1_0_915)
#define RADIO_SCLK_PIN 5 // GPIO5 - SX1278 SCK #define RADIO_SCLK_PIN 5 // GPIO5 - SX1278 SCK
#define RADIO_MISO_PIN 19 // GPIO19 - SX1278 MISO #define RADIO_MISO_PIN 19 // GPIO19 - SX1278 MISO
#define RADIO_MOSI_PIN 27 // GPIO27 - SX1278 MOSI #define RADIO_MOSI_PIN 27 // GPIO27 - SX1278 MOSI
@@ -18,7 +18,7 @@
#define RADIO_BUSY_PIN 26 // GPIO26 - SX1278 IRQ ---->DIO0 #define RADIO_BUSY_PIN 26 // GPIO26 - SX1278 IRQ ---->DIO0
#endif #endif
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_WS) #if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY) || defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_WS)
#define RADIO_SCLK_PIN 9 // SX1262 SCK #define RADIO_SCLK_PIN 9 // SX1262 SCK
#define RADIO_MISO_PIN 11 // SX1262 MISO #define RADIO_MISO_PIN 11 // SX1262 MISO
#define RADIO_MOSI_PIN 10 // SX1262 MOSI #define RADIO_MOSI_PIN 10 // SX1262 MOSI
@@ -28,7 +28,7 @@
#define RADIO_BUSY_PIN 13 // SX1262 BUSY #define RADIO_BUSY_PIN 13 // SX1262 BUSY
#endif #endif
#ifdef ESP32_DIY_1W_LoRa // Ebyte E22 400M30S / SX1268 #if defined(ESP32_DIY_1W_LoRa) || defined(ESP32_DIY_1W_LoRa_915) // Ebyte E22 400M30S (SX1268) or E22 900M30S (SX1262)
#define RADIO_SCLK_PIN 18 #define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19 #define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23 #define RADIO_MOSI_PIN 23
@@ -40,6 +40,18 @@
#define RADIO_TXEN 25 #define RADIO_TXEN 25
#endif #endif
#if defined(ESP32_DIY_1W_LoRa_Mesh_V1_2) // https://github.com/NanoVHF/Meshtastic-DIY/tree/main/PCB/ESP-32-devkit_EBYTE-E22/Mesh-v1.02-2LCD-FreePins
#define RADIO_SCLK_PIN 5
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 27
#define RADIO_CS_PIN 18
#define RADIO_RST_PIN 23
#define RADIO_DIO1_PIN 33
#define RADIO_BUSY_PIN 32
#define RADIO_RXEN 14
#define RADIO_TXEN 13
#endif
#ifdef WEMOS_LOLIN32_OLED_DIY_LoRa #ifdef WEMOS_LOLIN32_OLED_DIY_LoRa
#define RADIO_SCLK_PIN 15 #define RADIO_SCLK_PIN 15
#define RADIO_MISO_PIN 13 #define RADIO_MISO_PIN 13
@@ -82,7 +94,7 @@
#define RADIO_BUSY_PIN 4 // SX1262 BUSY #define RADIO_BUSY_PIN 4 // SX1262 BUSY
#endif #endif
#ifdef ESP32_DIY_LoRa_A7670 #if defined(ESP32_DIY_LoRa_A7670) || defined(ESP32_DIY_LoRa_A7670_915)
#define RADIO_SCLK_PIN 18 #define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19 #define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23 #define RADIO_MOSI_PIN 23
@@ -106,10 +118,23 @@
#define OLED_SDA 21 #define OLED_SDA 21
#define OLED_SCL 22 #define OLED_SCL 22
#define OLED_RST 36 #define OLED_RST 36
#endif #endif
#if defined(ESP32C3_DIY_1W_LoRa) || defined(ESP32C3_DIY_1W_LoRa_915)
#define RADIO_SCLK_PIN 8
#define RADIO_MISO_PIN 9
#define RADIO_MOSI_PIN 10
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 4
#define RADIO_DIO1_PIN 2
#define RADIO_BUSY_PIN 3
#define RADIO_RXEN 6
#define RADIO_TXEN 7
#endif
// OLED // OLED
#if defined(TTGO_T_LORA32_V2_1) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa) || defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262) || defined(OE5HWN_MeshCom) || defined(ESP32_DIY_LoRa_A7670) || defined(TTGO_T_LORA32_V2_1_915) #if defined(TTGO_T_LORA32_V2_1) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa) || defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262) || defined(OE5HWN_MeshCom) || defined(ESP32_DIY_LoRa_A7670) || defined(TTGO_T_LORA32_V2_1_915) || defined(ESP32_DIY_LoRa_915) || defined(TTGO_T_Beam_V1_0_915) || defined(TTGO_T_Beam_V1_2_915) || defined(ESP32_DIY_LoRa_A7670_915) || defined(ESP32_DIY_1W_LoRa_915) || defined(ESP32_DIY_1W_LoRa_Mesh_V1_2)
#define OLED_SDA 21 #define OLED_SDA 21
#define OLED_SCL 22 #define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin) #define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
@@ -133,8 +158,8 @@
#define OLED_RST -1 #define OLED_RST -1
#endif #endif
#if !defined(HELTEC_HTCT62) && !defined(HELTEC_WSL_V3) && !defined(ESP32C3_DIY_1W_LoRa) #if !defined(HELTEC_HTCT62) && !defined(HELTEC_WSL_V3) && !defined(ESP32C3_DIY_1W_LoRa) && !defined(ESP32C3_DIY_1W_LoRa_915)
#define HAS_DISPLAY #define HAS_DISPLAY
#endif #endif
// Leds and other stuff // Leds and other stuff
@@ -143,26 +168,29 @@
#endif #endif
#if defined(TTGO_T_LORA32_V2_1) || defined(TTGO_T_LORA32_V2_1_915) #if defined(TTGO_T_LORA32_V2_1) || defined(TTGO_T_LORA32_V2_1_915)
#define INTERNAL_LED_PIN 25 // Green Led #define INTERNAL_LED_PIN 25 // Green Led
#define BATTERY_PIN 35 // es 35 el led y 1 bateria? #define BATTERY_PIN 35
#endif #endif
#if defined(HELTEC_V2) #if defined(HELTEC_V2)
#define INTERNAL_LED_PIN 25 #define INTERNAL_LED_PIN 25
#define BATTERY_PIN 37 #define BATTERY_PIN 37
#define ADC_CTRL 21 #define ADC_CTRL 21
#endif #endif
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WS) #if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY) || defined(HELTEC_WS)
#define INTERNAL_LED_PIN 35 #define INTERNAL_LED_PIN 35
#define BATTERY_PIN 1 #define BATTERY_PIN 1
#define VEXT_CTRL 36 #define VEXT_CTRL 36
#define ADC_CTRL 37 // Heltec WSL_V3 just like Heltec WT #define ADC_CTRL 37 // Heltec WSL_V3 just like Heltec WT
#define BOARD_I2C_SDA 41 #define BOARD_I2C_SDA 41
#define BOARD_I2C_SCL 42 #define BOARD_I2C_SCL 42
#ifdef HELTEC_WSL_V3_DISPLAY
#define OLED_RST -1
#endif
#endif #endif
#if defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa) #if defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_LoRa_915) || defined(ESP32_DIY_1W_LoRa) || defined(ESP32_DIY_1W_LoRa_915)
#define INTERNAL_LED_PIN 2 #define INTERNAL_LED_PIN 2
#endif #endif
#if defined(ESP32_DIY_LoRa_A7670) #if defined(ESP32_DIY_LoRa_A7670) || defined(ESP32_DIY_LoRa_A7670_915)
#define INTERNAL_LED_PIN 13 // 13 for V1.1 and 12 for V1.0 #define INTERNAL_LED_PIN 13 // 13 for V1.1 and 12 for V1.0
#define BATTERY_PIN 35 #define BATTERY_PIN 35
#endif #endif
@@ -176,7 +204,7 @@
#define BOARD_I2C_SCL 6 #define BOARD_I2C_SCL 6
#endif #endif
#ifdef ESP32_C3_DIY_LoRa #ifdef ESP32_C3_DIY_LoRa // just testing!
#define OLED_SDA 8 #define OLED_SDA 8
#define OLED_SCL 9 #define OLED_SCL 9
#define OLED_RST 10 #define OLED_RST 10
@@ -188,16 +216,17 @@
#define RADIO_IRQ_PIN 2 #define RADIO_IRQ_PIN 2
#endif #endif
#ifdef ESP32C3_DIY_1W_LoRa #if defined(ESP32_C3_OctopusLab_LoRa)
#define RADIO_SCLK_PIN 8 #define OLED_SDA 0
#define RADIO_MISO_PIN 9 #define OLED_SCL 1
#define RADIO_MOSI_PIN 10 #define OLED_RST -1
#define RADIO_SCLK_PIN 6
#define RADIO_MISO_PIN 4
#define RADIO_MOSI_PIN 7
#define RADIO_CS_PIN 5 #define RADIO_CS_PIN 5
#define RADIO_RST_PIN 4 #define RADIO_DIO1_PIN 3
#define RADIO_DIO1_PIN 2 #define RADIO_RST_PIN -1
#define RADIO_BUSY_PIN 3 #define RADIO_BUSY_PIN 8
#define RADIO_RXEN 6
#define RADIO_TXEN 7
#endif #endif
/* (Same pins for LILYGO LoRa32 and ESP32 Wroom Dev ) /* (Same pins for LILYGO LoRa32 and ESP32 Wroom Dev )
+27 -3
View File
@@ -73,6 +73,9 @@ void Configuration::writeFile() {
data["battery"]["externalVoltagePin"] = battery.externalVoltagePin; data["battery"]["externalVoltagePin"] = battery.externalVoltagePin;
data["battery"]["monitorExternalVoltage"] = battery.monitorExternalVoltage; data["battery"]["monitorExternalVoltage"] = battery.monitorExternalVoltage;
data["battery"]["externalSleepVoltage"] = battery.externalSleepVoltage; data["battery"]["externalSleepVoltage"] = battery.externalSleepVoltage;
data["battery"]["voltageDividerR1"] = battery.voltageDividerR1;
data["battery"]["voltageDividerR2"] = battery.voltageDividerR2;
data["bme"]["active"] = bme.active; data["bme"]["active"] = bme.active;
data["bme"]["heightCorrection"] = bme.heightCorrection; data["bme"]["heightCorrection"] = bme.heightCorrection;
@@ -94,10 +97,16 @@ void Configuration::writeFile() {
data["other"]["rememberStationTime"] = rememberStationTime; data["other"]["rememberStationTime"] = rememberStationTime;
data["other"]["backupDigiMode"] = backupDigiMode; data["other"]["backupDigiMode"] = backupDigiMode;
data["other"]["lowPowerMode"] = lowPowerMode; data["other"]["lowPowerMode"] = lowPowerMode;
data["other"]["lowVoltageCutOff"] = lowVoltageCutOff; data["other"]["lowVoltageCutOff"] = lowVoltageCutOff;
data["personalNote"] = personalNote;
data["webadmin"]["active"] = webadmin.active;
data["webadmin"]["username"] = webadmin.username;
data["webadmin"]["password"] = webadmin.password;
serializeJson(data, configFile); serializeJson(data, configFile);
@@ -142,6 +151,8 @@ bool Configuration::readFile() {
battery.externalVoltagePin = data["battery"]["externalVoltagePin"].as<int>(); battery.externalVoltagePin = data["battery"]["externalVoltagePin"].as<int>();
battery.monitorExternalVoltage = data["battery"]["monitorExternalVoltage"].as<bool>(); battery.monitorExternalVoltage = data["battery"]["monitorExternalVoltage"].as<bool>();
battery.externalSleepVoltage = data["battery"]["externalSleepVoltage"].as<float>(); battery.externalSleepVoltage = data["battery"]["externalSleepVoltage"].as<float>();
battery.voltageDividerR1 = data["battery"]["voltageDividerR1"].as<float>();
battery.voltageDividerR2 = data["battery"]["voltageDividerR2"].as<float>();
aprs_is.passcode = data["aprs_is"]["passcode"].as<String>(); aprs_is.passcode = data["aprs_is"]["passcode"].as<String>();
aprs_is.server = data["aprs_is"]["server"].as<String>(); aprs_is.server = data["aprs_is"]["server"].as<String>();
@@ -179,6 +190,12 @@ bool Configuration::readFile() {
rebootMode = data["other"]["rebootMode"].as<bool>(); rebootMode = data["other"]["rebootMode"].as<bool>();
rebootModeTime = data["other"]["rebootModeTime"].as<int>(); rebootModeTime = data["other"]["rebootModeTime"].as<int>();
personalNote = data["personalNote"].as<String>();
webadmin.active = data["webadmin"]["active"].as<bool>();
webadmin.username = data["webadmin"]["username"].as<String>();
webadmin.password = data["webadmin"]["password"].as<String>();
int stationMode = data["stationMode"].as<int>(); // deprecated but need to specify config version int stationMode = data["stationMode"].as<int>(); // deprecated but need to specify config version
if (stationMode == 0) { if (stationMode == 0) {
@@ -330,7 +347,6 @@ void Configuration::init() {
ota.username = ""; ota.username = "";
ota.password = ""; ota.password = "";
rememberStationTime = 30; rememberStationTime = 30;
battery.sendInternalVoltage = false; battery.sendInternalVoltage = false;
@@ -341,6 +357,8 @@ void Configuration::init() {
battery.externalVoltagePin = 34; battery.externalVoltagePin = 34;
battery.monitorExternalVoltage = false; battery.monitorExternalVoltage = false;
battery.externalSleepVoltage = 3.0; battery.externalSleepVoltage = 3.0;
battery.voltageDividerR1 = 100.0;
battery.voltageDividerR2 = 27.0;
lowPowerMode = false; lowPowerMode = false;
lowVoltageCutOff = 0; lowVoltageCutOff = 0;
@@ -350,6 +368,12 @@ void Configuration::init() {
rebootMode = false; rebootMode = false;
rebootModeTime = 0; rebootModeTime = 0;
personalNote = "";
webadmin.active = false;
webadmin.username = "admin";
webadmin.password = "";
Serial.println("All is Written!"); Serial.println("All is Written!");
} }
+11
View File
@@ -75,6 +75,8 @@ public:
int externalVoltagePin; int externalVoltagePin;
bool monitorExternalVoltage; bool monitorExternalVoltage;
float externalSleepVoltage; float externalSleepVoltage;
float voltageDividerR1;
float voltageDividerR2;
}; };
class BME { class BME {
@@ -104,6 +106,13 @@ public:
String password; String password;
}; };
class WEBADMIN {
public:
bool active;
String username;
String password;
};
class Configuration { class Configuration {
public: public:
bool reload; // ? bool reload; // ?
@@ -114,6 +123,7 @@ public:
bool backupDigiMode; bool backupDigiMode;
bool rebootMode; bool rebootMode;
int rebootModeTime; int rebootModeTime;
String personalNote;
std::vector<WiFi_AP> wifiAPs; std::vector<WiFi_AP> wifiAPs;
WiFi_Auto_AP wifiAutoAP; WiFi_Auto_AP wifiAutoAP;
BEACON beacon; BEACON beacon;
@@ -126,6 +136,7 @@ public:
SYSLOG syslog; SYSLOG syslog;
TNC tnc; TNC tnc;
OTA ota; OTA ota;
WEBADMIN webadmin;
void init(); void init();
void writeFile(); void writeFile();
+81 -39
View File
@@ -5,6 +5,7 @@
#include "query_utils.h" #include "query_utils.h"
#include "digi_utils.h" #include "digi_utils.h"
#include "wifi_utils.h" #include "wifi_utils.h"
#include "lora_utils.h"
#include "gps_utils.h" #include "gps_utils.h"
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
@@ -24,32 +25,55 @@ extern bool backUpDigiMode;
namespace DIGI_Utils { namespace DIGI_Utils {
String generateDigiRepeatedPacket(const String& packet){ String buildPacket(const String& path, const String& packet, bool thirdParty) {
String temp0, path; String packetToRepeat = packet.substring(0, packet.indexOf(",") + 1);
temp0 = packet.substring(packet.indexOf(">") + 1, packet.indexOf(":")); String tempPath = path;
if (temp0.indexOf(",") > 2) {
path = temp0.substring(temp0.indexOf(",") + 1, temp0.indexOf(":"));
if (path.indexOf("WIDE1-") >= 0) {
String hop = path.substring(path.indexOf("WIDE1-") + 6, path.indexOf("WIDE1-") + 7);
if (hop.toInt() >= 1 && hop.toInt() <= 7) {
if (hop.toInt() == 1) {
path.replace("WIDE1-1", Config.callsign + "*");
} else {
path.replace("WIDE1-" + hop, Config.callsign + "*,WIDE1-" + String(hop.toInt() - 1));
}
String repeatedPacket = packet.substring(0, packet.indexOf(">")); // sender if (path.indexOf("WIDE1-1") != -1 && (Config.digi.mode == 2 || Config.digi.mode == 3)) {
repeatedPacket += ">"; tempPath.replace("WIDE1-1", Config.callsign + "*");
repeatedPacket += temp0.substring(0, temp0.indexOf(",")); // tocall } else if (path.indexOf("WIDE2-") != -1 && Config.digi.mode == 3) {
repeatedPacket += ","; if (path.indexOf("*") != 1) {
repeatedPacket += path; tempPath.remove(path.indexOf("*"), 1);
}
if (path.indexOf("WIDE2-1") != -1) {
tempPath.replace("WIDE2-1", Config.callsign + "*");
} else if (path.indexOf("WIDE2-2") != -1) {
tempPath.replace("WIDE2-2", Config.callsign + "*,WIDE2-1");
} else {
return "";
}
}
packetToRepeat += tempPath;
if (thirdParty) {
packetToRepeat += APRS_IS_Utils::checkForStartingBytes(packet.substring(packet.indexOf(":}")));
} else {
packetToRepeat += APRS_IS_Utils::checkForStartingBytes(packet.substring(packet.indexOf(":")));
}
return packetToRepeat;
}
String payload = packet.substring(packet.indexOf(":")); String generateDigiRepeatedPacket(const String& packet, bool thirdParty){
if (payload.indexOf("\x3c\xff\x01") != -1) { String temp;
payload = payload.substring(0, payload.indexOf("\x3c\xff\x01")); if (thirdParty) { // only header is used
} const String& header = packet.substring(0, packet.indexOf(":}"));
repeatedPacket += payload; temp = header.substring(header.indexOf(">") + 1);
return repeatedPacket; } else {
temp = packet.substring(packet.indexOf(">") + 1, packet.indexOf(":"));
}
if (temp.indexOf(",") > 2) { // checks for path
const String& path = temp.substring(temp.indexOf(",") + 1); // after tocall
if ((Config.digi.mode == 2 || backUpDigiMode) && path.indexOf("WIDE1-1") != - 1) {
return buildPacket(path, packet, thirdParty);
} else if (Config.digi.mode == 3) {
int wide1Index = path.indexOf("WIDE1-1");
int wide2Index = path.indexOf("WIDE2-");
if (wide1Index != -1 && wide2Index != -1 && wide1Index < wide2Index) { // WIDE1-1 && WIDE2-n
return buildPacket(path, packet, thirdParty);
} else if (wide1Index != -1 && wide2Index == -1) { // only WIDE1-1
return buildPacket(path, packet, thirdParty);
} else if (wide1Index == -1 && wide2Index != -1) { // only WIDE2-n
return buildPacket(path, packet, thirdParty);
} else { } else {
return ""; return "";
} }
@@ -61,26 +85,44 @@ namespace DIGI_Utils {
} }
} }
void processLoRaPacket(const String& packet) { void processLoRaPacket(const String& packet) {
bool queryMessage = false;
String loraPacket, Sender, AddresseeAndMessage, Addressee;
if (packet != "") { if (packet != "") {
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1)) { if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1)) {
Sender = packet.substring(3, packet.indexOf(">")); bool thirdPartyPacket = false;
if (Sender != Config.callsign && Utils::checkValidCallsign(Sender)) { String temp, Sender;
if (STATION_Utils::check25SegBuffer(Sender, packet.substring(packet.indexOf(":") + 2))) { int firstColonIndex = packet.indexOf(":");
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] == '}' && packet.indexOf("TCPIP") > 0) { // 3rd Party
thirdPartyPacket = true;
temp = packet.substring(packet.indexOf(":}") + 2);
Sender = temp.substring(0, temp.indexOf(">"));
} else {
temp = packet.substring(3);
Sender = packet.substring(3, packet.indexOf(">"));
}
if (Sender != Config.callsign) { // Avoid listening to own packets
if (!thirdPartyPacket && !Utils::checkValidCallsign(Sender)) {
return;
}
if (STATION_Utils::check25SegBuffer(Sender, temp.substring(temp.indexOf(":") + 2)) || Config.lowPowerMode) {
STATION_Utils::updateLastHeard(Sender); STATION_Utils::updateLastHeard(Sender);
Utils::typeOfPacket(packet.substring(3), 2); // Digi Utils::typeOfPacket(temp, 2); // Digi
AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2); bool queryMessage = false;
Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":")); if (temp.indexOf("::") > 10) { // it's a message
Addressee.trim(); String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2);
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me! String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage); Addressee.trim();
if (Addressee == Config.callsign) { // it's a message for me!
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
}
} }
if (!queryMessage && packet.indexOf("WIDE1-") > 10 && (Config.digi.mode == 2 || backUpDigiMode)) { // If should repeat packet (WIDE1 Digi) if (!queryMessage) {
loraPacket = generateDigiRepeatedPacket(packet.substring(3)); String loraPacket = generateDigiRepeatedPacket(packet.substring(3), thirdPartyPacket);
if (loraPacket != "") { if (loraPacket != "") {
STATION_Utils::addToOutputPacketBuffer(loraPacket); if (Config.lowPowerMode) {
LoRa_Utils::sendNewPacket(loraPacket);
} else {
STATION_Utils::addToOutputPacketBuffer(loraPacket);
}
display_toggle(true); display_toggle(true);
lastScreenOn = millis(); lastScreenOn = millis();
} }
+2 -1
View File
@@ -6,7 +6,8 @@
namespace DIGI_Utils { namespace DIGI_Utils {
String generateDigiRepeatedPacket(const String& packet); String buildPacket(const String& path, const String& packet, bool thirdParty);
String generateDigiRepeatedPacket(const String& packet, bool thirdParty);
void processLoRaPacket(const String& packet); void processLoRaPacket(const String& packet);
} }
+12 -5
View File
@@ -11,9 +11,9 @@
TFT_eSPI tft = TFT_eSPI(); TFT_eSPI tft = TFT_eSPI();
#ifdef HELTEC_WIRELESS_TRACKER #ifdef HELTEC_WIRELESS_TRACKER
#define bigSizeFont 2 #define bigSizeFont 2.5
#define smallSizeFont 1 #define smallSizeFont 1.5
#define lineSpacing 9 #define lineSpacing 12
#endif #endif
#else #else
#include <Adafruit_GFX.h> #include <Adafruit_GFX.h>
@@ -21,7 +21,11 @@
#if defined(HELTEC_V3) #if defined(HELTEC_V3)
#define OLED_DISPLAY_HAS_RST_PIN #define OLED_DISPLAY_HAS_RST_PIN
#endif #endif
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST); #ifdef HELTEC_WSL_V3_DISPLAY
Adafruit_SSD1306 display(128, 64, &Wire1, OLED_RST);
#else
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);
#endif
#endif #endif
#endif #endif
@@ -55,7 +59,10 @@ void setup_display() {
delay(20); delay(20);
digitalWrite(OLED_RST, HIGH); digitalWrite(OLED_RST, HIGH);
#endif #endif
Wire.begin(OLED_SDA, OLED_SCL);
#ifndef HELTEC_WSL_V3_DISPLAY
Wire.begin(OLED_SDA, OLED_SCL);
#endif
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed")); Serial.println(F("SSD1306 allocation failed"));
+51 -29
View File
@@ -49,14 +49,20 @@ namespace GPS_Utils {
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
encodedData += helper_base91[i]; encodedData += helper_base91[i];
} }
encodedData += symbol + " x" + "\x47"; encodedData += symbol;
encodedData += " x";
encodedData += "\x47";
return encodedData; return encodedData;
} }
void generateBeacons() { void generateBeacons() {
if (Config.callsign.indexOf("NOCALL-10") != 0 && !Utils::checkValidCallsign(Config.callsign)) { if (Config.callsign.indexOf("NOCALL-10") != 0 && !Utils::checkValidCallsign(Config.callsign)) {
show_display("***** ERROR ******", "CALLSIGN = NOT VALID!", " Use SSID 0-15", " Or Valid Callsign", 0); show_display("***** ERROR ******", "CALLSIGN = NOT VALID!", "", "Only Rx Mode Active", 3000);
while (true) {} Config.loramodule.txActive = false;
Config.aprs_is.messagesToRF = false;
Config.aprs_is.objectsToRF = false;
Config.beacon.sendViaRF = false;
Config.digi.mode = 0;
} }
String beaconPacket = Config.callsign; String beaconPacket = Config.callsign;
beaconPacket += ">APLRG1"; beaconPacket += ">APLRG1";
@@ -80,10 +86,10 @@ namespace GPS_Utils {
} }
String decodeEncodedGPS(const String& packet) { String decodeEncodedGPS(const String& packet) {
String GPSPacket = packet.substring(packet.indexOf(":!")+3); const String& GPSPacket = packet.substring(packet.indexOf(":!")+3);
String encodedLatitude = GPSPacket.substring(0,4); const String& encodedLatitude = GPSPacket.substring(0,4);
String encodedLongtitude = GPSPacket.substring(4,8); const String& encodedLongtitude = GPSPacket.substring(4,8);
String comment = GPSPacket.substring(12); const String& comment = GPSPacket.substring(12);
int Y1 = int(encodedLatitude[0]); int Y1 = int(encodedLatitude[0]);
int Y2 = int(encodedLatitude[1]); int Y2 = int(encodedLatitude[1]);
@@ -96,12 +102,21 @@ namespace GPS_Utils {
int X3 = int(encodedLongtitude[2]); int X3 = int(encodedLongtitude[2]);
int X4 = int(encodedLongtitude[3]); int X4 = int(encodedLongtitude[3]);
float decodedLongitude = -180.0 + ((((X1-33) * pow(91,3)) + ((X2-33) * pow(91,2)) + ((X3-33) * 91) + X4-33) / 190463.0); float decodedLongitude = -180.0 + ((((X1-33) * pow(91,3)) + ((X2-33) * pow(91,2)) + ((X3-33) * 91) + X4-33) / 190463.0);
distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1); distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1);
String decodedGPS = String(decodedLatitude,5);
decodedGPS += "N / ";
decodedGPS += String(decodedLongitude,5);
decodedGPS += "E / ";
decodedGPS += distance;
decodedGPS += "km";
if (comment != "") { if (comment != "") {
return String(decodedLatitude,5) + "N / " + String(decodedLongitude,5) + "E / " + distance + "km / " + comment; decodedGPS += " / ";
} else { decodedGPS += comment;
return String(decodedLatitude,5) + "N / " + String(decodedLongitude,5) + "E / " + distance + "km";
} }
return decodedGPS;
} }
String getReceivedGPS(const String& packet) { String getReceivedGPS(const String& packet) {
@@ -111,36 +126,43 @@ namespace GPS_Utils {
} else if (packet.indexOf(":=") > 10) { } else if (packet.indexOf(":=") > 10) {
infoGPS = packet.substring(packet.indexOf(":=") + 2); infoGPS = packet.substring(packet.indexOf(":=") + 2);
} }
String Latitude = infoGPS.substring(0,8); const String& Latitude = infoGPS.substring(0,8);
String Longitude = infoGPS.substring(9,18); const String& Longitude = infoGPS.substring(9,18);
String comment = infoGPS.substring(19); const String& comment = infoGPS.substring(19);
float convertedLatitude, convertedLongitude;
String firstLatPart = Latitude.substring(0,2);
String secondLatPart = Latitude.substring(2,4);
String thirdLatPart = Latitude.substring(Latitude.indexOf(".") + 1, Latitude.indexOf(".") + 3);
String firstLngPart = Longitude.substring(0,3);
String secondLngPart = Longitude.substring(3,5);
String thirdLngPart = Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3);
float convertedLatitude, convertedLongitude;
const String& firstLatPart = Latitude.substring(0,2);
const String& secondLatPart = Latitude.substring(2,4);
const String& thirdLatPart = Latitude.substring(Latitude.indexOf(".") + 1, Latitude.indexOf(".") + 3);
convertedLatitude = firstLatPart.toFloat() + (secondLatPart.toFloat()/60) + (thirdLatPart.toFloat()/(60*100)); convertedLatitude = firstLatPart.toFloat() + (secondLatPart.toFloat()/60) + (thirdLatPart.toFloat()/(60*100));
const String& firstLngPart = Longitude.substring(0,3);
const String& secondLngPart = Longitude.substring(3,5);
const String& thirdLngPart = Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3);
convertedLongitude = firstLngPart.toFloat() + (secondLngPart.toFloat()/60) + (thirdLngPart.toFloat()/(60*100)); convertedLongitude = firstLngPart.toFloat() + (secondLngPart.toFloat()/60) + (thirdLngPart.toFloat()/(60*100));
String LatSign = String(Latitude[7]); if (String(Latitude[7]) == "S") {
String LngSign = String(Longitude[8]);
if (LatSign == "S") {
convertedLatitude = -convertedLatitude; convertedLatitude = -convertedLatitude;
} }
if (LngSign == "W") { if (String(Longitude[8]) == "W") {
convertedLongitude = -convertedLongitude; convertedLongitude = -convertedLongitude;
} }
distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1); distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1);
String decodedGPS = String(convertedLatitude,5);
decodedGPS += "N / ";
decodedGPS += String(convertedLongitude,5);
decodedGPS += "E / ";
decodedGPS += distance;
decodedGPS += "km";
if (comment != "") { if (comment != "") {
return String(convertedLatitude,5) + "N / " + String(convertedLongitude,5) + "E / " + distance + "km / " + comment; decodedGPS += " / ";
} else { decodedGPS += comment;
return String(convertedLatitude,5) + "N / " + String(convertedLongitude,5) + "E / " + distance + "km";
} }
} return decodedGPS;
}
String getDistanceAndComment(const String& packet) { String getDistanceAndComment(const String& packet) {
uint8_t encodedBytePosition = 0; uint8_t encodedBytePosition = 0;
+10 -7
View File
@@ -43,11 +43,14 @@ namespace LoRa_Utils {
void setup() { void setup() {
SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN);
float freq = (float)Config.loramodule.rxFreq / 1000000; float freq = (float)Config.loramodule.rxFreq / 1000000;
#if defined(RADIO_HAS_XTAL)
radio.XTAL = true;
#endif
int state = radio.begin(freq); int state = radio.begin(freq);
if (state == RADIOLIB_ERR_NONE) { if (state == RADIOLIB_ERR_NONE) {
Utils::println("Initializing LoRa Module"); Utils::println("Initializing LoRa Module");
} else { } else {
Utils::println("Starting LoRa failed!"); Utils::println("Starting LoRa failed! State: " + String(state));
while (true); while (true);
} }
#if defined(HAS_SX1262) || defined(HAS_SX1268) #if defined(HAS_SX1262) || defined(HAS_SX1268)
@@ -70,15 +73,15 @@ namespace LoRa_Utils {
radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN); radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN);
#endif #endif
#if defined(ESP32_DIY_1W_LoRa) || defined(OE5HWN_MeshCom) || defined(ESP32C3_DIY_1W_LoRa) #ifdef HAS_1W_LORA // Ebyte E22 400M30S (SX1268) / 900M30S (SX1262)
state = radio.setOutputPower(Config.loramodule.power); // max value 20dB for 400M30S as it has Low Noise Amp state = radio.setOutputPower(Config.loramodule.power); // max value 20dB for 1W modules as they have Low Noise Amp
radio.setCurrentLimit(140); // to be validated (100 , 120, 140)? radio.setCurrentLimit(140); // to be validated (100 , 120, 140)?
#endif #endif
#if defined(HAS_SX1278) || defined(HAS_SX1276) #if defined(HAS_SX1278) || defined(HAS_SX1276)
state = radio.setOutputPower(Config.loramodule.power); // max value 20dB for 400M30S as it has Low Noise Amp state = radio.setOutputPower(Config.loramodule.power); // max value 20dB for 400M30S as it has Low Noise Amp
radio.setCurrentLimit(100); // to be validated (80 , 100)? radio.setCurrentLimit(100); // to be validated (80 , 100)?
#endif #endif
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WS) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262) #if (defined(HAS_SX1268) || defined(HAS_SX1262)) && !defined(HAS_1W_LORA)
state = radio.setOutputPower(Config.loramodule.power + 2); // values available: 10, 17, 22 --> if 20 in tracker_conf.json it will be updated to 22. state = radio.setOutputPower(Config.loramodule.power + 2); // values available: 10, 17, 22 --> if 20 in tracker_conf.json it will be updated to 22.
radio.setCurrentLimit(140); radio.setCurrentLimit(140);
#endif #endif
@@ -90,7 +93,7 @@ namespace LoRa_Utils {
if (state == RADIOLIB_ERR_NONE) { if (state == RADIOLIB_ERR_NONE) {
Utils::println("init : LoRa Module ... done!"); Utils::println("init : LoRa Module ... done!");
} else { } else {
Utils::println("Starting LoRa failed!"); Utils::println("Starting LoRa failed! State: " + String(state));
while (true); while (true);
} }
} }
@@ -157,9 +160,9 @@ namespace LoRa_Utils {
String receivePacket() { String receivePacket() {
String packet = ""; String packet = "";
if (operationDone) { if (operationDone || Config.lowPowerMode) {
operationDone = false; operationDone = false;
if (transmitFlag) { if (transmitFlag && !Config.lowPowerMode) {
radio.startReceive(); radio.startReceive();
transmitFlag = false; transmitFlag = false;
} else { } else {
+1 -1
View File
@@ -164,7 +164,7 @@ namespace POWER_Utils {
Wire.begin(BOARD_I2C_SDA, BOARD_I2C_SCL); Wire.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
#endif #endif
#ifdef HELTEC_V3 #if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
Wire1.begin(BOARD_I2C_SDA, BOARD_I2C_SCL); Wire1.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
#endif #endif
+35 -24
View File
@@ -12,19 +12,21 @@ extern int freqError;
namespace QUERY_Utils { namespace QUERY_Utils {
String process(const String& query, const String& station, const uint8_t queryOrigin) { String process(const String& query, const String& station, bool queryFromAPRSIS, bool thirdParty) {
String answer; String answer;
if (query=="?APRS?" || query=="?aprs?" || query=="?Aprs?" || query=="H" || query=="h" || query=="HELP" || query=="Help" || query=="help" || query=="?") { String queryQuestion = query;
answer = "?APRSV ?APRSP ?APRSL ?APRSH ?WHERE callsign"; queryQuestion.toUpperCase();
} else if (query=="?APRSV" || query=="?aprsv" || query=="?Aprsv") { if (queryQuestion == "?APRS?" || queryQuestion == "H" || queryQuestion == "HELP" || queryQuestion=="?") {
answer = "CA2RXU_LoRa_iGate 1.3 v"; answer.concat("?APRSV ?APRSP ?APRSL ?APRSH ?WHERE callsign");
} else if (queryQuestion == "?APRSV") {
answer.concat("CA2RXU_LoRa_iGate 1.4 v");
answer.concat(versionDate); answer.concat(versionDate);
} else if (query=="?APRSP" || query=="?aprsp" || query=="?Aprsp") { } else if (queryQuestion == "?APRSP") {
answer = "iGate QTH: "; answer.concat("iGate QTH: ");
answer.concat(String(Config.beacon.latitude,2)); answer.concat(String(Config.beacon.latitude,3));
answer.concat(" "); answer.concat(" ");
answer.concat(String(Config.beacon.longitude,2)); answer.concat(String(Config.beacon.longitude,3));
} else if (query=="?APRSL" || query=="?aprsl" || query=="?Aprsl") { } else if (queryQuestion == "?APRSL") {
if (lastHeardStation.size() == 0) { if (lastHeardStation.size() == 0) {
char answerArray[50]; char answerArray[50];
snprintf(answerArray, sizeof(answerArray), "No Station Listened in the last %d min.", Config.rememberStationTime); snprintf(answerArray, sizeof(answerArray), "No Station Listened in the last %d min.", Config.rememberStationTime);
@@ -35,32 +37,41 @@ namespace QUERY_Utils {
} }
answer.trim(); answer.trim();
} }
} else if (query=="?APRSSR" || query=="?aprssr" || query=="?Aprssr") { } else if (queryQuestion == "?APRSSR") {
char signalData[35]; char signalData[35];
snprintf(signalData, sizeof(signalData), " %ddBm / %.2fdB / %dHz", rssi, snr, freqError); snprintf(signalData, sizeof(signalData), " %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
answer.concat(signalData); answer.concat(signalData);
} else if (query.indexOf("?APRSH") == 0 || query.indexOf("?aprsh") == 0 || query.indexOf("?Aprsh") == 0) { } else if (queryQuestion.indexOf("?APRSH") == 0) {
// sacar callsign despues de ?APRSH // sacar callsign despues de ?APRSH
Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?"); Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?");
answer = "?APRSH on development 73!"; answer.concat("?APRSH on development 73!");
} else if (query.indexOf("?WHERE") == 0) { } else if (queryQuestion.indexOf("?WHERE") == 0) {
// agregar callsign para completar donde esta X callsign --> posicion // agregar callsign para completar donde esta X callsign --> posicion
Serial.println("estaciones escuchadas directo (ultimos 30 min)"); Serial.println("estaciones escuchadas directo (ultimos 30 min)");
answer = "?WHERE on development 73!"; answer.concat("?WHERE on development 73!");
} }
String queryAnswer = Config.callsign;
queryAnswer += ">APLRG1";
if (queryFromAPRSIS) {
queryAnswer += ",TCPIP,qAC";
} else {
if (!thirdParty) queryAnswer += ",RFONLY";
if (Config.beacon.path != "") {
queryAnswer += ",";
queryAnswer += Config.beacon.path;
}
}
queryAnswer += "::";
String processedStation = station; String processedStation = station;
for (int i = station.length(); i < 9; i++) { for (int i = station.length(); i < 9; i++) {
processedStation += ' '; processedStation += ' ';
} }
if (queryOrigin == 1) { // from APRS-IS queryAnswer += processedStation;
return Config.callsign + ">APLRG1,TCPIP,qAC::" + processedStation + ":" + answer; queryAnswer += ":";
} else { // else == 0 , from LoRa queryAnswer += answer;
if (Config.beacon.path == "") { return queryAnswer;
return Config.callsign + ">APLRG1,RFONLY::" + processedStation + ":" + answer;
} else {
return Config.callsign + ">APLRG1,RFONLY," + Config.beacon.path + "::" + processedStation + ":" + answer;
}
}
} }
} }
+1 -1
View File
@@ -6,7 +6,7 @@
namespace QUERY_Utils { namespace QUERY_Utils {
String process(const String& query, const String& station, const uint8_t queryOrigin); String process(const String& query, const String& station, bool queryFromAPRSIS, bool thirdParty);
} }
+6 -6
View File
@@ -81,9 +81,9 @@ namespace STATION_Utils {
if (!packet25SegBuffer.empty()) { if (!packet25SegBuffer.empty()) {
bool shouldBeIgnored = false; bool shouldBeIgnored = false;
for (int i = 0; i < packet25SegBuffer.size(); i++) { for (int i = 0; i < packet25SegBuffer.size(); i++) {
String temp = packet25SegBuffer[i].substring(packet25SegBuffer[i].indexOf(",") + 1); const String& temp = packet25SegBuffer[i].substring(packet25SegBuffer[i].indexOf(",") + 1);
String bufferStation = temp.substring(0, temp.indexOf(",")); const String& bufferStation = temp.substring(0, temp.indexOf(","));
String bufferMessage = temp.substring(temp.indexOf(",") + 1); const String& bufferMessage = temp.substring(temp.indexOf(",") + 1);
if (bufferStation == station && bufferMessage == textMessage) { if (bufferStation == station && bufferMessage == textMessage) {
shouldBeIgnored = true; shouldBeIgnored = true;
} }
@@ -101,9 +101,9 @@ namespace STATION_Utils {
} }
void processOutputPacketBuffer() { void processOutputPacketBuffer() {
int timeToWait = 3 * 1000; // 3 segs between packet Tx and also Rx ??? int timeToWait = 3 * 1000; // 3 segs between packet Tx and also Rx ???
uint32_t lastRx = millis() - lastRxTime; uint32_t lastRx = millis() - lastRxTime;
uint32_t lastTx = millis() - lastTxTime; uint32_t lastTx = millis() - lastTxTime;
if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) { if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) {
LoRa_Utils::sendNewPacket(outputPacketBuffer[0]); LoRa_Utils::sendNewPacket(outputPacketBuffer[0]);
outputPacketBuffer.erase(outputPacketBuffer.begin()); outputPacketBuffer.erase(outputPacketBuffer.begin());
+44 -43
View File
@@ -104,9 +104,6 @@ namespace Utils {
void checkBeaconInterval() { void checkBeaconInterval() {
uint32_t lastTx = millis() - lastBeaconTx; uint32_t lastTx = millis() - lastBeaconTx;
String beaconPacket = iGateBeaconPacket;
String secondaryBeaconPacket = iGateLoRaBeaconPacket;
if (lastBeaconTx == 0 || lastTx >= Config.beacon.interval * 60 * 1000) { if (lastBeaconTx == 0 || lastTx >= Config.beacon.interval * 60 * 1000) {
beaconUpdate = true; beaconUpdate = true;
} }
@@ -121,6 +118,8 @@ namespace Utils {
activeStations(); activeStations();
String beaconPacket = iGateBeaconPacket;
String secondaryBeaconPacket = iGateLoRaBeaconPacket;
if (Config.bme.active && wxModuleType != 0) { if (Config.bme.active && wxModuleType != 0) {
String sensorData = BME_Utils::readDataSensor(); String sensorData = BME_Utils::readDataSensor();
beaconPacket += sensorData; beaconPacket += sensorData;
@@ -129,26 +128,26 @@ namespace Utils {
beaconPacket += ".../...g...t...r...p...P...h..b....."; beaconPacket += ".../...g...t...r...p...P...h..b.....";
secondaryBeaconPacket += ".../...g...t...r...p...P...h..b....."; secondaryBeaconPacket += ".../...g...t...r...p...P...h..b.....";
} }
beaconPacket += Config.beacon.comment; beaconPacket += Config.beacon.comment;
secondaryBeaconPacket += Config.beacon.comment; secondaryBeaconPacket += Config.beacon.comment;
#if defined(BATTERY_PIN) || defined(HAS_AXP192) || defined(HAS_AXP2101) #if defined(BATTERY_PIN) || defined(HAS_AXP192) || defined(HAS_AXP2101)
if (Config.battery.sendInternalVoltage || Config.battery.monitorInternalVoltage) { if (Config.battery.sendInternalVoltage || Config.battery.monitorInternalVoltage) {
float internalVoltage = BATTERY_Utils::checkInternalVoltage(); float internalVoltage = BATTERY_Utils::checkInternalVoltage();
String internalVoltageInfo = String(internalVoltage,2) + "V"; String internalVoltageInfo = String(internalVoltage,2) + "V";
if (Config.battery.sendInternalVoltage) { if (Config.battery.sendInternalVoltage) {
beaconPacket += " Batt="; beaconPacket += " Batt=";
beaconPacket += internalVoltageInfo; beaconPacket += internalVoltageInfo;
secondaryBeaconPacket += " Batt="; secondaryBeaconPacket += " Batt=";
secondaryBeaconPacket += internalVoltageInfo; secondaryBeaconPacket += internalVoltageInfo;
sixthLine = " (Batt="; sixthLine = " (Batt=";
sixthLine += internalVoltageInfo; sixthLine += internalVoltageInfo;
sixthLine += ")"; sixthLine += ")";
} }
if (Config.battery.monitorInternalVoltage && internalVoltage < Config.battery.internalSleepVoltage) { if (Config.battery.monitorInternalVoltage && internalVoltage < Config.battery.internalSleepVoltage) {
beaconPacket += " **IntBatWarning:SLEEP**"; beaconPacket += " **IntBatWarning:SLEEP**";
secondaryBeaconPacket += " **IntBatWarning:SLEEP**"; secondaryBeaconPacket += " **IntBatWarning:SLEEP**";
shouldSleepLowVoltage = true; shouldSleepLowVoltage = true;
} }
} }
#endif #endif
@@ -157,25 +156,25 @@ namespace Utils {
float externalVoltage = BATTERY_Utils::checkExternalVoltage(); float externalVoltage = BATTERY_Utils::checkExternalVoltage();
String externalVoltageInfo = String(externalVoltage,2) + "V"; String externalVoltageInfo = String(externalVoltage,2) + "V";
if (Config.battery.sendExternalVoltage) { if (Config.battery.sendExternalVoltage) {
beaconPacket += " Ext="; beaconPacket += " Ext=";
beaconPacket += externalVoltageInfo; beaconPacket += externalVoltageInfo;
secondaryBeaconPacket += " Ext="; secondaryBeaconPacket += " Ext=";
secondaryBeaconPacket += externalVoltageInfo; secondaryBeaconPacket += externalVoltageInfo;
sixthLine = " (Ext V="; sixthLine = " (Ext V=";
sixthLine += externalVoltageInfo; sixthLine += externalVoltageInfo;
sixthLine += ")"; sixthLine += ")";
} }
if (Config.battery.monitorExternalVoltage && externalVoltage < Config.battery.externalSleepVoltage) { if (Config.battery.monitorExternalVoltage && externalVoltage < Config.battery.externalSleepVoltage) {
beaconPacket += " **ExtBatWarning:SLEEP**"; beaconPacket += " **ExtBatWarning:SLEEP**";
secondaryBeaconPacket += " **ExtBatWarning:SLEEP**"; secondaryBeaconPacket += " **ExtBatWarning:SLEEP**";
shouldSleepLowVoltage = true; shouldSleepLowVoltage = true;
} }
} }
if (Config.aprs_is.active && Config.beacon.sendViaAPRSIS && !backUpDigiMode) { if (Config.aprs_is.active && Config.beacon.sendViaAPRSIS && !backUpDigiMode) {
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING IGATE BEACON", 0); show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING IGATE BEACON", 0);
seventhLine = " listening..."; seventhLine = " listening...";
#ifdef ESP32_DIY_LoRa_A7670 #ifdef HAS_A7670
A7670_Utils::uploadToAPRSIS(beaconPacket); A7670_Utils::uploadToAPRSIS(beaconPacket);
#else #else
APRS_IS_Utils::upload(beaconPacket); APRS_IS_Utils::upload(beaconPacket);
@@ -238,13 +237,14 @@ namespace Utils {
seventhLineHelper += String(snr); seventhLineHelper += String(snr);
seventhLineHelper += "dBm"; seventhLineHelper += "dBm";
if (packet.indexOf("::") >= 10) { int firstColonIndex = packet.indexOf(":");
if (packet[firstColonIndex + 1] == ':') {
sixthLine += "> MESSAGE"; sixthLine += "> MESSAGE";
seventhLine = seventhLineHelper; seventhLine = seventhLineHelper;
} else if (packet.indexOf(":>") >= 10) { } else if (packet[firstColonIndex + 1] == '>') {
sixthLine += "> NEW STATUS"; sixthLine += "> NEW STATUS";
seventhLine = seventhLineHelper; seventhLine = seventhLineHelper;
} else if (packet.indexOf(":!") >= 10 || packet.indexOf(":=") >= 10) { } else if (packet[firstColonIndex + 1] == '!' || packet[firstColonIndex + 1] == '=') {
sixthLine += "> GPS BEACON"; sixthLine += "> GPS BEACON";
if (!Config.syslog.active) { if (!Config.syslog.active) {
GPS_Utils::getDistanceAndComment(packet); // to be checked!!! GPS_Utils::getDistanceAndComment(packet); // to be checked!!!
@@ -263,15 +263,15 @@ namespace Utils {
seventhLine += "D:"; seventhLine += "D:";
seventhLine += distance; seventhLine += distance;
seventhLine += "km"; seventhLine += "km";
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) { } else if (packet[firstColonIndex + 1] == '`' || packet[firstColonIndex + 1] == '\'') {
sixthLine += "> TELEMETRY";
seventhLine = seventhLineHelper;
} else if (packet.indexOf(":`") >= 10) {
sixthLine += "> MIC-E"; sixthLine += "> MIC-E";
seventhLine = seventhLineHelper; seventhLine = seventhLineHelper;
} else if (packet.indexOf(":;") >= 10) { } else if (packet[firstColonIndex + 1] == ';') {
sixthLine += "> OBJECT"; sixthLine += "> OBJECT";
seventhLine = seventhLineHelper; seventhLine = seventhLineHelper;
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) {
sixthLine += "> TELEMETRY";
seventhLine = seventhLineHelper;
} else { } else {
sixthLine += "> ??????????"; sixthLine += "> ??????????";
seventhLine = seventhLineHelper; seventhLine = seventhLineHelper;
@@ -331,14 +331,12 @@ namespace Utils {
if (callsign == "WLNK-1") return true; if (callsign == "WLNK-1") return true;
String cleanCallsign; String cleanCallsign;
if (callsign.indexOf("-")) { // SSID Validation if (callsign.indexOf("-") > 0) { // SSID Validation
cleanCallsign = callsign.substring(0, callsign.indexOf("-")); cleanCallsign = callsign.substring(0, callsign.indexOf("-"));
String ssid = callsign.substring(callsign.indexOf("-") + 1); String ssid = callsign.substring(callsign.indexOf("-") + 1);
int ssidInt = ssid.toInt(); if (ssid.indexOf("-") != -1 || ssid.length() > 2) return false;
if (ssidInt == 0 && ssid != "0") { for (int i = 0; i < ssid.length(); i++) {
return false; if (!isAlphaNumeric(ssid[i])) return false;
} else if (ssidInt < 0 || ssidInt > 15) {
return false;
} }
} else { } else {
cleanCallsign = callsign; cleanCallsign = callsign;
@@ -350,22 +348,25 @@ namespace Utils {
cleanCallsign = " " + cleanCallsign; // A0AA --> _A0AA cleanCallsign = " " + cleanCallsign; // A0AA --> _A0AA
} }
if (!isDigit(cleanCallsign[2]) || !isAlpha(cleanCallsign[3])) return false; // __0A must be validated if (!isDigit(cleanCallsign[2]) || !isAlpha(cleanCallsign[3])) { // __0A__ must be validated
if (cleanCallsign[0] != 'R' && !isDigit(cleanCallsign[1]) && !isAlpha(cleanCallsign[2])) return false; // to accepto R0A___
}
bool isValid = false; bool isValid = false;
if ((isAlphaNumeric(cleanCallsign[0]) || cleanCallsign[0] == ' ') && isAlpha(cleanCallsign[1])) { if ((isAlphaNumeric(cleanCallsign[0]) || cleanCallsign[0] == ' ') && isAlpha(cleanCallsign[1])) {
isValid = true; // AA0A (+A+A) + _A0AA (+A) + 0A0A (+A+A) isValid = true; // AA0A (+A+A) + _A0AA (+A) + 0A0A (+A+A)
} else if (isAlpha(cleanCallsign[0]) && isDigit(cleanCallsign[1])) { } else if (isAlpha(cleanCallsign[0]) && isDigit(cleanCallsign[1])) {
isValid = true; // A00A (+A+A) isValid = true; // A00A (+A+A)
} else if (cleanCallsign[0] == 'R' && cleanCallsign.length() == 6 && isDigit(cleanCallsign[1]) && isAlpha(cleanCallsign[2]) && isAlpha(cleanCallsign[3]) && isAlpha(cleanCallsign[4])) {
isValid = true; // R0AA (+A+A)
} }
if (!isValid) return false; // also 00__ avoided if (!isValid) return false; // also 00__ avoided
if (cleanCallsign.length() > 4) { if (cleanCallsign.length() > 4) { // to validate ____AA
for (int i = 5; i <= cleanCallsign.length(); i++) { for (int i = 5; i <= cleanCallsign.length(); i++) {
if (!isAlpha(cleanCallsign[i - 1])) return false; if (!isAlpha(cleanCallsign[i - 1])) return false;
} }
} }
return true; return true;
} }
+36 -18
View File
@@ -29,6 +29,10 @@ extern const char web_bootstrap_js[] asm("_binary_data_embed_bootstrap_js_gz_sta
extern const char web_bootstrap_js_end[] asm("_binary_data_embed_bootstrap_js_gz_end"); extern const char web_bootstrap_js_end[] asm("_binary_data_embed_bootstrap_js_gz_end");
extern const size_t web_bootstrap_js_len = web_bootstrap_js_end - web_bootstrap_js; extern const size_t web_bootstrap_js_len = web_bootstrap_js_end - web_bootstrap_js;
// Declare external symbols for the embedded image data
extern const unsigned char favicon_data[] asm("_binary_data_embed_favicon_png_gz_start");
extern const unsigned char favicon_data_end[] asm("_binary_data_embed_favicon_png_gz_end");
extern const size_t favicon_data_len = favicon_data_end - favicon_data;
namespace WEB_Utils { namespace WEB_Utils {
@@ -45,12 +49,24 @@ namespace WEB_Utils {
} }
void handleHome(AsyncWebServerRequest *request) { void handleHome(AsyncWebServerRequest *request) {
if(Config.webadmin.active && !request->authenticate(Config.webadmin.username.c_str(), Config.webadmin.password.c_str()))
return request->requestAuthentication();
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", (const uint8_t*)web_index_html, web_index_html_len); AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", (const uint8_t*)web_index_html, web_index_html_len);
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
} }
void handleFavicon(AsyncWebServerRequest *request) {
AsyncWebServerResponse *response = request->beginResponse_P(200, "image/x-icon", (const uint8_t*)favicon_data, favicon_data_len);
response->addHeader("Content-Encoding", "gzip");
request->send(response);
}
void handleReadConfiguration(AsyncWebServerRequest *request) { void handleReadConfiguration(AsyncWebServerRequest *request) {
if(Config.webadmin.active && !request->authenticate(Config.webadmin.username.c_str(), Config.webadmin.password.c_str()))
return request->requestAuthentication();
File file = SPIFFS.open("/igate_conf.json"); File file = SPIFFS.open("/igate_conf.json");
String fileContent; String fileContent;
@@ -141,16 +157,17 @@ namespace WEB_Utils {
Config.battery.sendInternalVoltage = request->hasParam("battery.sendInternalVoltage", true); Config.battery.sendInternalVoltage = request->hasParam("battery.sendInternalVoltage", true);
Config.battery.monitorInternalVoltage = request->hasParam("battery.monitorInternalVoltage", true); Config.battery.monitorInternalVoltage = request->hasParam("battery.monitorInternalVoltage", true);
Config.battery.internalSleepVoltage = request->getParam("battery.internalSleepVoltage", true)->value().toFloat(); Config.battery.internalSleepVoltage = request->getParam("battery.internalSleepVoltage", true)->value().toFloat();
Config.battery.sendExternalVoltage = request->hasParam("battery.sendExternalVoltage", true); Config.battery.sendExternalVoltage = request->hasParam("battery.sendExternalVoltage", true);
if (Config.battery.sendExternalVoltage) { if (Config.battery.sendExternalVoltage) {
Config.battery.externalVoltagePin = request->getParam("battery.externalVoltagePin", true)->value().toInt(); Config.battery.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.monitorExternalVoltage = request->hasParam("battery.monitorExternalVoltage", true); Config.battery.monitorExternalVoltage = request->hasParam("battery.monitorExternalVoltage", true);
Config.battery.externalSleepVoltage = request->getParam("battery.externalSleepVoltage", true)->value().toFloat(); Config.battery.externalSleepVoltage = request->getParam("battery.externalSleepVoltage", true)->value().toFloat();
Config.bme.active = request->hasParam("bme.active", true); Config.bme.active = request->hasParam("bme.active", true);
Config.bme.heightCorrection = request->getParam("bme.heightCorrection", true)->value().toInt(); Config.bme.heightCorrection = request->getParam("bme.heightCorrection", true)->value().toInt();
Config.bme.temperatureCorrection = request->getParam("bme.temperatureCorrection", true)->value().toFloat(); Config.bme.temperatureCorrection = request->getParam("bme.temperatureCorrection", true)->value().toFloat();
@@ -158,36 +175,36 @@ namespace WEB_Utils {
Config.beacon.symbol = "_"; Config.beacon.symbol = "_";
} }
Config.syslog.active = request->hasParam("syslog.active", true); Config.syslog.active = request->hasParam("syslog.active", true);
if (Config.syslog.active) { if (Config.syslog.active) {
Config.syslog.server = request->getParam("syslog.server", true)->value(); Config.syslog.server = request->getParam("syslog.server", true)->value();
Config.syslog.port = request->getParam("syslog.port", true)->value().toInt(); Config.syslog.port = request->getParam("syslog.port", true)->value().toInt();
} }
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.rebootMode = request->hasParam("other.rebootMode", true); Config.rebootMode = request->hasParam("other.rebootMode", true);
Config.rebootModeTime = request->getParam("other.rebootModeTime", true)->value().toInt(); Config.rebootModeTime = request->getParam("other.rebootModeTime", true)->value().toInt();
Config.ota.username = request->getParam("ota.username", true)->value(); Config.ota.username = request->getParam("ota.username", true)->value();
Config.ota.password = request->getParam("ota.password", true)->value(); Config.ota.password = request->getParam("ota.password", true)->value();
Config.rememberStationTime = request->getParam("other.rememberStationTime", true)->value().toInt();
Config.rememberStationTime = request->getParam("other.rememberStationTime", true)->value().toInt();
Config.backupDigiMode = request->hasParam("other.backupDigiMode", true); Config.backupDigiMode = request->hasParam("other.backupDigiMode", true);
Config.lowPowerMode = request->hasParam("other.lowPowerMode", true); Config.lowPowerMode = request->hasParam("other.lowPowerMode", true);
Config.lowVoltageCutOff = request->getParam("other.lowVoltageCutOff", true)->value().toDouble(); Config.lowVoltageCutOff = request->getParam("other.lowVoltageCutOff", true)->value().toDouble();
Config.personalNote = request->getParam("personalNote", true)->value();
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.writeFile(); Config.writeFile();
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", ""); AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
@@ -249,6 +266,7 @@ namespace WEB_Utils {
server.on("/script.js", HTTP_GET, handleScript); server.on("/script.js", HTTP_GET, handleScript);
server.on("/bootstrap.css", HTTP_GET, handleBootstrapStyle); server.on("/bootstrap.css", HTTP_GET, handleBootstrapStyle);
server.on("/bootstrap.js", HTTP_GET, handleBootstrapScript); server.on("/bootstrap.js", HTTP_GET, handleBootstrapScript);
server.on("/favicon.png", HTTP_GET, handleFavicon);
OTA_Utils::setup(&server); // Include OTA Updater for WebServer OTA_Utils::setup(&server); // Include OTA Updater for WebServer
+4 -2
View File
@@ -40,7 +40,7 @@ namespace WIFI_Utils {
Serial.print(millis()); Serial.print(millis());
Serial.println("Reconnecting to WiFi..."); Serial.println("Reconnecting to WiFi...");
WiFi.disconnect(); WiFi.disconnect();
WiFi.reconnect(); WIFI_Utils::startWiFi();//WiFi.reconnect();
previousWiFiMillis = millis(); previousWiFiMillis = millis();
if (Config.backupDigiMode) { if (Config.backupDigiMode) {
@@ -110,7 +110,9 @@ namespace WIFI_Utils {
#endif #endif
if (WiFi.status() == WL_CONNECTED) { if (WiFi.status() == WL_CONNECTED) {
Serial.print("Connected as "); Serial.print("Connected as ");
Serial.println(WiFi.localIP()); Serial.print(WiFi.localIP());
Serial.print(" / MAC Address: ");
Serial.println(WiFi.macAddress());
show_display("", " Connected!!", "" , " loading ...", 1000); show_display("", " Connected!!", "" , " loading ...", 1000);
} else if (WiFi.status() != WL_CONNECTED) { } else if (WiFi.status() != WL_CONNECTED) {
startAP = true; startAP = true;
+14 -1
View File
@@ -9,8 +9,21 @@ files = [
'data_embed/style.css', 'data_embed/style.css',
'data_embed/bootstrap.js', 'data_embed/bootstrap.js',
'data_embed/bootstrap.css', 'data_embed/bootstrap.css',
'data_embed/favicon.png',
] ]
string_to_find_str = "String"
string_to_find_ver = "versionDate"
with open('src/LoRa_APRS_iGate.cpp', encoding='utf-8') as cpp_file:
for line in cpp_file:
if string_to_find_str in line and string_to_find_ver in line:
start = line.find('"') + 1
end = line.find('"', start)
if start > 0 and end > start:
versionDate = line[start:end]
break
for src in files: for src in files:
out = src + ".gz" out = src + ".gz"
@@ -19,7 +32,7 @@ for src in files:
content = f.read() content = f.read()
if src == 'data_embed/index.html': if src == 'data_embed/index.html':
env_vars = env["BOARD"] + "<br>" + ','.join(env["BUILD_FLAGS"]).replace('-Werror -Wall,', '').replace(',-DELEGANTOTA_USE_ASYNC_WEBSERVER=1', '') env_vars = env["BOARD"] + "<br>" + ','.join(env["BUILD_FLAGS"]).replace('-Werror -Wall,', '').replace(',-DELEGANTOTA_USE_ASYNC_WEBSERVER=1', '') + "<br>" + "Version date: " + versionDate
current_date = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') + " UTC" current_date = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') + " UTC"
build_info = f'{env_vars}<br>Build date: {current_date}'.encode() build_info = f'{env_vars}<br>Build date: {current_date}'.encode()