Compare commits

...

80 Commits

Author SHA1 Message Date
richonguzman
8b7e0fdcef minor correction to EM activation 2025-03-20 15:54:19 -03:00
richonguzman
ad996c8a49 encoded byte update 2025-03-18 19:10:15 -03:00
richonguzman
dedd7152d9 first update of timestamp 2025-03-18 18:50:08 -03:00
richonguzman
5f5d7d7868 ready for test 2025-03-18 14:02:09 -03:00
richonguzman
2e3cafd0f0 3 2025-03-10 03:02:48 -03:00
richonguzman
1c07c2fb2b 2 2025-03-09 10:48:18 -03:00
richonguzman
4c63dd8bb7 start1 2025-03-09 10:23:34 -03:00
richonguzman
b00fba9693 readme update 2025-03-03 13:53:29 -03:00
richonguzman
37162b9708 display font size correction 2025-03-03 12:22:22 -03:00
richonguzman
44d9732aa2 TbeamSupreme Added 2025-03-03 12:15:50 -03:00
richonguzman
312bdc9d9f refactor and blacklist2.0 2025-03-03 11:19:25 -03:00
richonguzman
ff0b96bfe4 readme update again 2025-02-28 16:56:54 -03:00
richonguzman
36a8ef0ffb readme update for epaper 2025-02-28 16:53:16 -03:00
richonguzman
5ce8059040 epaper updated 2025-02-28 16:48:26 -03:00
richonguzman
60aef00b24 function name correction 2025-02-25 14:15:30 -03:00
richonguzman
72c2c144ae last corrections 2025-02-25 14:01:14 -03:00
richonguzman
a1c552f197 readme update 2025-02-25 13:56:27 -03:00
richonguzman
8ede848199 ready for testing 2025-02-25 13:54:36 -03:00
richonguzman
a4a82b75c5 more testing 2025-02-24 18:49:17 -03:00
richonguzman
64ac924f1f first proposal 2025-02-24 17:57:24 -03:00
richonguzman
bde4a7f042 trim mod 2025-02-24 17:08:53 -03:00
richonguzman
d54b63df22 telemetry conf packet start after first beacon 2025-02-24 16:36:52 -03:00
richonguzman
c3d94d673a height correction with gps 2025-02-24 16:17:01 -03:00
richonguzman
45edf2ffa3 gps satelites indicator 2025-02-24 16:10:02 -03:00
richonguzman
d628de9c9c code cleaned to lighter versions 2025-02-12 15:28:48 -03:00
richonguzman
f879182f62 new mods 2025-02-12 14:15:36 -03:00
richonguzman
c9ed618a8b t-deck readme update 2025-01-22 09:52:22 -03:00
richonguzman
6c7b8f9918 readme update 2025-01-22 09:40:42 -03:00
richonguzman
c2b4b3b92f readme update 2025-01-22 01:35:28 -03:00
richonguzman
f7319ce591 avoid msg TX-RF of telemetry declaration 2025-01-22 00:12:11 -03:00
richonguzman
858162eb9c version and readme update 2025-01-22 00:00:46 -03:00
richonguzman
100b002309 tdeck ready 2025-01-21 23:57:56 -03:00
richonguzman
3acf73bf5f Tdeck working 2025-01-21 23:00:49 -03:00
richonguzman
53675e8084 upload blackList 2025-01-14 15:15:28 -03:00
richonguzman
4349019f7b version and readme UPDATE 2025-01-11 10:44:40 -03:00
richonguzman
411753c0aa build.yml updated 2025-01-10 12:15:32 -03:00
richonguzman
ad6aed7f0d starting with Heltec V3_2 2025-01-10 11:53:52 -03:00
richonguzman
f325c54fc3 Heltec Wireless Stick display fix 2025-01-08 12:59:39 -03:00
richonguzman
1a3966eadc readme update 2025-01-07 16:10:35 -03:00
richonguzman
ffd3eaeb49 fixes for beaconUpdate 2025-01-07 14:19:06 -03:00
richonguzman
df03a49123 version update 2025-01-06 10:14:51 -03:00
richonguzman
58d647bad1 added gps to troy 2025-01-06 09:33:47 -03:00
richonguzman
59988fbaf1 ready for testing 2025-01-05 12:32:46 -03:00
richonguzman
1ad13e3c09 gmt 15min fix 2025-01-04 12:30:22 -03:00
richonguzman
ffe1a2f830 gmt correction for 15 min 2025-01-02 12:20:18 -03:00
richonguzman
a0fdd78cb1 GMT to 15min step 2025-01-02 11:49:53 -03:00
richonguzman
95e437cb50 readme update 2025-01-01 21:58:24 -03:00
richonguzman
9c488991e2 ready for testing 2025-01-01 21:57:21 -03:00
richonguzman
ddcd33b94a blackList working 2025-01-01 21:56:13 -03:00
richonguzman
b688391a0e wildcard and two stations blacklisted OK 2025-01-01 21:42:37 -03:00
richonguzman
56d63d0389 base lista 2025-01-01 13:02:38 -03:00
richonguzman
ad5a5ccf18 digiEcoMode fix 2024-12-31 17:40:16 -03:00
richonguzman
92bc0a7667 readme update 2024-12-30 18:28:18 -03:00
richonguzman
ffcfc42b8a digirepeater Beacon fixed 2024-12-30 18:02:20 -03:00
richonguzman
f3e0830473 new byte for syslog 2024-12-11 18:03:13 -03:00
richonguzman
62107a5b4a passcode verified 2024-12-06 12:03:37 -03:00
richonguzman
9801545965 update1 2024-12-04 13:59:46 -03:00
richonguzman
dd89f56436 added xiao board 2024-12-04 09:12:22 -03:00
richonguzman
27593d8718 Xiao added 2024-12-04 08:46:07 -03:00
richonguzman
008575b422 test1 2024-12-04 08:09:54 -03:00
richonguzman
b8eedabe9a starting Xiao 2024-12-04 07:59:03 -03:00
richonguzman
7371b8e37a heltec v2 screen update 2024-11-20 14:43:48 -03:00
richonguzman
44605e82c2 define OLED_DISPLAY_HAS_RST_PIN 2024-11-20 11:26:29 -03:00
richonguzman
0360085131 minor code cleaning 2024-11-16 08:13:29 -03:00
richonguzman
57f720b0d1 small code cleaning on 25SecBuffer 2024-11-16 08:02:15 -03:00
richonguzman
3d01ea03c0 syslog server update 2024-11-07 09:34:27 -03:00
richonguzman
afb6a60bfe readme update 2024-11-06 12:49:37 -03:00
richonguzman
06ef37e4dc eliminando espacios en blanco 2024-11-06 12:47:42 -03:00
richonguzman
9159362796 update 2024-11-06 10:07:44 -03:00
richonguzman
47c136fdd5 correcciones 2024-11-05 23:51:10 -03:00
richonguzman
970d743b80 refactor inis 2024-11-05 23:21:05 -03:00
richonguzman
7c5e58f3b2 ready for testing 2024-11-05 19:14:22 -03:00
richonguzman
210c7acb70 testing3 2024-11-05 18:20:44 -03:00
richonguzman
8d102a73c1 testing2 2024-11-05 18:15:39 -03:00
richonguzman
5030d2d645 casi casi1 2024-11-05 16:59:21 -03:00
richonguzman
a95f55273f up1 2024-11-05 16:10:41 -03:00
richonguzman
4014db03c8 2 listas 2024-11-05 15:14:56 -03:00
richonguzman
d96d5f1963 testing 2024-11-05 14:41:41 -03:00
richonguzman
d1cb732ae1 33 folders 2024-11-05 14:12:56 -03:00
richonguzman
1504bf5a7f code cleaning 2024-10-29 18:57:23 -03:00
130 changed files with 2684 additions and 1411 deletions

View File

@@ -21,6 +21,8 @@ jobs:
chip: esp32
- name: heltec_wifi_lora_32_V3
chip: esp32s3
- name: heltec_wifi_lora_32_V3_2
chip: esp32s3
- name: heltec_wireless_stick
chip: esp32s3
- name: heltec_wireless_stick_lite_v3
@@ -51,6 +53,12 @@ jobs:
chip: esp32
- name: ttgo-t-beam-v1_2_SX1262
chip: esp32
- name: ttgo_t_deck_plus
chip: esp32s3
- name: ttgo_t_deck_GPS
chip: esp32s3
- name: ttgo_t_beam_s3_SUPREME_v3
chip: esp32s3
- name: ESP32_DIY_LoRa_A7670
chip: esp32
- name: ESP32_DIY_LoRa_A7670_915
@@ -77,6 +85,10 @@ jobs:
chip: esp32c3
- name: QRPLabs_LightGateway_1_0
chip: esp32s3
- name: XIAO_ESP32S3_WIO_SX1262
chip: esp32s3
- name: TROY_LoRa_APRS
chip: esp32
steps:
- uses: actions/checkout@v3

View File

@@ -1,4 +1,4 @@
# CA2RXU LoRa APRS iGate/Digirepeater
# CA2RXU LoRa APRS iGate/Digipeater
This firmware is for using ESP32 based boards with LoRa Modules and GPS to live in the APRS world.
@@ -36,6 +36,8 @@ ____________________________________________________
- TTGO T-Beam V1.0 , V1.1, V1.2 (also variations with SX1262 and SX1268 LoRa Modules).
- T-Deck Plus (and also regular T-Deck with/without GPS).
- HELTEC V2, V3 , Wireless Stick, Wireless Stick Lite, HT-CT62, Wireless Tracker, Wireless Paper.
- QRP Labs LightGateway 1.0.
@@ -52,18 +54,28 @@ ____________________________________________________
## Timeline (Versions):
- 2025.03.03 T-Beam Supreme board added and more BlackList rules added.
- 2025.02.28 Heltec Wireless Paper with Epaper working. Thanks SzymonPriv for pointing to the right library.
- 2025.02.25 Objects Rules update, GPS Boards: Satellites on Screen, Wx Height Correction from GPS Data.
- 2025.01.22 Added LILYGO T-DECK PLUS (and DIY+GPS version) board support.
- 2025.01.11 Added HELTEC V3.2 board support.
- 2025.01.07 TROY_LoRa_APRS board added. GMT in quarter hour fix and Beacon fix for TNC.
- 2025.01.02 Callsign Black List added.
- 2024.12.30 Fixed missing validation for correct Digipeater mode when not connected to APRS-IS.
- 2024.12.06 APRS-IS connnection and passcode validation added.
- 2024.11.06 (Silent Update) Working now with Board "VARIANTS".
- 2024.10.29 Added LILYGO Lora32 T3S3 support.
- 2024.10.25 Added QRP Labs LightGateway 1.0 support.
- 2024.10.21 Boards with GPS can now send Real-GPS Beacon (also posible: GPS ambiguity of ~ 1 km).
- 2024.10.14 Received Packets in WebUI show real Local Time (NTP with GMT offset).
- 2024.10.08 New EcoMode for Remote Digirepeaters without WiFi/WiFiAP, Screen, Leds (Example: LILYGO LoRa32 uses only 24mA, with WifiAP and all was 150mA). APRS Message/Queries can start/stop this mode too.
- 2024.10.06 Cross Frequency Digirepeater Rules added.
- 2024.10.08 New EcoMode for Remote Digipeaters without WiFi/WiFiAP, Screen, Leds (Example: LILYGO LoRa32 uses only 24mA, with WifiAP 150mA). APRS Message/Queries can start/stop this mode too.
- 2024.10.06 Cross Frequency Digipeater Rules added.
- 2024.09.23 Libraries Update for SDK3
- 2024.09.23 Added Enconded Telemetry for Battery (+ External Voltage) in Station GPS Beacon Packet.
- 2024.08.23 Wemos S2 Mini DIY LoRa added.
- 2024.08.19 HELTEC Wireless Paper working (still missing Epaper code).
- 2024.08.13 Web Authentication for WebUI. Thanks Mitja S57PNX.
- 2024.08.05 WIDE2-n added to WIDE1-n in Digirepeater Modes.
- 2024.08.05 WIDE2-n added to WIDE1-n in Digipeater 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.
@@ -74,7 +86,7 @@ ____________________________________________________
- 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.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-Digipeater-Mode when "only" iGate mode loses WiFi connection added.
- 2024.05.20 WebConfig update to control whether Messages and Objects should be Tx to RF.
- 2024.05.17 HELTEC Wireless Stick Lite v3 support added.
- 2024.05.14 BME modules will be autodetected (I2C Address and if it is BME280/BMP280/BME680).
@@ -86,12 +98,12 @@ ____________________________________________________
- 2024.04.21 WEB INSTALLER (thanks Damian SQ2CPA).
- 2024.04.20 New Output Buffer process: no more packets lost.
- 2024.04.13 Received Packets added on WebUI.
- 2024.04.09 iGate/Digirepeater own GPS beacon is encoded (Base91) now.
- 2024.04.09 iGate/Digipeater own GPS beacon is encoded (Base91) now.
- 2024.03.18 OE5HWN MeshCom board support added.
- 2024.02.25 New Web Configuration UI with WiFi AP (thanks Damian SQ2CPA).
- 2023.01.28 Updated to ElegantOTA v.3 (AsyncElegantOTA was deprecated).
- 2024.01.19 TextSerialOutputForApp added to get text from Serial-Output over USB into PC for PinPoint App (https://www.pinpointaprs.com) and APRSIS32 App (http://aprsisce.wikidot.com)
- 2024.01.12 Added iGate Mode to also repeat packets (like a iGate+DigiRepeater) in stationMode 2 and 5.
- 2024.01.12 Added iGate Mode to also repeat packets (like a iGate+Digipeater) in stationMode 2 and 5.
- 2024.01.11 Added iGate Mode to enable APRS-IS and LoRa beacon report at the same time.
- 2024.01.05 Lilygo TTGO T-Beam V1, V1.2, V1 + SX1268, V1.2 + SX1262 support added.
- 2024.01.02 EByte 400M30S 1 Watt LoRa module for DIY ESP32 iGate support added.
@@ -100,18 +112,18 @@ ____________________________________________________
- 2023.12.07 MIC-E process and Syslog added.
- 2023.12.06 HELTEC V2 board support added.
- 2023.11.26 Small correction to enable Syslog in stationMode5.
- 2023.10.09 Added "WIDE1-1" to Tx packets from iGate to be *repeated* by Digirepeaters.
- 2023.10.09 Added "WIDE1-1" to Tx packets from iGate to be *repeated* by Digipeaters.
- 2023.10.09 BMP280 module support added.
- 2023.08.20 Added External Voltage Measurement (Max 15V!)
- 2023.08.05 Ground Height Correction for Pressure readings added.
- 2023.07.31 StationMode5 added: iGate when WiFi and APRS available, DigiRepeater when not.
- 2023.07.31 StationMode5 added: iGate when WiFi and APRS available, Digipeater when not.
- 2023.07.16 Small OTA, BME module update.
- 2023.07.05 Adding monitor info of Battery connected.
- 2023.06.18 Info on Oled Screen mayor update, added RSSI and Distance to Listened Station.
- 2023.06.17 BME280 Module (Temperature, Humidity, Pressure) support added.
- 2023.06.12 Syslog added.
- 2023.06.10 OTA update support for Firmware and Filesystem.
- 2023.06.08 Adding Digirepeater Functions.
- 2023.06.08 Adding Digipeater Functions.
- 2023.06.06 Full repack of Code and adding _enableTx_ only for Ham Ops.
- 2023.05.23 Processing Query's from RF/LoRa or APRS-IS (Send "Help" Message to test).
- 2023.05.19 Saving Last-Heard Stations for validating Tx Responses.

44
common_settings.ini Normal file
View File

@@ -0,0 +1,44 @@
[common]
build_flags =
-Werror -Wall
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
-DRADIOLIB_EXCLUDE_CC1101=1
-DRADIOLIB_EXCLUDE_NRF24=1
-DRADIOLIB_EXCLUDE_RF69=1
-DRADIOLIB_EXCLUDE_SX1231=1
-DRADIOLIB_EXCLUDE_SX1233=1
-DRADIOLIB_EXCLUDE_SI443X=1
-DRADIOLIB_EXCLUDE_RFM2X=1
-DRADIOLIB_EXCLUDE_AFSK=1
-DRADIOLIB_EXCLUDE_BELL=1
-DRADIOLIB_EXCLUDE_HELLSCHREIBER=1
-DRADIOLIB_EXCLUDE_MORSE=1
-DRADIOLIB_EXCLUDE_RTTY=1
-DRADIOLIB_EXCLUDE_SSTV=1
-DRADIOLIB_EXCLUDE_AX25=1
-DRADIOLIB_EXCLUDE_DIRECT_RECEIVE=1
-DRADIOLIB_EXCLUDE_BELL=1
-DRADIOLIB_EXCLUDE_PAGER=1
-DRADIOLIB_EXCLUDE_FSK4=1
-DRADIOLIB_EXCLUDE_APRS=1
-DRADIOLIB_EXCLUDE_LORAWAN=1
-I variants/${PIOENV}
lib_deps =
adafruit/Adafruit Unified Sensor @ 1.1.14
adafruit/Adafruit BME280 Library @ 2.2.4
adafruit/Adafruit BMP280 Library @ 2.6.8
adafruit/Adafruit BME680 Library @ 2.0.4
adafruit/Adafruit Si7021 Library @ 1.5.3
arduino-libraries/NTPClient @ 3.2.1
ayushsharma82/ElegantOTA @ 3.1.5
bblanchon/ArduinoJson @ 6.21.3
jgromes/RadioLib @ 7.1.0
mathieucarbou/AsyncTCP @ 3.2.5
mathieucarbou/ESPAsyncWebServer @ 3.2.3
mikalhart/TinyGPSPlus @ 1.0.3
display_libs =
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
usb_flags=
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1

View File

@@ -56,7 +56,7 @@
"externalSleepVoltage": 10.9,
"voltageDividerR1": 100.0,
"voltageDividerR2": 27.0,
"sendVoltageAsTelemetry": true
"sendVoltageAsTelemetry": false
},
"wxsensor": {
"active": false,
@@ -65,8 +65,8 @@
},
"syslog": {
"active": false,
"server": "192.168.0.100",
"port": 514
"server": "lora.link9.net",
"port": 1514
},
"tnc": {
"enableServer": false,
@@ -82,8 +82,12 @@
"password": ""
},
"ntp": {
"gmtCorrection": 0
"gmtCorrection": 0.0
},
"remoteManagement": {
"managers": "",
"rfOnly": true
},
"other": {
"rememberStationTime": 30,
"lowPowerMode": false,
@@ -92,5 +96,6 @@
"rebootMode": false,
"rebootModeTime": 6
},
"personalNote": ""
"personalNote": "",
"blacklist": ""
}

View File

@@ -77,7 +77,7 @@
</tbody>
</table>
<span>List refresh automatically every 15 seconds.</span><br>
<small>(Local Time is NPT-Time adjusted with your GMT Offset)</small>
<small>(Local Time is NTP-Time adjusted with your GMT Offset)</small>
</div>
</div>
<hr />
@@ -121,7 +121,7 @@
<div class="row">
<div class="col-12">
<label for="callsign" class="form-label"
>Callsign and SSID</label
>Callsign - SSID</label
>
<input
type="text"
@@ -152,7 +152,7 @@
<label
for="beacon.path"
class="form-label"
>Beacon path</label
>Beacon Path</label
>
<input
type="text"
@@ -492,8 +492,7 @@
<label
for="beacon.sendViaAPRSIS"
class="form-label"
>Send beacon to
APRS-IS
>Send beacon via APRS-IS
</label>
</div>
</div>
@@ -516,12 +515,12 @@
<button class="btn btn-primary" id="send-beacon">Send beacon now</button>
</div>
</div>
<div class="row mt-3">
<div class="row mt-4">
<div class="col-12">
<label
for="beacon.interval"
class="form-label"
>Interval
>Beacon Interval
</label>
<div class="input-group">
<input
@@ -574,6 +573,47 @@
</div>
<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-broadcast-pin"
viewBox="0 0 16 16"
>
<path
d="M3.05 3.05a7 7 0 0 0 0 9.9.5.5 0 0 1-.707.707 8 8 0 0 1 0-11.314.5.5 0 0 1 .707.707m2.122 2.122a4 4 0 0 0 0 5.656.5.5 0 1 1-.708.708 5 5 0 0 1 0-7.072.5.5 0 0 1 .708.708m5.656-.708a.5.5 0 0 1 .708 0 5 5 0 0 1 0 7.072.5.5 0 1 1-.708-.708 4 4 0 0 0 0-5.656.5.5 0 0 1 0-.708m2.122-2.12a.5.5 0 0 1 .707 0 8 8 0 0 1 0 11.313.5.5 0 0 1-.707-.707 7 7 0 0 0 0-9.9.5.5 0 0 1 0-.707zM6 8a2 2 0 1 1 2.5 1.937V15.5a.5.5 0 0 1-1 0V9.937A2 2 0 0 1 6 8"
/>
</svg>
Black List
</h5>
<small>Add Callsigns with space between them to Blacklist them (* wild card allowed)</small>
</div>
<div class="col-9 mt-2">
<div class="row">
<div class="col-12">
<label
for="blacklist"
class="form-label"
>Blacklist</label
>
<input
type="text"
name="blacklist"
id="blacklist"
class="form-control"
placeholder="Station Callsign"
oninput="this.value = this.value.toUpperCase();"
/>
</div>
</div>
</div>
</div>
<hr />
<div class="row my-5 d-flex align-items-top">
<div class="col-lg-3 col-sm-12">
<h5>
@@ -626,7 +666,7 @@
<label
for="digi.ecoMode"
class="form-label"
>Eco Mode<small> This will disable WiFi, Display, Leds and lower CPU Speed for Low Power Digirepeater. (<strong>Caution:</strong> Active means No WebUI Configuration, so <strong>ONLY</strong> activate this for Remote Digirepeater)</small></label
>Eco Mode<small> This will disable WiFi, Display, Leds and lower CPU Speed for Low Power Digipeater. (<strong>Caution:</strong> Active means No WebUI Configuration, so <strong>ONLY</strong> activate this for Remote Digipeater)</small></label
>
</div>
</div>
@@ -1198,7 +1238,7 @@
class="form-label"
><b>Activate Wx Telemetry</b>
<small
>Requires a BME/BMP280, BME680 or Si7021 sensor installed</small
>Requires a BME/BMP280, BME680 or Si7021 sensor.</small
></label
>
</div>
@@ -1296,7 +1336,7 @@
type="text"
name="syslog.server"
id="syslog.server"
placeholder="192.168.0.100"
placeholder="lora.link9.net"
class="form-control"
disabled
/>
@@ -1311,7 +1351,7 @@
type="text"
name="syslog.port"
id="syslog.port"
placeholder="514"
placeholder="1514"
class="form-control"
disabled
/>
@@ -1668,6 +1708,65 @@
</div>
<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>
Remote Management
</h5>
<small
>Manage Station via APRS Messages. Leave empty to disable!
</small>
</div>
<div class="col-lg-9 col-sm-12">
<div class="col-12">
<label
for="remoteManagement.managers"
class="form-label"
>Callsign-SSID of Managers, space separated, trailing * wildcard allowed</label
>
<div class="input-group">
<input
type="text"
name="remoteManagement.managers"
id="remoteManagement.managers"
class="form-control"
/>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="form-check form-switch">
<input
type="checkbox"
name="remoteManagement.rfOnly"
id="remoteManagement.rfOnly"
class="form-check-input"
/>
<label
for="remoteManagement.rfOnly"
class="form-label"
>Managers commands only via RF (not APRS-IS)</label
>
</div>
</div>
</div>
</div>
</div>
<hr />
<div class="row my-5 d-flex align-items-top">
<div class="col-lg-3 col-sm-12">
<h5>
@@ -1704,9 +1803,9 @@
id="ntp.gmtCorrection"
placeholder="0"
class="form-control"
step="1"
min="-23"
max="23"
step="0.25"
min="-23.75"
max="23.75"
/>
<span class="input-group-text"
>hours</span
@@ -1744,7 +1843,7 @@
<div class="col-12">
<div class="form-check form-switch">
<div class="form-text">
When "only" iGate Mode loses WiFi, it will change into a Digirepeater Mode and after 15 min check if WiFi available and return to "only" iGate Mode.
When "only" iGate Mode loses WiFi, it will change into a Digipeater Mode and after 15 min check if WiFi available and return to "only" iGate Mode.
</div>
<input
type="checkbox"
@@ -1755,7 +1854,7 @@
<label
for="other.backupDigiMode"
class="form-label"
>Backup Digirepeater Mode</label
>Backup Digipeater Mode</label
>
</div>
</div>

View File

@@ -137,6 +137,9 @@ function loadSettings(settings) {
document.getElementById("beacon.gpsActive").checked = settings.beacon.gpsActive;
document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity;
// Black List
document.getElementById("blacklist").value = settings.blacklist;
// Digi
document.getElementById("digi.mode").value = settings.digi.mode;
document.getElementById("digi.ecoMode").checked = settings.digi.ecoMode;
@@ -220,6 +223,10 @@ function loadSettings(settings) {
document.getElementById("other.lowPowerMode").checked = settings.other.lowPowerMode;
document.getElementById("other.lowVoltageCutOff").value = settings.other.lowVoltageCutOff || 0
// Management over APRS
document.getElementById("remoteManagement.managers").value = settings.remoteManagement.managers;
document.getElementById("remoteManagement.rfOnly").checked = settings.remoteManagement.rfOnly;
updateImage();
refreshSpeedStandard();
toggleFields();
@@ -251,8 +258,6 @@ document.getElementById('reboot').addEventListener('click', function (e) {
const wxsensorCheckbox = document.querySelector("input[name='wxsensor.active']");
const stationModeSelect = document.querySelector("select[name='stationMode']");
function updateImage() {
const value = document.getElementById("beacon.overlay").value + document.getElementById("beacon.symbol").value;

BIN
images/Web004-BlackList.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -3,6 +3,7 @@
#include <Arduino.h>
namespace A7670_Utils {
bool checkModemOn();

View File

@@ -1,39 +0,0 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View File

@@ -8,6 +8,7 @@ namespace APRS_IS_Utils {
void upload(const String& line);
void connect();
void checkStatus();
String checkForStartingBytes(const String& packet);
@@ -19,6 +20,8 @@ namespace APRS_IS_Utils {
void processAPRSISPacket(const String& packet);
void listenAPRSIS();
void firstConnection();
}
#endif

View File

@@ -5,6 +5,7 @@
#include <vector>
#include <FS.h>
class WiFi_AP {
public:
String ssid;
@@ -49,7 +50,6 @@ public:
bool ecoMode;
};
class LoraModule {
public:
long txFreq;
@@ -119,10 +119,14 @@ public:
class NTP {
public:
int gmtCorrection;
float gmtCorrection;
};
class REMOTE_MANAGEMENT {
public:
String managers;
bool rfOnly;
};
class Configuration {
public:
@@ -134,6 +138,7 @@ public:
bool rebootMode;
int rebootModeTime;
String personalNote;
String blacklist;
std::vector<WiFi_AP> wifiAPs;
WiFi_Auto_AP wifiAutoAP;
BEACON beacon;
@@ -147,7 +152,8 @@ public:
TNC tnc;
OTA ota;
WEBADMIN webadmin;
NTP ntp;
NTP ntp;
REMOTE_MANAGEMENT remoteManagement;
void init();
void writeFile();

View File

@@ -7,7 +7,7 @@
namespace DIGI_Utils {
String buildPacket(const String& path, const String& packet, bool thirdParty, bool crossFreq);
String generateDigiRepeatedPacket(const String& packet, bool thirdParty);
String generateDigipeatedPacket(const String& packet, bool thirdParty);
void processLoRaPacket(const String& packet);
void checkEcoMode();

View File

@@ -5,13 +5,9 @@
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
void cleanTFT();
void displaySetup();
void displayToggle(bool toggle);
bool shouldCleanTFT(const String& header, const String& line1, const String& line2, const String& line3);
bool shouldCleanTFT(const String& header, const String& line1, const String& line2, const String& line3, const String& line4, const String& line5, const String& line6);
void displayShow(const String& header, const String& line1, const String& line2, const String& line3, int wait = 0);
void displayShow(const String& header, const String& line1, const String& line2, const String& line3, const String& line4, const String& line5, const String& line6, int wait = 0);

View File

@@ -3,6 +3,7 @@
#include <Arduino.h>
String encodeAddressAX25(String tnc2Address);
String decodeAddressAX25(const String& ax25Address, bool& isLast, bool isRelay);

View File

@@ -12,7 +12,7 @@ namespace LoRa_Utils {
String receivePacket();
void changeFreqTx();
void changeFreqRx();
void startReceive(); // ???
void startReceive();
void sleepRadio();
}

View File

@@ -3,6 +3,7 @@
#include <Arduino.h>
namespace NTP_Utils {
void setup();

View File

@@ -16,9 +16,13 @@ struct LastHeardStation {
String station;
};
namespace STATION_Utils {
void loadBlacklist();
void loadManagers();
bool isBlacklisted(const String& callsign);
bool isManager(const String& callsign);
bool checkObjectTime(const String& packet);
void deleteNotHeard();
void updateLastHeard(const String& station);
bool wasHeard(const String& station);

View File

@@ -3,6 +3,7 @@
#include <Arduino.h>
namespace TNC_Utils {
void setup();

View File

@@ -3,6 +3,7 @@
#include <Arduino.h>
class ReceivedPacket {
public:
String rxTime;

View File

@@ -13,10 +13,6 @@ namespace WEB_Utils {
void handleNotFound(AsyncWebServerRequest *request);
void handleStatus(AsyncWebServerRequest *request);
void handleHome(AsyncWebServerRequest *request);
//void handleReadConfiguration(AsyncWebServerRequest *request);
//void handleWriteConfiguration(AsyncWebServerRequest *request);
void handleStyle(AsyncWebServerRequest *request);
void handleScript(AsyncWebServerRequest *request);
void handleBootstrapStyle(AsyncWebServerRequest *request);

View File

@@ -11,6 +11,10 @@
[platformio]
default_envs = ttgo-lora32-v21
extra_configs =
common_settings.ini
variants/*/platformio.ini
[env]
platform = espressif32 @ 6.7.0
board_build.partitions = min_spiffs.csv
@@ -25,461 +29,4 @@ board_build.embed_files =
data_embed/favicon.png.gz
extra_scripts =
pre:tools/compress.py
debug_tool = esp-prog
[common]
build_flags =
-Werror -Wall
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
-DRADIOLIB_EXCLUDE_CC1101=1
-DRADIOLIB_EXCLUDE_NRF24=1
-DRADIOLIB_EXCLUDE_RF69=1
-DRADIOLIB_EXCLUDE_SX1231=1
-DRADIOLIB_EXCLUDE_SX1233=1
-DRADIOLIB_EXCLUDE_SI443X=1
-DRADIOLIB_EXCLUDE_RFM2X=1
-DRADIOLIB_EXCLUDE_AFSK=1
-DRADIOLIB_EXCLUDE_BELL=1
-DRADIOLIB_EXCLUDE_HELLSCHREIBER=1
-DRADIOLIB_EXCLUDE_MORSE=1
-DRADIOLIB_EXCLUDE_RTTY=1
-DRADIOLIB_EXCLUDE_SSTV=1
-DRADIOLIB_EXCLUDE_AX25=1
-DRADIOLIB_EXCLUDE_DIRECT_RECEIVE=1
-DRADIOLIB_EXCLUDE_BELL=1
-DRADIOLIB_EXCLUDE_PAGER=1
-DRADIOLIB_EXCLUDE_FSK4=1
-DRADIOLIB_EXCLUDE_APRS=1
-DRADIOLIB_EXCLUDE_LORAWAN=1
lib_deps =
jgromes/RadioLib @ 6.6.0
mikalhart/TinyGPSPlus @ 1.0.3
bblanchon/ArduinoJson @ 6.21.3
adafruit/Adafruit Unified Sensor @ 1.1.14
adafruit/Adafruit BME280 Library @ 2.2.4
adafruit/Adafruit BMP280 Library @ 2.6.8
adafruit/Adafruit BME680 Library @ 2.0.4
adafruit/Adafruit Si7021 Library @ 1.5.3
ayushsharma82/ElegantOTA @ 3.1.5
mathieucarbou/ESPAsyncWebServer @ 3.2.3
mathieucarbou/AsyncTCP @ 3.2.5
arduino-libraries/NTPClient @ 3.2.1
display_libs =
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ttgo-lora32-v21]
board = ttgo-lora32-v21
build_flags =
${common.build_flags}
-DTTGO_LORA32_V2_1
-DHAS_SX1278
-DHAS_ADC_CALIBRATION
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:ttgo-lora32-v21_915]
board = ttgo-lora32-v21
build_flags =
${common.build_flags}
-DTTGO_LORA32_V2_1_915
-DHAS_SX1276
-DHAS_ADC_CALIBRATION
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:heltec-lora32-v2]
board = ttgo-lora32-v21
build_flags =
${common.build_flags}
-DHELTEC_V2
-DHAS_SX1278
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:heltec_wifi_lora_32_V3]
board = heltec_wifi_lora_32_V3
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-DHELTEC_V3
-DHAS_SX1262
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:heltec_wireless_stick]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-DHELTEC_WS
-DHAS_SX1262
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:heltec_wireless_stick_lite_v3]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-DHELTEC_WSL_V3
-DHAS_SX1262
lib_deps =
${common.lib_deps}
[env:heltec_wireless_stick_lite_v3_display]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-DHELTEC_WSL_V3_DISPLAY
-DHAS_SX1262
lib_deps =
${common.lib_deps}
[env:ESP32_DIY_LoRa]
board = esp32dev
build_flags =
${common.build_flags}
-DESP32_DIY_LoRa
-DHAS_SX1278
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:ESP32_DIY_LoRa_915]
board = esp32dev
build_flags =
${common.build_flags}
-DESP32_DIY_LoRa_915
-DHAS_SX1276
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:ESP32_DIY_1W_LoRa]
board = esp32dev
build_flags =
${common.build_flags}
-DESP32_DIY_1W_LoRa
-DHAS_SX1268
-DHAS_1W_LORA
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:ESP32_DIY_1W_LoRa_915]
board = esp32dev
build_flags =
${common.build_flags}
-DESP32_DIY_1W_LoRa_915
-DHAS_SX1262
-DHAS_1W_LORA
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:ESP32_DIY_1W_LoRa_LLCC68]
board = esp32dev
build_flags =
${common.build_flags}
-DESP32_DIY_1W_LoRa_LLCC68
-DHAS_LLCC68
-DHAS_1W_LORA
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:ESP32_DIY_1W_LoRa_Mesh_V1_2]
board = esp32dev
build_flags =
${common.build_flags}
-DESP32_DIY_1W_LoRa_Mesh_V1_2
-DHAS_SX1268
-DHAS_1W_LORA
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:ttgo-t-beam-v1_2]
board = ttgo-t-beam
build_flags =
${common.build_flags}
-DTTGO_T_BEAM_V1_2
-DHAS_SX1278
-DHAS_AXP2101
-DHAS_GPS
lib_deps =
${common.lib_deps}
${common.display_libs}
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_2_915]
board = ttgo-t-beam
build_flags =
${common.build_flags}
-DTTGO_T_BEAM_V1_2_915
-DHAS_SX1276
-DHAS_AXP2101
-DHAS_GPS
lib_deps =
${common.lib_deps}
${common.display_libs}
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1]
board = ttgo-t-beam
build_flags =
${common.build_flags}
-DTTGO_T_BEAM_V1_0
-DHAS_SX1278
-DHAS_AXP192
-DHAS_GPS
lib_deps =
${common.lib_deps}
${common.display_libs}
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_915]
board = ttgo-t-beam
build_flags =
${common.build_flags}
-DTTGO_T_BEAM_V1_0_915
-DHAS_SX1276
-DHAS_AXP192
-DHAS_GPS
lib_deps =
${common.lib_deps}
${common.display_libs}
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_SX1268]
board = ttgo-t-beam
build_flags =
${common.build_flags}
-DTTGO_T_BEAM_V1_0_SX1268
-DHAS_SX1268
-DHAS_AXP192
-DHAS_GPS
lib_deps =
${common.lib_deps}
${common.display_libs}
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_2_SX1262]
board = ttgo-t-beam
build_flags =
${common.build_flags}
-DTTGO_T_BEAM_V1_2_SX1262
-DHAS_SX1262
-DHAS_AXP2101
-DHAS_GPS
lib_deps =
${common.lib_deps}
${common.display_libs}
lewisxhe/XPowersLib @ 0.2.4
[env:ESP32_DIY_LoRa_A7670]
board = esp32dev
build_flags =
${common.build_flags}
-DESP32_DIY_LoRa_A7670
-DHAS_SX1278
-DHAS_A7670
lib_deps =
${common.lib_deps}
${common.display_libs}
vshymanskyy/TinyGSM @ 0.12.0
vshymanskyy/StreamDebugger @ 1.0.1
[env:ESP32_DIY_LoRa_A7670_915]
board = esp32dev
build_flags =
${common.build_flags}
-DESP32_DIY_LoRa_A7670_915
-DHAS_SX1276
-DHAS_A7670
lib_deps =
${common.lib_deps}
${common.display_libs}
vshymanskyy/TinyGSM @ 0.12.0
vshymanskyy/StreamDebugger @ 1.0.1
[env:heltec_wireless_tracker]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-DHELTEC_WIRELESS_TRACKER
-DHAS_SX1262
-DHAS_GPS
-DGPS_BAUDRATE=115200
-DHAS_TFT
-D USER_SETUP_LOADED
-D TFT_WIDTH=80
-D TFT_HEIGHT=160
-D ST7735_DRIVER
-D ST7735_GREENTAB160x80
-D TFT_RGB_ORDER=TFT_BGR
-D TFT_MOSI=42
-D TFT_SCLK=41
-D TFT_CS=38
-D TFT_DC=40
-D TFT_RST=39
-D TFT_BL=21
-D TFT_BACKLIGHT_ON=1
-D TOUCH_CS=-1
-D LOAD_GLCD
-D LOAD_FONT2
-D LOAD_FONT4
-D LOAD_FONT6
-D LOAD_FONT7
-D LOAD_FONT8
-D SPI_FREQUENCY=27000000
-D USE_HSPI_PORT
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
lib_deps =
${common.lib_deps}
bodmer/TFT_eSPI @ 2.5.43
[env:heltec_ht-ct62]
board = heltec_wireless_stick_lite
board_build.mcu = esp32c3
build_flags =
${common.build_flags}
-DHELTEC_HTCT62
-DHAS_SX1262
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:heltec_wireless_paper]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-DHELTEC_WP
-DHAS_SX1262
-DHAS_EPAPER
lib_deps =
${common.lib_deps}
[env:OE5HWN_MeshCom]
board = esp32dev
build_flags =
${common.build_flags}
-DOE5HWN_MeshCom
-DHAS_SX1268
-DHAS_1W_LORA
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:WEMOS-LOLIN32-OLED-DIY]
board = lolin32
build_flags =
${common.build_flags}
-DWEMOS_LOLIN32_OLED_DIY_LoRa
-DHAS_SX1278
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:WEMOS-D1-R32-RA02]
board = wemos_d1_uno32
build_flags =
${common.build_flags}
-DWEMOS_D1_R32_RA02
-DHAS_SX1278
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:WEMOS_S2_MINI_DIY_LoRa]
board = lolin_s2_mini
build_flags =
${common.build_flags}
-DWEMOS_S2_MINI_DIY_LoRa
-DHAS_SX1278
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:esp32c3_DIY_1W_LoRa]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
${common.build_flags}
-DESP32C3_DIY_1W_LoRa
-DHAS_SX1268
-DHAS_1W_LORA
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:esp32c3_DIY_1W_LoRa_915]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
${common.build_flags}
-DESP32C3_DIY_1W_LoRa_915
-DHAS_SX1262
-DHAS_1W_LORA
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:ESP32_C3_OctopusLab_LoRa]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
${common.build_flags}
-DESP32_C3_OctopusLab_LoRa
-DHAS_SX1268
-DRADIO_HAS_XTAL
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:QRPLabs_LightGateway_1_0]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-DLIGHTGATEWAY_1_0
-DHAS_SX1268
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
lib_deps =
${common.lib_deps}
${common.display_libs}
[env:ttgo_lora32_t3s3_v1_2]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
board_upload.flash_size = 4MB
build_flags =
${common.build_flags}
-DTTGO_LORA32_T3S3_V1_2
-DHAS_SX1262
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
lib_deps =
${common.lib_deps}
${common.display_libs}
debug_tool = esp-prog

View File

@@ -1,11 +1,12 @@
#include "configuration.h"
#include "aprs_is_utils.h"
#include "boards_pinout.h"
#include "board_pinout.h"
#include "A7670_utils.h"
#include "lora_utils.h"
#include "display.h"
#include "utils.h"
#ifdef HAS_A7670
#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
@@ -200,6 +201,6 @@
}
}
delay(1);
}
}
}
#endif

View File

@@ -1,16 +1,24 @@
/*______________________________________________________________________________________________________________
/*___________________________________________________________________
██╗ ██████╗ ██████╗ █████╗ █████╗ ██████╗ ██████╗ ███████╗ ██╗ ██████╗ █████╗ ████████╗███████╗
██║ ██╔═══██╗██╔══██╗██╔══██╗ ██╔══██╗██╔══██╗██╔══██╗██╔════╝ ██║██╔════╝ ██╔══██╗╚══██╔══╝██╔════╝
██║ ██║ ██║██████╔╝███████║ ███████║██████╔╝██████╔╝███████╗ ██║██║ ███╗███████║ ██║ █████╗
██║ ██║ ██║██╔══██╗██╔══██║ ██╔══██║██╔═══╝ ██╔══██╗╚════██║ ██║██║ ██║██╔══██║ ██║ ██╔══╝
███████╗╚██████╔╝██║ ██║██║ ██║ ██║ ██║██║ ██║ ██║███████║ ██║╚██████╔╝██║ ██║ ██║ ███████╗
╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝
██╗ ██████╗ ██████╗ █████╗ █████╗ ██████╗ ██████╗ ███████╗
██║ ██╔═══██╗██╔══██╗██╔══██╗ ██╔══██╗██╔══██╗██╔══██╗██╔════╝
██║ ██║ ██║██████╔╝███████║ ███████║██████╔╝██████╔╝███████╗
██║ ██║ ██║██╔══██╗██╔══██║ ██╔══██║██╔═══╝ ██╔══██╗╚════██║
███████╗╚██████╔╝██║ ██║██║ ██║ ██║ ██║██║ ██║ ██║███████║
╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚══════╝
██╗ ██████╗ █████╗ ████████╗███████╗
██║██╔════╝ ██╔══██╗╚══██╔══╝██╔════╝
██║██║ ███╗███████║ ██║ █████╗
██║██║ ██║██╔══██║ ██║ ██╔══╝
██║╚██████╔╝██║ ██║ ██║ ███████╗
╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝
Ricardo Guzman - CA2RXU
https://github.com/richonguzman/LoRa_APRS_Tracker
(donations : http://paypal.me/richonguzman)
______________________________________________________________________________________________________________*/
Ricardo Guzman - CA2RXU
https://github.com/richonguzman/LoRa_APRS_Tracker
(donations : http://paypal.me/richonguzman)
___________________________________________________________________*/
#include <ElegantOTA.h>
#include <TinyGPS++.h>
@@ -18,13 +26,11 @@ ________________________________________________________________________________
#include <WiFi.h>
#include <vector>
#include "configuration.h"
#include "battery_utils.h"
#include "aprs_is_utils.h"
#include "station_utils.h"
#include "boards_pinout.h"
#include "battery_utils.h"
#include "board_pinout.h"
#include "syslog_utils.h"
#include "query_utils.h"
#include "power_utils.h"
#include "lora_utils.h"
#include "wifi_utils.h"
@@ -40,12 +46,15 @@ ________________________________________________________________________________
#include "A7670_utils.h"
#endif
String versionDate = "2024.10.29";
String versionDate = "2025.03.20";
Configuration Config;
WiFiClient espClient;
#ifdef HAS_GPS
HardwareSerial gpsSerial(1);
TinyGPSPlus gps;
uint32_t gpsSatelliteTime = 0;
bool gpsInfoToggle = false;
#endif
uint8_t myWiFiAPIndex = 0;
@@ -58,12 +67,17 @@ uint32_t lastBatteryCheck = 0;
bool backUpDigiMode = false;
bool modemLoggedToAPRSIS = false;
#ifdef HAS_EPAPER
uint32_t lastEpaperTime = 0;
extern String lastEpaperText;
#endif
std::vector<ReceivedPacket> receivedPackets;
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
//#define STARTUP_DELAY 5 //min
void setup() {
Serial.begin(115200);
POWER_Utils::setup();
@@ -71,6 +85,8 @@ void setup() {
LoRa_Utils::setup();
Utils::validateFreqs();
GPS_Utils::setup();
STATION_Utils::loadBlacklist();
STATION_Utils::loadManagers();
#ifdef STARTUP_DELAY // (TEST) just to wait for WiFi init of Routers
displayShow("", " STARTUP DELAY ...", "", "", 0);
@@ -128,6 +144,7 @@ void setup() {
A7670_Utils::setup();
#endif
Utils::checkRebootMode();
APRS_IS_Utils::firstConnection();
}
void loop() {
@@ -141,14 +158,32 @@ void loop() {
if (Config.lowVoltageCutOff > 0) {
BATTERY_Utils::checkIfShouldSleep();
}
thirdLine = Utils::getLocalIP();
WIFI_Utils::checkWiFi();
#ifdef HAS_GPS
if (Config.beacon.gpsActive) {
if (millis() - gpsSatelliteTime > 5000) {
gpsInfoToggle = !gpsInfoToggle;
gpsSatelliteTime = millis();
}
if (gpsInfoToggle) {
thirdLine = "Satellite(s): ";
String gpsData = String(gps.satellites.value());
if (gpsData.length() < 2) gpsData = "0" + gpsData; // Ensure two-digit formatting
thirdLine += gpsData;
} else {
thirdLine = Utils::getLocalIP();
}
} else {
thirdLine = Utils::getLocalIP();
}
#else
thirdLine = Utils::getLocalIP();
#endif
#ifdef HAS_A7670
if (Config.aprs_is.active && !modemLoggedToAPRSIS) A7670_Utils::APRS_IS_connect();
#else
WIFI_Utils::checkWiFi();
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) APRS_IS_Utils::connect();
#endif
@@ -172,7 +207,7 @@ void loop() {
if (Config.loramodule.txActive && (Config.digi.mode == 2 || Config.digi.mode == 3 || backUpDigiMode)) { // If Digi enabled
STATION_Utils::clean25SegBuffer();
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi
}
if (Config.tnc.enableServer) { // If TNC server enabled
@@ -183,13 +218,25 @@ void loop() {
}
}
if (Config.aprs_is.active) { // If APRSIS enabled
if (Config.aprs_is.active) {
APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS
}
STATION_Utils::processOutputPacketBuffer();
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
#ifdef HAS_EPAPER // Only consider updating every 10 seconds (when data to show is different from before)
if(lastEpaperTime == 0 || millis() - lastEpaperTime > 10000) {
String posibleEpaperText = firstLine + secondLine + thirdLine + fourthLine + fifthLine + sixthLine + seventhLine;
if (lastEpaperText != posibleEpaperText) {
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
lastEpaperText = posibleEpaperText;
lastEpaperTime = millis();
}
}
#else
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
#endif
Utils::checkRebootTime();
Utils::checkSleepByLowBatteryVoltage(1);
}

View File

@@ -9,6 +9,7 @@
#include "display.h"
#include "utils.h"
extern Configuration Config;
extern WiFiClient espClient;
extern uint32_t lastScreenOn;
@@ -22,7 +23,8 @@ extern String seventhLine;
extern bool modemLoggedToAPRSIS;
extern bool backUpDigiMode;
uint32_t lastRxTime = millis();
uint32_t lastRxTime = millis();
bool passcodeValid = false;
#ifdef HAS_A7670
extern bool stationBeacon;
@@ -50,19 +52,16 @@ namespace APRS_IS_Utils {
}
if (count == 20) {
Serial.println("Tried: " + String(count) + " FAILED!");
}
else {
} else {
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 aprsAuth = "user ";
aprsAuth += Config.callsign;
aprsAuth += " pass ";
aprsAuth += Config.aprs_is.passcode;
aprsAuth += " vers CA2RXU_LoRa_iGate 2.0 filter ";
aprsAuth += " vers CA2RXU_iGate 2.3 filter ";
aprsAuth += Config.aprs_is.filter;
upload(aprsAuth);
delay(200);
}
}
@@ -101,7 +100,7 @@ namespace APRS_IS_Utils {
if(aprsisState == "--" && !Config.display.alwaysOn && Config.display.timeout != 0) {
displayToggle(true);
lastScreenOn = millis();
}
}
}
secondLine = "WiFi: ";
secondLine += wifiState;
@@ -174,40 +173,38 @@ namespace APRS_IS_Utils {
}
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) {
displayToggle(true);
}
lastScreenOn = millis();
#ifdef HAS_A7670
stationBeacon = true;
A7670_Utils::uploadToAPRSIS(aprsPacket);
stationBeacon = false;
#else
upload(aprsPacket);
#endif
Utils::println("---> Uploaded to APRS-IS");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
}
if (passcodeValid && (espClient.connected() || modemLoggedToAPRSIS)) {
if (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) {
displayToggle(true);
}
lastScreenOn = millis();
#ifdef HAS_A7670
stationBeacon = true;
A7670_Utils::uploadToAPRSIS(aprsPacket);
stationBeacon = false;
#else
upload(aprsPacket);
#endif
Utils::println("---> Uploaded to APRS-IS");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
}
}
}
}
}
@@ -259,13 +256,22 @@ namespace APRS_IS_Utils {
}
void processAPRSISPacket(const String& packet) {
if (!packet.startsWith("#")) {
if (!passcodeValid && packet.indexOf(Config.callsign) != -1) {
if (packet.indexOf("unverified") != -1 ) {
Serial.println("\n****APRS PASSCODE NOT VALID****\n");
displayShow(firstLine, "", " APRS PASSCODE", " NOT VALID !!!", "", "", "", 0);
while (1) {};
} else if (packet.indexOf("verified") != -1 ) {
passcodeValid = true;
}
}
if (passcodeValid && !packet.startsWith("#")) {
if (Config.aprs_is.messagesToRF && packet.indexOf("::") > 0) {
String Sender = packet.substring(0, packet.indexOf(">"));
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
if (Addressee == Config.callsign) { // its for me!
if (Addressee == Config.callsign) { // its for me!
String receivedMessage;
if (AddresseeAndMessage.indexOf("{") > 0) { // ack?
String ackMessage = "ack";
@@ -285,13 +291,14 @@ namespace APRS_IS_Utils {
A7670_Utils::uploadToAPRSIS(ackPacket);
#else
upload(ackPacket);
#endif
#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);
Utils::println("Rx Query (APRS-IS) : " + packet);
Sender.trim();
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
@@ -315,22 +322,28 @@ namespace APRS_IS_Utils {
seventhLine = "QUERY = ";
seventhLine += receivedMessage;
}
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} else {
Utils::print("Received Message from APRS-IS : " + packet);
if (STATION_Utils::wasHeard(Addressee)) {
Utils::print("Rx Message (APRS-IS): " + packet);
if (STATION_Utils::wasHeard(Addressee) && packet.indexOf("EQNS.") == -1 && packet.indexOf("UNIT.") == -1 && packet.indexOf("PARM.") == -1) {
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1));
displayToggle(true);
lastScreenOn = millis();
Utils::typeOfPacket(packet, 1); // APRS-LoRa
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
}
}
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
Utils::println("Received Object from APRS-IS : " + packet);
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5));
displayToggle(true);
lastScreenOn = millis();
Utils::typeOfPacket(packet, 1); // APRS-LoRa
Utils::print("Rx Object (APRS-IS) : " + packet);
if (STATION_Utils::checkObjectTime(packet)) {
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5));
displayToggle(true);
lastScreenOn = millis();
Utils::typeOfPacket(packet, 1); // APRS-LoRa
Serial.println();
} else {
Serial.println(" ---> Rejected (Time): No Tx");
}
}
}
}
@@ -342,7 +355,7 @@ namespace APRS_IS_Utils {
if (espClient.connected()) {
if (espClient.available()) {
String aprsisPacket = espClient.readStringUntil('\r');
// Serial.println(aprsisPacket);
aprsisPacket.trim(); // Serial.println(aprsisPacket);
processAPRSISPacket(aprsisPacket);
lastRxTime = millis();
}
@@ -350,4 +363,13 @@ namespace APRS_IS_Utils {
#endif
}
void firstConnection() {
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) {
connect();
while (!passcodeValid) {
listenAPRSIS();
}
}
}
}

View File

@@ -1,10 +1,11 @@
#include <Arduino.h>
#include "battery_utils.h"
#include "configuration.h"
#include "boards_pinout.h"
#include "board_pinout.h"
#include "power_utils.h"
#include "utils.h"
extern Configuration Config;
extern uint32_t lastBatteryCheck;
@@ -101,7 +102,7 @@ namespace BATTERY_Utils {
int sample;
int sampleSum = 0;
#ifdef ADC_CTRL
#if defined(HELTEC_WIRELESS_TRACKER)
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3_2)
digitalWrite(ADC_CTRL, HIGH);
#endif
#if defined(HELTEC_V3) || defined(HELTEC_V2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WP)
@@ -126,13 +127,13 @@ namespace BATTERY_Utils {
sample = 0;
#endif
#endif
#endif
#endif
sampleSum += sample;
delayMicroseconds(50);
}
#ifdef ADC_CTRL
#if defined(HELTEC_WIRELESS_TRACKER)
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3_2)
digitalWrite(ADC_CTRL, LOW);
#endif
#if defined(HELTEC_V3) || defined(HELTEC_V2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WP)
@@ -182,7 +183,7 @@ namespace BATTERY_Utils {
float extVoltage;
#ifdef HAS_ADC_CALIBRATION
if (calibrationEnable){
if (calibrationEnable){
extVoltage = esp_adc_cal_raw_to_voltage(sampleSum / 100, &adc_chars) * voltageDividerTransformation; // in mV
extVoltage /= 1000;
} else {
@@ -240,7 +241,7 @@ namespace BATTERY_Utils {
tempValue = value;
break;
}
}
}
int firstByte = tempValue / 91;
tempValue -= firstByte * 91;

View File

@@ -1,331 +0,0 @@
#ifndef PINS_CONFIG_H_
#define PINS_CONFIG_H_
#include <Arduino.h>
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
// LORA MODULES
#if defined(TTGO_LORA32_V2_1) || defined(HELTEC_V2) || defined(ESP32_DIY_LoRa) || defined(TTGO_T_BEAM_V1_2) || defined(TTGO_T_BEAM_V1_0) || defined(TTGO_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_MISO_PIN 19 // GPIO19 - SX1278 MISO
#define RADIO_MOSI_PIN 27 // GPIO27 - SX1278 MOSI
#define RADIO_CS_PIN 18 // GPIO18 - SX1278 CS ---> NSS
#define RADIO_RST_PIN 14 // GPIO14 - SX1278 RST
#define RADIO_BUSY_PIN 26 // GPIO26 - SX1278 IRQ ---->DIO0
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY) || defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_WS) || defined(HELTEC_WP)
#define RADIO_SCLK_PIN 9 // SX1262 SCK
#define RADIO_MISO_PIN 11 // SX1262 MISO
#define RADIO_MOSI_PIN 10 // SX1262 MOSI
#define RADIO_CS_PIN 8 // SX1262 NSS
#define RADIO_RST_PIN 12 // SX1262 RST
#define RADIO_DIO1_PIN 14 // SX1262 DIO1
#define RADIO_BUSY_PIN 13 // SX1262 BUSY
#endif
#if defined(ESP32_DIY_1W_LoRa) || defined(ESP32_DIY_1W_LoRa_915) || defined(ESP32_DIY_1W_LoRa_LLCC68) // Ebyte E22 400M30S (SX1268) or E22 900M30S (SX1262) or E220 LLCC68
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 12
#define RADIO_BUSY_PIN 14
#define RADIO_RXEN 32
#define RADIO_TXEN 25
#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
#define RADIO_SCLK_PIN 15
#define RADIO_MISO_PIN 13
#define RADIO_MOSI_PIN 12
#define RADIO_CS_PIN 14
#define RADIO_RST_PIN 2
#define RADIO_BUSY_PIN 25
#endif
#if defined(TTGO_T_BEAM_V1_0_SX1268) || defined(TTGO_T_BEAM_V1_2_SX1262)
#define RADIO_SCLK_PIN 5
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 27
#define RADIO_CS_PIN 18
#define RADIO_DIO0_PIN 26
#define RADIO_RST_PIN 23
#define RADIO_DIO1_PIN 33
#define RADIO_BUSY_PIN 32
#endif
#if defined(OE5HWN_MeshCom)
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 33
#define RADIO_BUSY_PIN 26
#define RADIO_RXEN 14
#define RADIO_TXEN 13
#endif
#if defined(HELTEC_HTCT62)
#define RADIO_SCLK_PIN 10 // SX1262 SCK
#define RADIO_MISO_PIN 6 // SX1262 MISO
#define RADIO_MOSI_PIN 7 // SX1262 MOSI
#define RADIO_CS_PIN 8 // SX1262 NSS
#define RADIO_RST_PIN 5 // SX1262 RST
#define RADIO_DIO1_PIN 3 // SX1262 DIO1
#define RADIO_BUSY_PIN 4 // SX1262 BUSY
#endif
#if defined(ESP32_DIY_LoRa_A7670) || defined(ESP32_DIY_LoRa_A7670_915)
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 2
#define RADIO_RST_PIN 0
#define RADIO_BUSY_PIN 32
#define A7670_PWR_PIN 4
#define A7670_ResetPin 5
#define A7670_TX_PIN 26
#define A7670_RX_PIN 27
#endif
#ifdef WEMOS_D1_R32_RA02
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_BUSY_PIN 12
#define RADIO_RST_PIN 13
#define RADIO_DIO1_PIN 14
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST 36
#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
#ifdef WEMOS_S2_MINI_DIY_LoRa
#define RADIO_SCLK_PIN 36
#define RADIO_MISO_PIN 37
#define RADIO_MOSI_PIN 35
#define RADIO_CS_PIN 34
#define RADIO_BUSY_PIN 38
#define RADIO_RST_PIN 33
#endif
#ifdef LIGHTGATEWAY_1_0
#define RADIO_VCC_PIN 21
#define RADIO_SCLK_PIN 12
#define RADIO_MISO_PIN 13
#define RADIO_MOSI_PIN 11
#define RADIO_CS_PIN 10
#define RADIO_RST_PIN 9
#define RADIO_DIO1_PIN 5
#define RADIO_BUSY_PIN 6
#define RADIO_RXEN 42
#define RADIO_TXEN 14
#endif
// OLED
#if defined(TTGO_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_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_LLCC68) || defined(ESP32_DIY_1W_LoRa_Mesh_V1_2)
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#endif
#if defined(HELTEC_V2) || defined(HELTEC_WS)
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
#endif
#if defined(HELTEC_V3)
#define OLED_SDA 17
#define OLED_SCL 18
#define OLED_RST 21
#endif
#ifdef WEMOS_LOLIN32_OLED_DIY_LoRa
#define OLED_SDA 5
#define OLED_SCL 4
#define OLED_RST -1
#endif
#ifdef LIGHTGATEWAY_1_0
#define OLED_SDA 3
#define OLED_SCL 4
#define OLED_RST -1
#endif
#if !defined(HELTEC_HTCT62) && !defined(HELTEC_WSL_V3) && !defined(ESP32C3_DIY_1W_LoRa) && !defined(ESP32C3_DIY_1W_LoRa_915) && !defined(WEMOS_S2_MINI_DIY_LoRa)
#define HAS_DISPLAY
#endif
// Leds and other stuff
#ifdef HELTEC_HTCT62
#define BATTERY_PIN 1
#endif
#ifdef WEMOS_S2_MINI_DIY_LoRa
#define INTERNAL_LED_PIN 15
#endif
#if defined(TTGO_LORA32_V2_1) || defined(TTGO_LORA32_V2_1_915)
#define INTERNAL_LED_PIN 25 // Green Led
#define BATTERY_PIN 35
#endif
#if defined(HELTEC_V2)
#define INTERNAL_LED_PIN 25
#define BATTERY_PIN 37
#define ADC_CTRL 21
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY) || defined(HELTEC_WS)
#define INTERNAL_LED_PIN 35
#define BATTERY_PIN 1
#define VEXT_CTRL 36
#define ADC_CTRL 37
#define BOARD_I2C_SDA 41
#define BOARD_I2C_SCL 42
#ifdef HELTEC_WSL_V3_DISPLAY
#define OLED_RST -1
#endif
#endif
#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
#endif
#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 BATTERY_PIN 35
#endif
#ifdef HELTEC_WIRELESS_TRACKER
#define INTERNAL_LED_PIN 18
#define BATTERY_PIN 1
#define ADC_CTRL 2 // HELTEC Wireless Tracker ADC_CTRL = HIGH powers the voltage divider to read BatteryPin. Only on V05 = V1.1
#define VEXT_CTRL 3 // To turn on GPS and TFT
#define BOARD_I2C_SDA 7
#define BOARD_I2C_SCL 6
#endif
#ifdef HELTEC_WP
#define INTERNAL_LED_PIN 18
#define BATTERY_PIN 20
#define ADC_CTRL 19
#define VEXT_CTRL 45
#define BOARD_I2C_SDA 37
#define BOARD_I2C_SCL 36
#define EPAPER_BUSY 7
#define EPAPER_RST 6
#define EPAPER_DC 5
#define EPAPER_CS 4
#define EPAPER_SCL 3
#define EPAPER_SDA 2
#endif
#ifdef ESP32_C3_DIY_LoRa // just testing!
#define OLED_SDA 8
#define OLED_SCL 9
#define OLED_RST 10
#define RADIO_SCLK_PIN 4
#define RADIO_MISO_PIN 5
#define RADIO_MOSI_PIN 6
#define RADIO_CS 7
#define RADIO_RST_PIN 3
#define RADIO_IRQ_PIN 2
#endif
#if defined(ESP32_C3_OctopusLab_LoRa)
#define OLED_SDA 0
#define OLED_SCL 1
#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_DIO1_PIN 3
#define RADIO_RST_PIN -1
#define RADIO_BUSY_PIN 8
#endif
#ifdef LIGHTGATEWAY_1_0
#define BUTTON_PIN 0
#define INTERNAL_LED_PIN 16
#endif
// GPS
#if defined(TTGO_T_BEAM_V1_2) || defined(TTGO_T_BEAM_V1_2_915) || defined(TTGO_T_BEAM_V1_0) || defined(TTGO_T_BEAM_V1_0_915) || defined(TTGO_T_BEAM_V1_0_SX1268) || defined(TTGO_T_BEAM_V1_2_SX1262)
#define GPS_RX 12
#define GPS_TX 34
#endif
#if defined( HELTEC_WIRELESS_TRACKER)
#define GPS_RX 34
#define GPS_TX 33
#endif
/* (Same pins for LILYGO LoRa32 and ESP32 Wroom Dev )
SX1278-------------------> ESP32 ttgo-lora32-v21 and ESP32 WROOM Dev
GND GND
DIO1 -
DIO2 -
DIO3 -
VCC 3.3V
MISO 19
MOSI 27
SCLK 5
NSS 18
DIO0 26
REST 14
GND - */
#ifdef TTGO_LORA32_T3S3_V1_2
#define RADIO_SCLK_PIN 5 // SX1262 SCK
#define RADIO_MISO_PIN 3 // SX1262 MISO
#define RADIO_MOSI_PIN 6 // SX1262 MOSI
#define RADIO_CS_PIN 7 // SX1262 NSS
#define RADIO_RST_PIN 8 // SX1262 RST
#define RADIO_DIO1_PIN 33 // SX1262 DIO1
#define RADIO_BUSY_PIN 34 // SX1262 BUSY
#define OLED_SDA 18
#define OLED_SCL 17
#define OLED_RST -1
#define INTERNAL_LED_PIN 37 // Green Led
#define BATTERY_PIN 1
#endif
#endif

View File

@@ -71,7 +71,7 @@ void Configuration::writeFile() {
data["battery"]["voltageDividerR2"] = battery.voltageDividerR2;
data["battery"]["sendVoltageAsTelemetry"] = battery.sendVoltageAsTelemetry;
data["wxsensor"]["active"] = wxsensor.active;
data["wxsensor"]["heightCorrection"] = wxsensor.heightCorrection;
data["wxsensor"]["temperatureCorrection"] = wxsensor.temperatureCorrection;
@@ -99,12 +99,17 @@ void Configuration::writeFile() {
data["personalNote"] = personalNote;
data["blacklist"] = blacklist;
data["webadmin"]["active"] = webadmin.active;
data["webadmin"]["username"] = webadmin.username;
data["webadmin"]["password"] = webadmin.password;
data["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
data["remoteManagement"]["managers"] = remoteManagement.managers;
data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly;
serializeJson(data, configFile);
configFile.close();
@@ -152,7 +157,7 @@ bool Configuration::readFile() {
beacon.gpsActive = data["beacon"]["gpsActive"] | false;
beacon.gpsAmbiguity = data["beacon"]["gpsAmbiguity"] | false;
aprs_is.active = data["aprs_is"]["active"] | false;
aprs_is.passcode = data["aprs_is"]["passcode"] | "XYZWV";
aprs_is.server = data["aprs_is"]["server"] | "rotate.aprs2.net";
@@ -160,7 +165,7 @@ bool Configuration::readFile() {
aprs_is.filter = data["aprs_is"]["filter"] | "m/10";
aprs_is.messagesToRF = data["aprs_is"]["messagesToRF"] | false;
aprs_is.objectsToRF = data["aprs_is"]["objectsToRF"] | false;
digi.mode = data["digi"]["mode"] | 0;
digi.ecoMode = data["digi"]["ecoMode"] | false;
@@ -195,8 +200,8 @@ bool Configuration::readFile() {
wxsensor.temperatureCorrection = data["wxsensor"]["temperatureCorrection"] | 0.0;
syslog.active = data["syslog"]["active"] | false;
syslog.server = data["syslog"]["server"] | "192.168.0.100";
syslog.port = data["syslog"]["port"] | 514;
syslog.server = data["syslog"]["server"] | "lora.link9.net";
syslog.port = data["syslog"]["port"] | 1514;
tnc.enableServer = data["tnc"]["enableServer"] | false;
tnc.enableSerial = data["tnc"]["enableSerial"] | false;
@@ -209,7 +214,7 @@ bool Configuration::readFile() {
webadmin.username = data["webadmin"]["username"] | "admin";
webadmin.password = data["webadmin"]["password"] | "";
ntp.gmtCorrection = data["ntp"]["gmtCorrection"] | 0;
ntp.gmtCorrection = data["ntp"]["gmtCorrection"] | 0.0;
lowPowerMode = data["other"]["lowPowerMode"] | false;
lowVoltageCutOff = data["other"]["lowVoltageCutOff"] | 0;
@@ -219,7 +224,12 @@ bool Configuration::readFile() {
rebootMode = data["other"]["rebootMode"] | false;
rebootModeTime = data["other"]["rebootModeTime"] | 6;
personalNote = data["personalNote"] | "personal note here...";
personalNote = data["personalNote"] | "personal note here";
blacklist = data["blacklist"] | "station callsign";
remoteManagement.managers = data["remoteManagement"]["managers"] | "";
remoteManagement.rfOnly = data["remoteManagement"]["rfOnly"] | true;
if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP
WiFi_AP wifiap;
@@ -262,7 +272,7 @@ void Configuration::init() {
beacon.gpsActive = false;
beacon.gpsAmbiguity = false;
digi.mode = 0;
digi.ecoMode = false;
@@ -292,8 +302,8 @@ void Configuration::init() {
display.turn180 = false;
syslog.active = false;
syslog.server = "192.168.0.100";
syslog.port = 514;
syslog.server = "lora.link9.net";
syslog.port = 1514;
wxsensor.active = false;
wxsensor.heightCorrection = 0;
@@ -315,7 +325,7 @@ void Configuration::init() {
battery.voltageDividerR1 = 100.0;
battery.voltageDividerR2 = 27.0;
battery.sendVoltageAsTelemetry = true;
battery.sendVoltageAsTelemetry = false;
lowPowerMode = false;
lowVoltageCutOff = 0;
@@ -327,11 +337,16 @@ void Configuration::init() {
personalNote = "";
blacklist = "";
webadmin.active = false;
webadmin.username = "admin";
webadmin.password = "";
ntp.gmtCorrection = 0;
ntp.gmtCorrection = 0.0;
remoteManagement.managers = "";
remoteManagement.rfOnly = true;
Serial.println("All is Written!");
}

View File

@@ -2,7 +2,6 @@
#include "configuration.h"
#include "station_utils.h"
#include "aprs_is_utils.h"
#include "query_utils.h"
#include "digi_utils.h"
#include "wifi_utils.h"
#include "lora_utils.h"
@@ -10,6 +9,7 @@
#include "display.h"
#include "utils.h"
extern Configuration Config;
extern uint32_t lastScreenOn;
extern String iGateBeaconPacket;
@@ -54,7 +54,7 @@ namespace DIGI_Utils {
packetToRepeat += APRS_IS_Utils::checkForStartingBytes(packet.substring(packet.indexOf(":")));
}
return packetToRepeat;
} else { // CrossFreq Digirepeater
} else { // CrossFreq Digipeater
String suffix = thirdParty ? ":}" : ":";
String packetToRepeat = packet.substring(0, packet.indexOf(suffix));
@@ -73,7 +73,7 @@ namespace DIGI_Utils {
}
}
String generateDigiRepeatedPacket(const String& packet, bool thirdParty){
String generateDigipeatedPacket(const String& packet, bool thirdParty){
String temp;
if (thirdParty) { // only header is used
const String& header = packet.substring(0, packet.indexOf(":}"));
@@ -117,46 +117,44 @@ namespace DIGI_Utils {
}
void processLoRaPacket(const String& packet) {
if (packet != "") {
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1)) {
bool thirdPartyPacket = false;
String temp, Sender;
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 (packet.indexOf("NOGATE") == -1) {
bool thirdPartyPacket = false;
String temp, Sender;
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 (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);
Utils::typeOfPacket(temp, 2); // Digi
bool queryMessage = false;
if (temp.indexOf("::") > 10) { // it's a message
String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2);
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
if (Addressee == Config.callsign) { // it's a message for me!
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
}
if (STATION_Utils::check25SegBuffer(Sender, temp.substring(temp.indexOf(":") + 2)) || Config.lowPowerMode) {
STATION_Utils::updateLastHeard(Sender);
Utils::typeOfPacket(temp, 2); // Digi
bool queryMessage = false;
if (temp.indexOf("::") > 10) { // it's a message
String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2);
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
if (Addressee == Config.callsign) { // it's a message for me!
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
}
if (!queryMessage) {
String loraPacket = generateDigiRepeatedPacket(packet.substring(3), thirdPartyPacket);
if (loraPacket != "") {
if (Config.lowPowerMode) {
LoRa_Utils::sendNewPacket(loraPacket);
} else {
STATION_Utils::addToOutputPacketBuffer(loraPacket);
}
displayToggle(true);
lastScreenOn = millis();
}
if (!queryMessage) {
String loraPacket = generateDigipeatedPacket(packet.substring(3), thirdPartyPacket);
if (loraPacket != "") {
if (Config.lowPowerMode) {
LoRa_Utils::sendNewPacket(loraPacket);
} else {
STATION_Utils::addToOutputPacketBuffer(loraPacket);
}
displayToggle(true);
lastScreenOn = millis();
}
}
}

View File

@@ -1,6 +1,6 @@
#include <Wire.h>
#include "configuration.h"
#include "boards_pinout.h"
#include "board_pinout.h"
#include "display.h"
@@ -9,25 +9,37 @@
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite sprite = TFT_eSprite(&tft);
#ifdef HELTEC_WIRELESS_TRACKER
#define bigSizeFont 2.5
#define smallSizeFont 1.5
#define lineSpacing 12
#define bigSizeFont 2
#define smallSizeFont 1
#define lineSpacing 10
#endif
#if defined(TTGO_T_DECK_GPS) || defined(TTGO_T_DECK_PLUS)
#define bigSizeFont 5
#define smallSizeFont 2
#define lineSpacing 25
#endif
uint16_t redColor = 0xc8a2;
#else
#if HAS_EPAPER
//
#ifdef HAS_EPAPER
#include <heltec-eink-modules.h>
#include "Fonts/FreeSansBold9pt7b.h"
EInkDisplay_WirelessPaperV1_1 display;
String lastEpaperText;
#else
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#if defined(HELTEC_V3) || defined(HELTEC_WS)
#define OLED_DISPLAY_HAS_RST_PIN
#endif
#ifdef HELTEC_WSL_V3_DISPLAY
Adafruit_SSD1306 display(128, 64, &Wire1, OLED_RST);
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
#include <Adafruit_SH110X.h>
Adafruit_SH1106G display(128, 64, &Wire, OLED_RST);
#else
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);
#include <Adafruit_SSD1306.h>
#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
@@ -35,16 +47,8 @@
extern Configuration Config;
String oldHeader, oldFirstLine, oldSecondLine, oldThirdLine, oldFourthLine, oldFifthLine, oldSixthLine;
bool displayFound = false;
void cleanTFT() {
#ifdef HAS_TFT
tft.fillScreen(TFT_BLACK);
#endif
}
void displaySetup() {
#ifdef HAS_DISPLAY
delay(500);
@@ -56,11 +60,20 @@ void displaySetup() {
} else {
tft.setRotation(1);
}
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);
tft.setTextFont(0);
tft.fillScreen(TFT_BLACK);
#if defined(TTGO_T_DECK_GPS) || defined(TTGO_T_DECK_PLUS)
sprite.createSprite(320,240);
#else
sprite.createSprite(160,80);
#endif
#else
#if HAS_EPAPER
//
#ifdef HAS_EPAPER
display.landscape();
display.printCenter("LoRa APRS iGate Initialising...");
display.update();
#else
#ifdef OLED_DISPLAY_HAS_RST_PIN
pinMode(OLED_RST, OUTPUT);
@@ -69,19 +82,30 @@ void displaySetup() {
digitalWrite(OLED_RST, HIGH);
#endif
if(display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
displayFound = true;
if (Config.display.turn180) {
display.setRotation(2);
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
if (!display.begin(0x3c, false)) {
displayFound = true;
if (Config.display.turn180) display.setRotation(2);
display.clearDisplay();
display.setTextColor(SH110X_WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.setContrast(1);
display.display();
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
}
#else
if(display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
displayFound = true;
if (Config.display.turn180) display.setRotation(2);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
}
#endif
#endif
#endif
delay(1000);
@@ -94,76 +118,81 @@ void displayToggle(bool toggle) {
#ifdef HAS_TFT
digitalWrite(TFT_BL, HIGH);
#else
#if HAS_EPAPER
// ... to be continued
#ifdef HAS_EPAPER
display.printCenter("EPAPER Display Disabled by toggle...");
display.update();
#else
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYON);
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
if (displayFound) display.oled_command(SH110X_DISPLAYON);
#else
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYON);
#endif
#endif
#endif
} else {
#ifdef HAS_TFT
digitalWrite(TFT_BL, LOW);
#else
#if HAS_EPAPER
// ... to be continued
#ifdef HAS_EPAPER
display.printCenter("Enabled EPAPER Display...");
display.update();
#else
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYOFF);
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
if (displayFound) display.oled_command(SH110X_DISPLAYOFF);
#else
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYOFF);
#endif
#endif
#endif
}
#endif
}
bool shouldCleanTFT(const String& header, const String& line1, const String& line2, const String& line3) {
if (oldHeader != header || oldFirstLine != line1 || oldSecondLine != line2 || oldThirdLine != line3) {
oldHeader = header;
oldFirstLine = line1;
oldSecondLine = line2;
oldThirdLine = line3;
return true;
} else {
return false;
}
}
bool shouldCleanTFT(const String& header, const String& line1, const String& line2, const String& line3, const String& line4, const String& line5, const String& line6) {
if (oldHeader != header || oldFirstLine != line1 || oldSecondLine != line2 || oldThirdLine != line3 || oldFourthLine != line4 || oldFifthLine != line5 || oldSixthLine != line6) {
oldHeader = header;
oldFirstLine = line1;
oldSecondLine = line2;
oldThirdLine = line3;
oldFourthLine = line4;
oldFifthLine = line5;
oldSixthLine = line6;
return true;
} else {
return false;
}
}
void displayShow(const String& header, const String& line1, const String& line2, const String& line3, int wait) {
#ifdef HAS_DISPLAY
const String* const lines[] = {&line1, &line2, &line3};
#ifdef HAS_TFT
if (shouldCleanTFT(header, line1, line2, line3)) {
cleanTFT();
}
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.setTextSize(bigSizeFont);
tft.setCursor(0, 0);
tft.print(header);
tft.setTextSize(smallSizeFont);
sprite.fillSprite(TFT_BLACK);
#if defined(HELTEC_WIRELESS_TRACKER)
sprite.fillRect(0, 0, 160, 19, redColor);
#endif
#if defined(TTGO_T_DECK_GPS) || defined(TTGO_T_DECK_PLUS)
sprite.fillRect(0, 0, 320, 43, redColor);
#endif
sprite.setTextFont(0);
sprite.setTextSize(bigSizeFont);
sprite.setTextColor(TFT_WHITE, redColor);
sprite.drawString(header, 3, 3);
sprite.setTextSize(smallSizeFont);
sprite.setTextColor(TFT_WHITE, TFT_BLACK);
for (int i = 0; i < 3; i++) {
tft.setCursor(0, ((lineSpacing * (2 + i)) - 2));
tft.print(*lines[i]);
sprite.drawString(*lines[i], 3, (lineSpacing * (2 + i)) - 2);
}
sprite.pushSprite(0,0);
#else
#ifdef HAS_EPAPER
// ... to be continued
display.clearMemory();
display.setCursor(5,10);
display.setFont(&FreeSansBold9pt7b);
display.println(header);
display.setFont(NULL);
for (int i = 0; i < 3; i++) {
display.setCursor(0, 25 + (14 * i));
display.println(*lines[i]);
}
display.update();
#else
if (displayFound) {
display.clearDisplay();
display.setTextColor(WHITE);
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
display.setTextColor(SH110X_WHITE);
#else
display.setTextColor(WHITE);
#endif
display.setTextSize(1);
display.setCursor(0, 0);
display.println(header);
@@ -171,8 +200,12 @@ void displayShow(const String& header, const String& line1, const String& line2,
display.setCursor(0, 8 + (8 * i));
display.println(*lines[i]);
}
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
display.setContrast(1);
#else
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
#endif
display.display();
}
#endif
@@ -185,25 +218,47 @@ void displayShow(const String& header, const String& line1, const String& line2,
#ifdef HAS_DISPLAY
const String* const lines[] = {&line1, &line2, &line3, &line4, &line5, &line6};
#ifdef HAS_TFT
if (shouldCleanTFT(header, line1, line2, line3, line4, line5, line6)) {
cleanTFT();
}
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.setTextSize(bigSizeFont);
tft.setCursor(0, 0);
tft.print(header);
tft.setTextSize(smallSizeFont);
sprite.fillSprite(TFT_BLACK);
#if defined(HELTEC_WIRELESS_TRACKER)
sprite.fillRect(0, 0, 160, 19, redColor);
#endif
#if defined(TTGO_T_DECK_GPS) || defined(TTGO_T_DECK_PLUS)
sprite.fillRect(0, 0, 320, 43, redColor);
#endif
sprite.setTextFont(0);
sprite.setTextSize(bigSizeFont);
sprite.setTextColor(TFT_WHITE, redColor);
sprite.drawString(header, 3, 3);
sprite.setTextSize(smallSizeFont);
sprite.setTextColor(TFT_WHITE, TFT_BLACK);
for (int i = 0; i < 6; i++) {
tft.setCursor(0, ((lineSpacing * (2 + i)) - 2));
tft.print(*lines[i]);
sprite.drawString(*lines[i], 3, (lineSpacing * (2 + i)) - 2);
}
sprite.pushSprite(0,0);
#else
#ifdef HAS_EPAPER
// ... to be continued
lastEpaperText = header + line1 + line2 + line3 + line4 + line5 + line6;
display.clearMemory();
display.setCursor(5,10);
display.setFont(&FreeSansBold9pt7b);
display.println(header);
display.setFont(NULL);
for (int i = 0; i < 6; i++) {
display.setCursor(0, 25 + (14 * i));
display.println(*lines[i]);
}
display.update();
#else
if (displayFound) {
display.clearDisplay();
display.setTextColor(WHITE);
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
display.setTextColor(SH110X_WHITE);
#else
display.setTextColor(WHITE);
#endif
display.setTextSize(2);
display.setCursor(0, 0);
display.println(header);
@@ -212,8 +267,12 @@ void displayShow(const String& header, const String& line1, const String& line2,
display.setCursor(0, 16 + (8 * i));
display.println(*lines[i]);
}
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
display.setContrast(1);
#else
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
#endif
display.display();
}
#endif

View File

@@ -1,7 +1,7 @@
#include <TinyGPS++.h>
#include <WiFi.h>
#include "configuration.h"
#include "boards_pinout.h"
#include "board_pinout.h"
#include "gps_utils.h"
#include "display.h"
#include "utils.h"
@@ -110,22 +110,30 @@ namespace GPS_Utils {
}
String decodeEncodedGPS(const String& packet) {
const String& GPSPacket = packet.substring(packet.indexOf(":!")+3);
const String& encodedLatitude = GPSPacket.substring(0,4);
const String& encodedLongtitude = GPSPacket.substring(4,8);
const String& comment = GPSPacket.substring(12);
int indexOfExclamation = packet.indexOf(":!");
int indexOfEqual = packet.indexOf(":=");
int Y1 = int(encodedLatitude[0]);
int Y2 = int(encodedLatitude[1]);
int Y3 = int(encodedLatitude[2]);
int Y4 = int(encodedLatitude[3]);
float decodedLatitude = 90.0 - ((((Y1-33) * pow(91,3)) + ((Y2-33) * pow(91,2)) + ((Y3-33) * 91) + Y4-33) / 380926.0);
int X1 = int(encodedLongtitude[0]);
int X2 = int(encodedLongtitude[1]);
int X3 = int(encodedLongtitude[2]);
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);
const uint8_t OFFSET = 3; // Offset for encoded data in the packet
String GPSPacket;
if (indexOfExclamation > 10) {
GPSPacket = packet.substring(indexOfExclamation + OFFSET);
} else if (indexOfEqual > 10) {
GPSPacket = packet.substring(indexOfEqual + OFFSET);
}
String encodedLatitude = GPSPacket.substring(0,4);
int Y1 = encodedLatitude[0] - 33;
int Y2 = encodedLatitude[1] - 33;
int Y3 = encodedLatitude[2] - 33;
int Y4 = encodedLatitude[3] - 33;
float decodedLatitude = 90.0 - (((Y1 * pow(91,3)) + (Y2 * pow(91,2)) + (Y3 * 91) + Y4) / 380926.0);
String encodedLongitude = GPSPacket.substring(4,8);
int X1 = encodedLongitude[0] - 33;
int X2 = encodedLongitude[1] - 33;
int X3 = encodedLongitude[2] - 33;
int X4 = encodedLongitude[3] - 33;
float decodedLongitude = -180.0 + (((X1 * pow(91,3)) + (X2 * pow(91,2)) + (X3 * 91) + X4) / 190463.0);
distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1);
@@ -136,6 +144,7 @@ namespace GPS_Utils {
decodedGPS += distance;
decodedGPS += "km";
String comment = GPSPacket.substring(12);
if (comment != "") {
decodedGPS += " / ";
decodedGPS += comment;
@@ -144,33 +153,30 @@ namespace GPS_Utils {
}
String getReceivedGPS(const String& packet) {
String infoGPS;
if (packet.indexOf(":!") > 10) {
infoGPS = packet.substring(packet.indexOf(":!") + 2);
} else if (packet.indexOf(":=") > 10) {
infoGPS = packet.substring(packet.indexOf(":=") + 2);
}
const String& Latitude = infoGPS.substring(0,8);
const String& Longitude = infoGPS.substring(9,18);
const String& comment = infoGPS.substring(19);
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));
int indexOfExclamation = packet.indexOf(":!");
int indexOfEqual = packet.indexOf(":=");
int indexOfAt = packet.indexOf(":@");
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));
if (String(Latitude[7]) == "S") {
convertedLatitude = -convertedLatitude;
}
if (String(Longitude[8]) == "W") {
convertedLongitude = -convertedLongitude;
String infoGPS;
if (indexOfExclamation > 10) {
infoGPS = packet.substring(indexOfExclamation + 2);
} else if (indexOfEqual > 10) {
infoGPS = packet.substring(indexOfEqual + 2);
} else if (indexOfAt > 10) {
infoGPS = packet.substring(indexOfAt + 9); // 9 = 2+7 (when 7 is timestamp characters)
}
String Latitude = infoGPS.substring(0,8); // First 8 characters are Latitude
float convertedLatitude = Latitude.substring(0,2).toFloat(); // First 2 digits (Degrees)
convertedLatitude += Latitude.substring(2,4).toFloat() / 60; // Next 2 digits (Minutes)
convertedLatitude += Latitude.substring(Latitude.indexOf(".") + 1, Latitude.indexOf(".") + 3).toFloat() / (60*100);
if (Latitude.endsWith("S")) convertedLatitude = -convertedLatitude; // Handle Southern Hemisphere
String Longitude = infoGPS.substring(9,18); // Next 9 characters are Longitude
float convertedLongitude = Longitude.substring(0,3).toFloat(); // First 3 digits (Degrees)
convertedLongitude += Longitude.substring(3,5).toFloat() / 60; // Next 2 digits (Minutes)
convertedLongitude += Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3).toFloat() / (60*100);
if (Longitude.endsWith("W")) convertedLongitude = -convertedLongitude; // Handle Western Hemisphere
distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1);
@@ -181,6 +187,7 @@ namespace GPS_Utils {
decodedGPS += distance;
decodedGPS += "km";
String comment = infoGPS.substring(19);
if (comment != "") {
decodedGPS += " / ";
decodedGPS += comment;
@@ -189,21 +196,30 @@ namespace GPS_Utils {
}
String getDistanceAndComment(const String& packet) {
uint8_t encodedBytePosition = 0;
if (packet.indexOf(":!") > 10) {
encodedBytePosition = packet.indexOf(":!") + 14;
}
if (packet.indexOf(":=") > 10) {
encodedBytePosition = packet.indexOf(":=") + 14;
}
if (encodedBytePosition != 0) {
if (String(packet[encodedBytePosition]) == "G" || String(packet[encodedBytePosition]) == "Q" || String(packet[encodedBytePosition]) == "[" || String(packet[encodedBytePosition]) == "H") {
return decodeEncodedGPS(packet);
} else {
return getReceivedGPS(packet);
}
int indexOfAt = packet.indexOf(":@");
if (indexOfAt > 10) {
return getReceivedGPS(packet);
} else {
return " _ / _ / _ ";
const uint8_t ENCODED_BYTE_OFFSET = 14; // Offset for encoded data in the packet
int indexOfExclamation = packet.indexOf(":!");
int indexOfEqual = packet.indexOf(":=");
uint8_t encodedBytePosition = 0;
if (indexOfExclamation > 10) { // Determine the position where encoded data starts
encodedBytePosition = indexOfExclamation + ENCODED_BYTE_OFFSET;
} else if (indexOfEqual > 10) {
encodedBytePosition = indexOfEqual + ENCODED_BYTE_OFFSET;
}
if (encodedBytePosition != 0) {
char currentChar = packet[encodedBytePosition];
if (currentChar == 'G' || currentChar == 'Q' || currentChar == '[' || currentChar == 'H' || currentChar == 'X') {
return decodeEncodedGPS(packet); // If valid encoded data position is found, decode it
} else {
return getReceivedGPS(packet);
}
} else {
return " _ / _ / _ ";
}
}
}

View File

@@ -1,6 +1,7 @@
#include <Arduino.h>
#include "kiss_protocol.h"
bool validateTNC2Frame(const String& tnc2FormattedFrame) {
return (tnc2FormattedFrame.indexOf(':') != -1) && (tnc2FormattedFrame.indexOf('>') != -1);
}

View File

@@ -2,12 +2,14 @@
#include <WiFi.h>
#include "configuration.h"
#include "aprs_is_utils.h"
#include "boards_pinout.h"
#include "station_utils.h"
#include "board_pinout.h"
#include "syslog_utils.h"
#include "ntp_utils.h"
#include "display.h"
#include "utils.h"
extern Configuration Config;
extern uint32_t lastRxTime;
@@ -40,6 +42,7 @@ bool transmitFlag = true;
int rssi, freqError;
float snr;
namespace LoRa_Utils {
void setFlag(void) {
@@ -138,7 +141,7 @@ namespace LoRa_Utils {
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
SYSLOG_Utils::log(3, newPacket, 0, 0.0, 0); // TX
}
Utils::print("---> LoRa Packet Tx : ");
Utils::print("---> LoRa Packet Tx : ");
Utils::println(newPacket);
} else {
Utils::print(F("failed, code "));
@@ -181,30 +184,36 @@ namespace LoRa_Utils {
int state = radio.readData(packet);
if (state == RADIOLIB_ERR_NONE) {
if (packet != "") {
rssi = radio.getRSSI();
snr = radio.getSNR();
freqError = radio.getFrequencyError();
Utils::println("<--- LoRa Packet Rx : " + packet.substring(3));
Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
if (!Config.lowPowerMode && !Config.digi.ecoMode) {
if (receivedPackets.size() >= 10) {
receivedPackets.erase(receivedPackets.begin());
String sender = packet.substring(3, packet.indexOf(">"));
if (packet.substring(0,3) == "\x3c\xff\x01" && !STATION_Utils::isBlacklisted(sender)){ // avoid processing BlackListed stations
rssi = radio.getRSSI();
snr = radio.getSNR();
freqError = radio.getFrequencyError();
Utils::println("<--- LoRa Packet Rx : " + packet.substring(3));
Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
if (!Config.lowPowerMode && !Config.digi.ecoMode) {
if (receivedPackets.size() >= 10) {
receivedPackets.erase(receivedPackets.begin());
}
ReceivedPacket receivedPacket;
receivedPacket.rxTime = NTP_Utils::getFormatedTime();
receivedPacket.packet = packet.substring(3);
receivedPacket.RSSI = rssi;
receivedPacket.SNR = snr;
receivedPackets.push_back(receivedPacket);
}
ReceivedPacket receivedPacket;
receivedPacket.rxTime = NTP_Utils::getFormatedTime();
receivedPacket.packet = packet.substring(3);
receivedPacket.RSSI = rssi;
receivedPacket.SNR = snr;
receivedPackets.push_back(receivedPacket);
}
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX
}
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX
}
} else {
packet = "";
}
lastRxTime = millis();
return packet;
}
}
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
rssi = radio.getRSSI();
snr = radio.getSNR();

View File

@@ -5,6 +5,7 @@
#include "ota_utils.h"
#include "display.h"
extern Configuration Config;
extern uint32_t lastScreenOn;
extern bool isUpdatingOTA;
@@ -48,13 +49,13 @@ namespace OTA_Utils {
void onOTAEnd(bool success) {
displayToggle(true);
lastScreenOn = millis();
if (success) {
Serial.println("OTA update finished successfully!");
displayShow("", "", " OTA update success!", "", " Rebooting ...", "", "", 4000);
} else {
Serial.println("There was an error during OTA update!");
displayShow("", "", " OTA update fail!", "", "", "", "", 4000);
}
String statusMessage = success ? "OTA update success!" : "OTA update fail!";
String rebootMessage = success ? "Rebooting ..." : "";
Serial.println(success ? "OTA update finished successfully!" : "There was an error during OTA update!");
displayShow("", "", statusMessage, "", rebootMessage, "", "", 4000);
isUpdatingOTA = false;
}

View File

@@ -1,12 +1,20 @@
#include "configuration.h"
#include "battery_utils.h"
#include "boards_pinout.h"
#include "board_pinout.h"
#include "power_utils.h"
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
#define I2C_SDA 21
#define I2C_SCL 22
#define IRQ_PIN 35
#ifdef TTGO_T_Beam_S3_SUPREME_V3
#define I2C0_SDA 17
#define I2C0_SCL 18
#define I2C1_SDA 42
#define I2C1_SCL 41
#define IRQ_PIN 40
#else
#define I2C_SDA 21
#define I2C_SCL 22
#define IRQ_PIN 35
#endif
#endif
#ifdef HAS_AXP192
@@ -54,8 +62,13 @@ namespace POWER_Utils {
#endif
#ifdef HAS_AXP2101
#ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.setALDO4Voltage(3300);
PMU.enableALDO4();
#else
PMU.setALDO3Voltage(3300);
PMU.enableALDO3();
#endif
#endif
#ifdef HELTEC_WIRELESS_TRACKER
digitalWrite(VEXT_CTRL, HIGH);
@@ -69,7 +82,11 @@ namespace POWER_Utils {
#endif
#ifdef HAS_AXP2101
PMU.disableALDO3();
#ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.disableALDO4();
#else
PMU.disableALDO3();
#endif
#endif
#ifdef HELTEC_WIRELESS_TRACKER
digitalWrite(VEXT_CTRL, LOW);
@@ -83,8 +100,13 @@ namespace POWER_Utils {
PMU.enableLDO2();
#endif
#ifdef HAS_AXP2101
PMU.setALDO2Voltage(3300);
PMU.enableALDO2();
#ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.setALDO3Voltage(3300);
PMU.enableALDO3();
#else
PMU.setALDO2Voltage(3300);
PMU.enableALDO2();
#endif
#endif
}
@@ -93,7 +115,11 @@ namespace POWER_Utils {
PMU.disableLDO2();
#endif
#ifdef HAS_AXP2101
PMU.disableALDO2();
#ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.disableALDO3();
#else
PMU.disableALDO2();
#endif
#endif
}
@@ -111,20 +137,29 @@ namespace POWER_Utils {
}
return result;
#elif defined(HAS_AXP2101)
bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
#ifdef TTGO_T_Beam_S3_SUPREME_V3
bool result = PMU.begin(Wire1, AXP2101_SLAVE_ADDRESS, I2C1_SDA, I2C1_SCL);
#else
bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
#endif
if (result) {
PMU.disableDC2();
PMU.disableDC3();
PMU.disableDC4();
PMU.disableDC5();
PMU.disableALDO1();
PMU.disableALDO4();
#ifndef TTGO_T_Beam_S3_SUPREME_V3
PMU.disableALDO1();
PMU.disableALDO4();
#endif
PMU.disableBLDO1();
PMU.disableBLDO2();
PMU.disableDLDO1();
PMU.disableDLDO2();
PMU.setDC1Voltage(3300);
PMU.enableDC1();
#ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.setALDO1Voltage(3300);
#endif
PMU.setButtonBatteryChargeVoltage(3300);
PMU.enableButtonBatteryCharge();
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
@@ -152,8 +187,16 @@ namespace POWER_Utils {
#endif
#ifdef HAS_AXP2101
Wire.begin(SDA, SCL);
if (begin(Wire)) {
bool beginStatus = false;
#ifdef TTGO_T_Beam_S3_SUPREME_V3
Wire1.begin(I2C1_SDA, I2C1_SCL);
Wire.begin(I2C0_SDA, I2C0_SCL);
if (begin(Wire1)) beginStatus = true;
#else
Wire.begin(SDA, SCL);
if (begin(Wire)) beginStatus = true;
#endif
if (beginStatus) {
Serial.println("AXP2101 init done!");
} else {
Serial.println("AXP2101 init failed!");
@@ -181,10 +224,10 @@ namespace POWER_Utils {
#ifdef VEXT_CTRL
pinMode(VEXT_CTRL,OUTPUT); // GPS + TFT on HELTEC Wireless_Tracker and only for Oled in HELTEC V3
#ifndef HELTEC_WSL_V3
#if defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_V3)
digitalWrite(VEXT_CTRL, HIGH);
#endif
#ifdef HELTEC_WP
#if defined(HELTEC_WP) || defined(HELTEC_WS) || defined(HELTEC_V3_2)
digitalWrite(VEXT_CTRL, LOW);
#endif
#endif
@@ -201,13 +244,29 @@ namespace POWER_Utils {
Wire.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WP) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
Wire1.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WS) || defined(LIGHTGATEWAY_1_0) || defined(TTGO_LORA32_T3S3_V1_2)
#if defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WS) || defined(LIGHTGATEWAY_1_0) || defined(TTGO_LORA32_T3S3_V1_2) || defined(HELTEC_V2)
Wire.begin(OLED_SDA, OLED_SCL);
#endif
#if defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WP) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
Wire1.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
#endif
#if defined(TTGO_T_DECK_GPS) || defined(TTGO_T_DECK_PLUS)
pinMode(BOARD_POWERON, OUTPUT);
digitalWrite(BOARD_POWERON, HIGH);
pinMode(BOARD_SDCARD_CS, OUTPUT);
pinMode(RADIO_CS_PIN, OUTPUT);
pinMode(TFT_CS, OUTPUT);
digitalWrite(BOARD_SDCARD_CS, HIGH);
digitalWrite(RADIO_CS_PIN, HIGH);
digitalWrite(TFT_CS, HIGH);
delay(500);
Wire.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
#endif
delay(1000);
BATTERY_Utils::setup();

View File

@@ -1,4 +1,5 @@
#include "configuration.h"
#include "battery_utils.h"
#include "station_utils.h"
#include "query_utils.h"
#include "lora_utils.h"
@@ -10,6 +11,8 @@ extern String versionDate;
extern int rssi;
extern float snr;
extern int freqError;
extern bool shouldSleepLowVoltage;
extern bool saveNewDigiEcoModeConfig;
namespace QUERY_Utils {
@@ -19,9 +22,9 @@ namespace QUERY_Utils {
String queryQuestion = query;
queryQuestion.toUpperCase();
if (queryQuestion == "?APRS?" || queryQuestion == "H" || queryQuestion == "HELP" || queryQuestion=="?") {
answer.concat("?APRSV ?APRSP ?APRSL ?APRSH ?WHERE callsign");
answer.concat("?APRSV ?APRSP ?APRSL ?APRSSSR ?EM=? ?TX=? "); // ?APRSH ?WHERE callsign
} else if (queryQuestion == "?APRSV") {
answer.concat("CA2RXU_LoRa_iGate 2.0 v");
answer.concat("CA2RXU_LoRa_iGate 2.3 v");
answer.concat(versionDate);
} else if (queryQuestion == "?APRSP") {
answer.concat("iGate QTH: ");
@@ -43,25 +46,69 @@ namespace QUERY_Utils {
char signalData[35];
snprintf(signalData, sizeof(signalData), " %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
answer.concat(signalData);
} else if (queryQuestion.indexOf("?APRSH") == 0) {
} /*else if (queryQuestion.indexOf("?APRSH") == 0) {
// sacar callsign despues de ?APRSH
Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?");
answer.concat("?APRSH on development 73!");
} else if (queryQuestion.indexOf("?WHERE") == 0) {
} *//*else if (queryQuestion.indexOf("?WHERE") == 0) {
// agregar callsign para completar donde esta X callsign --> posicion
Serial.println("estaciones escuchadas directo (ultimos 30 min)");
answer.concat("?WHERE on development 73!");
} else if (queryQuestion.indexOf("?APRSEEM") == 0 && Config.digi.ecoMode == true) { // Exit DigiRepeater EcoMode
answer = "DigiEcoMode:Stop";
Config.digi.ecoMode = false;
Config.display.alwaysOn = true;
Config.display.timeout = 10;
} else if (queryQuestion.indexOf("?APRSSEM") == 0 && Config.digi.ecoMode == false) { // Start DigiRepeater EcoMode
answer = "DigiEcoMode:Start";
Config.digi.ecoMode = true;
} else if (queryQuestion.indexOf("?APRSEMS") == 0) { // DigiRepeater EcoMode Status
answer = (Config.digi.ecoMode) ? "DigiEcoMode:ON" : "DigiEcoMode:OFF";
} */
else if (STATION_Utils::isManager(station) && (!queryFromAPRSIS || !Config.remoteManagement.rfOnly)) {
if (queryQuestion.indexOf("?EM=OFF") == 0) {
if ((Config.digi.mode == 2 || Config.digi.mode == 3) && Config.loramodule.txActive && Config.loramodule.rxActive && !Config.aprs_is.active) {
if (Config.digi.ecoMode) { // Exit Digipeater EcoMode
answer = "DigiEcoMode:OFF";
Config.digi.ecoMode = false;
Config.display.alwaysOn = true;
Config.display.timeout = 10;
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
saveNewDigiEcoModeConfig = true;
} else {
answer = "DigiEcoMode was OFF";
}
} else {
answer = "DigiEcoMode control not possible";
}
} else if (queryQuestion.indexOf("?EM=ON") == 0) {
if ((Config.digi.mode == 2 || Config.digi.mode == 3) && Config.loramodule.txActive && Config.loramodule.rxActive && !Config.aprs_is.active) {
if (!Config.digi.ecoMode) { // Start Digipeater EcoMode
answer = "DigiEcoMode:ON";
Config.digi.ecoMode = true;
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
saveNewDigiEcoModeConfig = true;
} else {
answer = "DigiEcoMode was ON";
}
} else {
answer = "DigiEcoMode control not possible";
}
} else if (queryQuestion.indexOf("?EM=?") == 0) { // Digipeater EcoMode Status
answer = (Config.digi.ecoMode) ? "DigiEcoMode:ON" : "DigiEcoMode:OFF";
} else if (queryQuestion.indexOf("?TX=ON") == 0) {
if (Config.loramodule.txActive) {
answer = "TX was ON";
} else {
Config.loramodule.txActive = true;
answer = "TX=ON";
}
} else if (queryQuestion.indexOf("?TX=OFF") == 0) {
if (!Config.loramodule.txActive) {
answer = "TX was OFF";
} else {
Config.loramodule.txActive = false;
answer = "TX=OFF";
}
} else if (queryQuestion.indexOf("?TX=?") == 0) {
answer = (Config.loramodule.txActive) ? "TX=ON" : "TX=OFF";
} else if (queryQuestion.indexOf("?COMMIT") == 0) { // saving for next reboot
answer = "New Config Saved";
Config.writeFile();
}
}
if (answer == "") return "";
String queryAnswer = Config.callsign;
queryAnswer += ">APLRG1";
@@ -83,6 +130,11 @@ namespace QUERY_Utils {
queryAnswer += processedStation;
queryAnswer += ":";
queryAnswer += answer;
queryAnswer += " *";
queryAnswer += char(random(97, 123));
queryAnswer += char(random(97, 123));
queryAnswer += "*";
return queryAnswer;
}

View File

@@ -7,6 +7,7 @@
#include "utils.h"
#include <vector>
extern Configuration Config;
extern uint32_t lastRxTime;
extern String fourthLine;
@@ -16,10 +17,87 @@ uint32_t lastTxTime = millis();
std::vector<LastHeardStation> lastHeardStations;
std::vector<String> outputPacketBuffer;
std::vector<Packet25SegBuffer> packet25SegBuffer;
std::vector<String> blacklist;
std::vector<String> managers;
std::vector<LastHeardStation> lastHeardObjects;
bool saveNewDigiEcoModeConfig = false;
namespace STATION_Utils {
std::vector<String> loadCallSignList(const String& list) {
std::vector<String> loadedList;
String callsigns = list;
callsigns.trim();
while (callsigns.length() > 0) { // != ""
int spaceIndex = callsigns.indexOf(" ");
if (spaceIndex == -1) { // No more spaces, add the last part
loadedList.push_back(callsigns);
break;
}
loadedList.push_back(callsigns.substring(0, spaceIndex));
callsigns = callsigns.substring(spaceIndex + 1);
callsigns.trim(); // Trim in case of multiple spaces
}
return loadedList;
}
void loadBlacklist() {
blacklist = loadCallSignList(Config.blacklist);
}
void loadManagers() {
managers = loadCallSignList(Config.remoteManagement.managers);
}
bool checkCallsignList(const std::vector<String>& list, const String& callsign) {
for (int i = 0; i < list.size(); i++) {
int wildcardIndex = list[i].indexOf("*");
if (wildcardIndex >= 0) {
String wildcard = list[i].substring(0, wildcardIndex);
if (callsign.startsWith(wildcard)) return true;
} else {
if (list[i] == callsign) return true;
}
}
return false;
}
bool isBlacklisted(const String& callsign) {
return checkCallsignList(blacklist, callsign);
}
bool isManager(const String& callsign) {
return checkCallsignList(managers, callsign);
}
void cleanObjectsHeard() {
for (auto it = lastHeardObjects.begin(); it != lastHeardObjects.end(); ) {
if (millis() - it->lastHeardTime >= 9.75 * 60 * 1000) { // 9.75 = 9min 45secs
it = lastHeardObjects.erase(it); // erase() returns the next valid iterator
} else {
++it; // Only increment if not erasing
}
}
}
bool checkObjectTime(const String& packet) {
cleanObjectsHeard();
int objectIDIndex = packet.indexOf(":;");
String object = packet.substring(objectIDIndex + 2, objectIDIndex + 11);
object.trim();
for (int i = 0; i < lastHeardObjects.size(); i++) { // Check if i should Tx object
if (lastHeardObjects[i].station == object) return false;
}
lastHeardObjects.emplace_back(LastHeardStation{millis(), object}); // Add new object and Tx
return true;
}
void deleteNotHeard() {
std::vector<LastHeardStation> lastHeardStation_temp;
for (int i = 0; i < lastHeardStations.size(); i++) {
@@ -41,22 +119,11 @@ namespace STATION_Utils {
if (lastHeardStations[i].station == station) {
lastHeardStations[i].lastHeardTime = millis();
stationHeard = true;
break;
}
}
if (!stationHeard) {
LastHeardStation lastStation;
lastStation.lastHeardTime = millis();
lastStation.station = station;
lastHeardStations.push_back(lastStation);
}
fourthLine = "Stations (";
fourthLine += String(Config.rememberStationTime);
fourthLine += "min) = ";
if (lastHeardStations.size() < 10) {
fourthLine += " ";
}
fourthLine += String(lastHeardStations.size());
if (!stationHeard) lastHeardStations.emplace_back(LastHeardStation{millis(), station});
Utils::activeStations();
}
bool wasHeard(const String& station) {
@@ -67,50 +134,30 @@ namespace STATION_Utils {
return true;
}
}
Utils::println(" ---> Station not Heard for last 30 min (Not Tx)\n");
Utils::println(" ---> Station not Heard in " + String(Config.rememberStationTime) + " min: No Tx");
return false;
}
void clean25SegBuffer() {
if (!packet25SegBuffer.empty()) {
if ((millis() - packet25SegBuffer[0].receivedTime) > 25 * 1000) {
packet25SegBuffer.erase(packet25SegBuffer.begin());
}
}
if (!packet25SegBuffer.empty() && (millis() - packet25SegBuffer[0].receivedTime) > 25 * 1000) packet25SegBuffer.erase(packet25SegBuffer.begin());
}
bool check25SegBuffer(const String& station, const String& textMessage) {
bool shouldBeIgnored = false;
if (!packet25SegBuffer.empty()) {
for (int i = 0; i < packet25SegBuffer.size(); i++) {
if (packet25SegBuffer[i].station == station && packet25SegBuffer[i].payload == textMessage) {
shouldBeIgnored = true;
}
if (packet25SegBuffer[i].station == station && packet25SegBuffer[i].payload == textMessage) return false;
}
}
if (shouldBeIgnored) {
return false;
} else {
Packet25SegBuffer packet;
packet.receivedTime = millis();
packet.station = station;
packet.payload = textMessage;
packet25SegBuffer.push_back(packet);
return true;
}
packet25SegBuffer.emplace_back(Packet25SegBuffer{millis(), station, textMessage});
return true;
}
void processOutputPacketBuffer() {
int timeToWait = 3 * 1000; // 3 segs between packet Tx and also Rx ???
uint32_t lastRx = millis() - lastRxTime;
uint32_t lastTx = millis() - lastTxTime;
bool saveNewDigiEcoModeConfig = false;
if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) {
LoRa_Utils::sendNewPacket(outputPacketBuffer[0]);
if (outputPacketBuffer[0].indexOf("DigiEcoMode:Start") != -1 || outputPacketBuffer[0].indexOf("DigiEcoMode:Stop") != -1) {
saveNewDigiEcoModeConfig = true;
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
}
outputPacketBuffer.erase(outputPacketBuffer.begin());
lastTxTime = millis();
}
@@ -122,7 +169,9 @@ namespace STATION_Utils {
}
}
if (saveNewDigiEcoModeConfig) {
setCpuFrequencyMhz(80);
Config.writeFile();
delay(1000);
displayToggle(false);
ESP.restart();
}

View File

@@ -4,6 +4,7 @@
#include "syslog_utils.h"
#include "gps_utils.h"
extern Configuration Config;
WiFiUDP udpClient;
@@ -20,6 +21,10 @@ namespace SYSLOG_Utils {
char signalData[35];
snprintf(signalData, sizeof(signalData), " / %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
int colonIndex = packet.indexOf(":");
char nextChar = packet[colonIndex + 1];
String sender = packet.substring(3, packet.indexOf(">"));
switch (type) {
case 0: // CRC
syslogPacket.concat("CRC / CRC-ERROR / ");
@@ -28,59 +33,57 @@ namespace SYSLOG_Utils {
break;
case 1: // RX
syslogPacket.concat("RX / ");
if (packet.indexOf("::") > 10) {
if (nextChar == ':') {
syslogPacket.concat("MESSAGE / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(" ---> "); syslogPacket.concat(packet.substring(packet.indexOf("::") + 2));
syslogPacket.concat(signalData);
} else if (packet.indexOf(":!") > 10 || packet.indexOf(":=") > 10) {
syslogPacket.concat(sender);
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(colonIndex + 2));
} else if (nextChar == '!' || nextChar == '=' || nextChar == '@') {
syslogPacket.concat("GPS / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(sender);
syslogPacket.concat(" / ");
int greaterThanIndex = packet.indexOf(">");
if (packet.indexOf("WIDE1-1") > 10) {
syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, packet.indexOf(",")));
syslogPacket.concat(packet.substring(greaterThanIndex + 1, packet.indexOf(",")));
syslogPacket.concat(" / WIDE1-1");
} else {
syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, packet.indexOf(":")));
syslogPacket.concat(packet.substring(greaterThanIndex + 1, colonIndex));
syslogPacket.concat(" / -");
}
syslogPacket.concat(signalData);
syslogPacket.concat(" / ");
syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet));
} else if (packet.indexOf(":>") > 10) {
} else if (nextChar == '>') {
syslogPacket.concat("STATUS / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(sender);
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":>") + 2));
syslogPacket.concat(signalData);
} else if (packet.indexOf(":`") > 10) {
syslogPacket.concat(packet.substring(colonIndex + 2));
} else if (nextChar == '`') {
syslogPacket.concat("MIC-E / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(sender);
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":`") + 2));
syslogPacket.concat(signalData);
syslogPacket.concat(packet.substring(colonIndex + 2));
} else if (nextChar == ';') {
syslogPacket.concat("OBJECT / ");
syslogPacket.concat(sender);
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(colonIndex + 2));
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) {
syslogPacket.concat("TELEMETRY / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(sender);
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":T#") + 3));
syslogPacket.concat(signalData);
} else if (packet.indexOf(":;") > 10) {
syslogPacket.concat("OBJECT / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":;") + 2));
syslogPacket.concat(signalData);
} else {
syslogPacket.concat(packet);
syslogPacket.concat(signalData);
}
syslogPacket.concat(signalData);
if (nextChar == '!' || nextChar == '=' || nextChar == '@') {
syslogPacket.concat(" / ");
syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet));
}
break;
case 2: // APRSIS TX
syslogPacket.concat("APRSIS TX / ");
if (packet.indexOf(":>") > 10) {
if (nextChar == '>') {
syslogPacket.concat("StartUp_Status / ");
syslogPacket.concat(packet.substring(packet.indexOf(":>") + 2));
syslogPacket.concat(packet.substring(colonIndex + 2));
} else {
syslogPacket.concat("QUERY / ");
syslogPacket.concat(packet);
@@ -91,11 +94,11 @@ namespace SYSLOG_Utils {
if (packet.indexOf("RFONLY") > 10) {
syslogPacket.concat("RFONLY / ");
syslogPacket.concat(packet);
} else if (packet.indexOf("::") > 10) {
} else if (nextChar == ':') {
syslogPacket.concat("MESSAGE / ");
syslogPacket.concat(packet.substring(0,packet.indexOf(">")));
syslogPacket.concat(sender);
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf("::") + 2));
syslogPacket.concat(packet.substring(colonIndex + 2));
} else {
syslogPacket.concat(packet);
}

View File

@@ -5,6 +5,7 @@
#include "station_utils.h"
#include "utils.h"
extern Configuration Config;
#define MAX_CLIENTS 4
@@ -19,6 +20,7 @@ WiFiServer tncServer(TNC_PORT);
String inputServerBuffer[INPUT_BUFFER_SIZE];
String inputSerialBuffer = "";
namespace TNC_Utils {
void setup() {
@@ -43,16 +45,9 @@ namespace TNC_Utils {
}
void handleInputData(char character, int bufferIndex) {
String* data;
if (bufferIndex == -1) {
data = &inputSerialBuffer;
} else {
data = &inputServerBuffer[bufferIndex];
}
if (data->length() == 0 && character != (char)FEND) {
return;
}
String* data = (bufferIndex == -1) ? &inputSerialBuffer : &inputServerBuffer[bufferIndex];
if (data->length() == 0 && character != (char)FEND) return;
data->concat(character);
if (character == (char)FEND && data->length() > 3) {

View File

@@ -4,7 +4,7 @@
#include "station_utils.h"
#include "battery_utils.h"
#include "aprs_is_utils.h"
#include "boards_pinout.h"
#include "board_pinout.h"
#include "syslog_utils.h"
#include "A7670_utils.h"
#include "lora_utils.h"
@@ -37,12 +37,13 @@ extern int wxModuleType;
extern bool backUpDigiMode;
extern bool shouldSleepLowVoltage;
extern bool transmitFlag;
extern bool passcodeValid;
extern std::vector<LastHeardStation> lastHeardStations;
bool statusAfterBoot = true;
bool sendStartTelemetry = true;
bool beaconUpdate = true;
bool beaconUpdate = false;
uint32_t lastBeaconTx = 0;
uint32_t lastScreenOn = millis();
String beaconPacket;
@@ -83,7 +84,7 @@ namespace Utils {
return "- BACKUP DIGI MODE -";
} else {
return "IP : " + String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." + String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]);
}
}
}
void setupDisplay() {
@@ -102,37 +103,36 @@ namespace Utils {
}
void activeStations() {
fourthLine = "Stations (";
fourthLine.concat(String(Config.rememberStationTime));
fourthLine.concat("min) = ");
if (lastHeardStations.size() < 10) {
fourthLine += " ";
}
fourthLine.concat(String(lastHeardStations.size()));
char buffer[30]; // Adjust size as needed
sprintf(buffer, "Stations (%dmin) = %2d", Config.rememberStationTime, lastHeardStations.size());
fourthLine = buffer;
}
void sendInitialTelemetryPackets() {
String sender = Config.callsign;
for (int i = sender.length(); i < 9; i++) {
sender += ' ';
}
char sender[10]; // 9 characters + null terminator
snprintf(sender, sizeof(sender), "%-9s", Config.callsign.c_str()); // Left-align with spaces
String baseAPRSISTelemetryPacket = Config.callsign;
baseAPRSISTelemetryPacket += ">APLRG1,TCPIP,qAC::";
baseAPRSISTelemetryPacket += sender;
baseAPRSISTelemetryPacket += ":";
String baseRFTelemetryPacket = Config.callsign;
baseRFTelemetryPacket += ">APLRG1,WIDE1-1::";
baseRFTelemetryPacket += ">APLRG1";
if (Config.beacon.path.indexOf("WIDE") != -1) {
baseRFTelemetryPacket += ",";
baseRFTelemetryPacket += Config.beacon.path;
}
baseRFTelemetryPacket += "::";
baseRFTelemetryPacket += sender;
baseRFTelemetryPacket += ":";
String telemetryPacket1 = "EQNS.";
if (Config.battery.sendInternalVoltage) {
telemetryPacket1 += "0,0.01,0";
}
if (Config.battery.sendExternalVoltage) {
telemetryPacket1 += String(Config.battery.sendInternalVoltage ? "," : "") + "0,0.02,0";
telemetryPacket1 += String(Config.battery.sendInternalVoltage ? ",0,0.02,0" : "0,0.02,0");
}
String telemetryPacket2 = "UNIT.";
@@ -140,7 +140,7 @@ namespace Utils {
telemetryPacket2 += "VDC";
}
if (Config.battery.sendExternalVoltage) {
telemetryPacket2 += String(Config.battery.sendInternalVoltage ? "," : "") + "VDC";
telemetryPacket2 += String(Config.battery.sendInternalVoltage ? ",VDC" : "VDC");
}
String telemetryPacket3 = "PARM.";
@@ -148,7 +148,7 @@ namespace Utils {
telemetryPacket3 += "V_Batt";
}
if (Config.battery.sendExternalVoltage) {
telemetryPacket3 += String(Config.battery.sendInternalVoltage ? "," : "") + "V_Ext";
telemetryPacket3 += String(Config.battery.sendInternalVoltage ? ",V_Ext" : "V_Ext");
}
if (Config.beacon.sendViaAPRSIS) {
@@ -177,7 +177,7 @@ namespace Utils {
delay(3000);
}
sendStartTelemetry = false;
}
}
void checkBeaconInterval() {
uint32_t lastTx = millis() - lastBeaconTx;
@@ -193,14 +193,17 @@ namespace Utils {
#endif
if (beaconUpdate) {
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
displayToggle(true);
}
if (!Config.display.alwaysOn && Config.display.timeout != 0) displayToggle(true);
if (sendStartTelemetry && Config.battery.sendVoltageAsTelemetry && !Config.wxsensor.active && (Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage)) {
if (sendStartTelemetry &&
Config.battery.sendVoltageAsTelemetry &&
!Config.wxsensor.active &&
(Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) &&
(lastBeaconTx > 0)) {
//(!Config.digi.ecoMode || lastBeaconTx > 0)) {
sendInitialTelemetryPackets();
}
STATION_Utils::deleteNotHeard();
activeStations();
@@ -219,13 +222,10 @@ namespace Utils {
}
#endif
if (Config.wxsensor.active && wxModuleType != 0) {
String sensorData = WX_Utils::readDataSensor();
beaconPacket += sensorData;
secondaryBeaconPacket += sensorData;
} else if (Config.wxsensor.active && wxModuleType == 0) {
beaconPacket += ".../...g...t...";
secondaryBeaconPacket += ".../...g...t...";
if (Config.wxsensor.active) {
const char* sensorData = (wxModuleType == 0) ? ".../...g...t..." : WX_Utils::readDataSensor().c_str();
beaconPacket += sensorData;
secondaryBeaconPacket += sensorData;
}
beaconPacket += Config.beacon.comment;
secondaryBeaconPacket += Config.beacon.comment;
@@ -239,18 +239,21 @@ namespace Utils {
shouldSleepLowVoltage = true;
}
String internalVoltageInfo = String(internalVoltage,2) + "V";
if (Config.battery.sendInternalVoltage) {
sixthLine = " (Batt=";
sixthLine += internalVoltageInfo;
sixthLine += ")";
char internalVoltageInfo[10]; // Enough to hold "xx.xxV\0"
snprintf(internalVoltageInfo, sizeof(internalVoltageInfo), "%.2fV", internalVoltage);
char sixthLineBuffer[25]; // Enough to hold " (Batt=xx.xxV)"
snprintf(sixthLineBuffer, sizeof(sixthLineBuffer), " (Batt=%s)", internalVoltageInfo);
sixthLine = sixthLineBuffer;
if (!Config.battery.sendVoltageAsTelemetry) {
beaconPacket += " Batt=";
beaconPacket += internalVoltageInfo;
secondaryBeaconPacket += " Batt=";
secondaryBeaconPacket += internalVoltageInfo;
}
}
}
}
#endif
@@ -263,18 +266,21 @@ namespace Utils {
shouldSleepLowVoltage = true;
}
String externalVoltageInfo = String(externalVoltage,2) + "V";
if (Config.battery.sendExternalVoltage) {
sixthLine = " (Ext V=";
sixthLine += externalVoltageInfo;
sixthLine += ")";
char externalVoltageInfo[10]; // "xx.xxV\0" (max 7 chars)
snprintf(externalVoltageInfo, sizeof(externalVoltageInfo), "%.2fV", externalVoltage);
char sixthLineBuffer[25]; // Ensure enough space
snprintf(sixthLineBuffer, sizeof(sixthLineBuffer), " (Ext V=%s)", externalVoltageInfo);
sixthLine = sixthLineBuffer;
if (!Config.battery.sendVoltageAsTelemetry) {
beaconPacket += " Ext=";
beaconPacket += externalVoltageInfo;
secondaryBeaconPacket += " Ext=";
secondaryBeaconPacket += externalVoltageInfo;
}
}
}
}
}
#endif
@@ -284,9 +290,9 @@ namespace Utils {
secondaryBeaconPacket += encodedTelemetry;
}
if (Config.aprs_is.active && Config.beacon.sendViaAPRSIS && !backUpDigiMode) {
if (Config.beacon.sendViaAPRSIS && Config.aprs_is.active && passcodeValid && !backUpDigiMode) {
Utils::println("-- Sending Beacon to APRSIS --");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING IGATE BEACON", 0);
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING IGATE BEACON", 0);
seventhLine = " listening...";
#ifdef HAS_A7670
A7670_Utils::uploadToAPRSIS(beaconPacket);
@@ -338,58 +344,49 @@ namespace Utils {
case 1: // APRS-LoRa
fifthLine = "APRS-IS ----> LoRa Tx";
break;
case 2: // Digi
case 2: // Digipeater
fifthLine = "LoRa Rx ----> LoRa Tx";
break;
}
int firstColonIndex = packet.indexOf(":");
char nextChar = packet[firstColonIndex + 1];
for (int i = sender.length(); i < 9; i++) {
sender += " ";
}
sixthLine = sender;
String seventhLineHelper = "RSSI:";
seventhLineHelper += String(rssi);
seventhLineHelper += "dBm SNR: ";
seventhLineHelper += String(snr);
seventhLineHelper += "dBm";
int firstColonIndex = packet.indexOf(":");
if (packet[firstColonIndex + 1] == ':') {
if (nextChar == ':') {
sixthLine += "> MESSAGE";
seventhLine = seventhLineHelper;
} else if (packet[firstColonIndex + 1] == '>') {
} else if (nextChar == '>') {
sixthLine += "> NEW STATUS";
seventhLine = seventhLineHelper;
} else if (packet[firstColonIndex + 1] == '!' || packet[firstColonIndex + 1] == '=' || packet[firstColonIndex + 1] == '@') {
} else if (nextChar == '!' || nextChar == '=' || nextChar == '@') {
sixthLine += "> GPS BEACON";
if (!Config.syslog.active) {
GPS_Utils::getDistanceAndComment(packet); // to be checked!!!
}
if (!Config.syslog.active) GPS_Utils::getDistanceAndComment(packet); // to be checked!!!
seventhLine = "RSSI:";
seventhLine += String(rssi);
seventhLine += "dBm";
if (rssi <= -100) {
seventhLine += " ";
} else {
seventhLine += " ";
}
if (distance.indexOf(".") == 1) {
seventhLine += " ";
}
seventhLine += (rssi <= -100) ? " " : " ";
if (distance.indexOf(".") == 1) seventhLine += " ";
seventhLine += "D:";
seventhLine += distance;
seventhLine += "km";
} else if (packet[firstColonIndex + 1] == '`' || packet[firstColonIndex + 1] == '\'') {
} else if (nextChar == '`' || nextChar == '\'') {
sixthLine += "> MIC-E";
seventhLine = seventhLineHelper;
} else if (packet[firstColonIndex + 1] == ';') {
} else if (nextChar == ';') {
sixthLine += "> OBJECT";
seventhLine = seventhLineHelper;
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) {
sixthLine += "> TELEMETRY";
seventhLine = seventhLineHelper;
} else {
sixthLine += "> ??????????";
seventhLine = seventhLineHelper;
}
if (nextChar != '!' && nextChar != '=' && nextChar != '@') { // Common assignment for non-GPS cases
seventhLine = "RSSI:";
seventhLine += String(rssi);
seventhLine += "dBm SNR: ";
seventhLine += String(snr);
seventhLine += "dBm";
}
}

View File

@@ -5,6 +5,7 @@
#include "display.h"
#include "utils.h"
extern Configuration Config;
extern uint32_t lastBeaconTx;
extern std::vector<ReceivedPacket> receivedPackets;
@@ -34,6 +35,7 @@ extern const unsigned char favicon_data[] asm("_binary_data_embed_favicon_png_gz
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 {
AsyncWebServer server(80);
@@ -136,7 +138,7 @@ namespace WEB_Utils {
Config.beacon.gpsActive = request->hasParam("beacon.gpsActive", true);
Config.beacon.gpsAmbiguity = request->hasParam("beacon.gpsAmbiguity", true);
Config.digi.mode = request->getParam("digi.mode", true)->value().toInt();
Config.digi.ecoMode = request->hasParam("digi.ecoMode", true);
@@ -186,7 +188,7 @@ namespace WEB_Utils {
Config.syslog.server = request->getParam("syslog.server", true)->value();
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);
@@ -205,13 +207,18 @@ namespace WEB_Utils {
Config.personalNote = request->getParam("personalNote", true)->value();
Config.blacklist = request->getParam("blacklist", 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.ntp.gmtCorrection = request->getParam("ntp.gmtCorrection", true)->value().toInt();
Config.ntp.gmtCorrection = request->getParam("ntp.gmtCorrection", true)->value().toFloat();
Config.remoteManagement.managers = request->getParam("remoteManagement.managers", true)->value();
Config.remoteManagement.rfOnly = request->getParam("remoteManagement.rfOnly", true);
Config.writeFile();

View File

@@ -1,10 +1,11 @@
#include <WiFi.h>
#include "configuration.h"
#include "boards_pinout.h"
#include "board_pinout.h"
#include "wifi_utils.h"
#include "display.h"
#include "utils.h"
extern Configuration Config;
extern uint8_t myWiFiAPIndex;

View File

@@ -1,4 +1,6 @@
#include <TinyGPS++.h>
#include "configuration.h"
#include "board_pinout.h"
#include "wx_utils.h"
#include "display.h"
@@ -8,6 +10,9 @@
extern Configuration Config;
extern String fifthLine;
#ifdef HAS_GPS
extern TinyGPSPlus gps;
#endif
int wxModuleType = 0;
uint8_t wxModuleAddress = 0x00;
@@ -16,7 +21,7 @@ float newHum, newTemp, newPress, newGas;
Adafruit_BME280 bme280;
#ifdef HELTEC_V3
#if defined(HELTEC_V3) || defined(HELTEC_V3_2)
Adafruit_BMP280 bmp280(&Wire1);
Adafruit_Si7021 sensor = Adafruit_Si7021();
#else
@@ -26,13 +31,12 @@ Adafruit_Si7021 sensor = Adafruit_Si7021();
#endif
namespace WX_Utils {
void getWxModuleAddres() {
uint8_t err, addr;
for(addr = 1; addr < 0x7F; addr++) {
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
#if defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
Wire1.beginTransmission(addr);
err = Wire1.endTransmission();
#else
@@ -58,7 +62,7 @@ namespace WX_Utils {
if (wxModuleAddress != 0x00) {
bool wxModuleFound = false;
if (wxModuleAddress == 0x76 || wxModuleAddress == 0x77) {
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
#if defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
if (bme280.begin(wxModuleAddress, &Wire1)) {
Serial.println("BME280 sensor found");
wxModuleType = 1;
@@ -115,7 +119,7 @@ namespace WX_Utils {
Serial.println("BMP280 Module init done!");
break;
case 3:
#ifndef HELTEC_V3
#if !defined(HELTEC_V3) && !defined(HELTEC_V3_2)
bme680.setTemperatureOversampling(BME680_OS_1X);
bme680.setHumidityOversampling(BME680_OS_1X);
bme680.setPressureOversampling(BME680_OS_1X);
@@ -125,7 +129,7 @@ namespace WX_Utils {
break;
}
}
}
}
}
}
@@ -195,7 +199,7 @@ namespace WX_Utils {
newHum = 0;
break;
case 3: // BME680
#ifndef HELTEC_V3
#if !defined(HELTEC_V3) && !defined(HELTEC_V3_2)
bme680.performReading();
delay(50);
if (bme680.endReading()) {
@@ -227,13 +231,14 @@ namespace WX_Utils {
humStr = "..";
}
String presStr;
if (wxModuleAddress == 4) {
presStr = ".....";
} else {
presStr = generatePresString(newPress + (Config.wxsensor.heightCorrection/CORRECTION_FACTOR));
}
String presStr = (wxModuleAddress == 4)
? "....."
#ifdef HAS_GPS
: generatePresString(newPress + (gps.altitude.meters() / CORRECTION_FACTOR));
#else
: generatePresString(newPress + (Config.wxsensor.heightCorrection / CORRECTION_FACTOR));
#endif
fifthLine = "BME-> ";
fifthLine += String(int(newTemp + Config.wxsensor.temperatureCorrection));
fifthLine += "C ";

View File

@@ -1,11 +0,0 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html

View File

@@ -0,0 +1,26 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1268
#define RADIO_HAS_XTAL
#define RADIO_SCLK_PIN 6
#define RADIO_MISO_PIN 4
#define RADIO_MOSI_PIN 7
#define RADIO_CS_PIN 5
#define RADIO_DIO1_PIN 3
#define RADIO_RST_PIN -1
#define RADIO_BUSY_PIN 8
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 0
#define OLED_SCL 1
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#endif

View File

@@ -0,0 +1,10 @@
[env:ESP32_C3_OctopusLab_LoRa]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
${common.build_flags}
${common.usb_flags}
-D ESP32_C3_OctopusLab_LoRa
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,31 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1268
#define HAS_1W_LORA
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 12
#define RADIO_BUSY_PIN 14
#define RADIO_RXEN 32
#define RADIO_TXEN 25
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// Aditional Config
#define INTERNAL_LED_PIN 2
#endif

View File

@@ -0,0 +1,8 @@
[env:ESP32_DIY_1W_LoRa]
board = esp32dev
build_flags =
${common.build_flags}
-D ESP32_DIY_1W_LoRa
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,31 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1262
#define HAS_1W_LORA
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 12
#define RADIO_BUSY_PIN 14
#define RADIO_RXEN 32
#define RADIO_TXEN 25
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// Aditional Config
#define INTERNAL_LED_PIN 2
#endif

View File

@@ -0,0 +1,8 @@
[env:ESP32_DIY_1W_LoRa_915]
board = esp32dev
build_flags =
${common.build_flags}
-D ESP32_DIY_1W_LoRa_915
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,28 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_LLCC68
#define HAS_1W_LORA
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 12
#define RADIO_BUSY_PIN 14
#define RADIO_RXEN 32
#define RADIO_TXEN 25
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#endif

View File

@@ -0,0 +1,8 @@
[env:ESP32_DIY_1W_LoRa_LLCC68]
board = esp32dev
build_flags =
${common.build_flags}
-D ESP32_DIY_1W_LoRa_LLCC68
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,28 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1268
#define HAS_1W_LORA
#define RADIO_SCLK_PIN 5 // https://github.com/NanoVHF/Meshtastic-DIY/tree/main/PCB/ESP-32-devkit_EBYTE-E22/Mesh-v1.02-2LCD-FreePins
#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
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#endif

View File

@@ -0,0 +1,8 @@
[env:ESP32_DIY_1W_LoRa_Mesh_V1_2]
board = esp32dev
build_flags =
${common.build_flags}
-D ESP32_DIY_1W_LoRa_Mesh_V1_2
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,27 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1278
#define RADIO_SCLK_PIN 5
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 27
#define RADIO_CS_PIN 18
#define RADIO_RST_PIN 14
#define RADIO_BUSY_PIN 26
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// Aditional Config
#define INTERNAL_LED_PIN 2
#endif

View File

@@ -0,0 +1,8 @@
[env:ESP32_DIY_LoRa]
board = esp32dev
build_flags =
${common.build_flags}
-D ESP32_DIY_LoRa
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,27 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1276
#define RADIO_SCLK_PIN 5
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 27
#define RADIO_CS_PIN 18
#define RADIO_RST_PIN 14
#define RADIO_BUSY_PIN 26
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// Aditional Config
#define INTERNAL_LED_PIN 2
#endif

View File

@@ -0,0 +1,8 @@
[env:ESP32_DIY_LoRa_915]
board = esp32dev
build_flags =
${common.build_flags}
-D ESP32_DIY_LoRa_915
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,34 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1278
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 2
#define RADIO_RST_PIN 0
#define RADIO_BUSY_PIN 32
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// Aditional Config
#define INTERNAL_LED_PIN 13 // 13 for V1.1 and 12 for V1.0
#define BATTERY_PIN 35
#define HAS_A7670
#define A7670_PWR_PIN 4
#define A7670_ResetPin 5
#define A7670_TX_PIN 26
#define A7670_RX_PIN 27
#endif

View File

@@ -0,0 +1,10 @@
[env:ESP32_DIY_LoRa_A7670]
board = esp32dev
build_flags =
${common.build_flags}
-D ESP32_DIY_LoRa_A7670
lib_deps =
${common.lib_deps}
${common.display_libs}
vshymanskyy/TinyGSM @ 0.12.0
vshymanskyy/StreamDebugger @ 1.0.1

View File

@@ -0,0 +1,34 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1276
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 2
#define RADIO_RST_PIN 0
#define RADIO_BUSY_PIN 32
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// Aditional Config
#define INTERNAL_LED_PIN 13 // 13 for V1.1 and 12 for V1.0
#define BATTERY_PIN 35
#define HAS_A7670
#define A7670_PWR_PIN 4
#define A7670_ResetPin 5
#define A7670_TX_PIN 26
#define A7670_RX_PIN 27
#endif

View File

@@ -0,0 +1,10 @@
[env:ESP32_DIY_LoRa_A7670_915]
board = esp32dev
build_flags =
${common.build_flags}
-D ESP32_DIY_LoRa_A7670_915
lib_deps =
${common.lib_deps}
${common.display_libs}
vshymanskyy/TinyGSM @ 0.12.0
vshymanskyy/StreamDebugger @ 1.0.1

View File

@@ -0,0 +1,28 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1268
#define HAS_1W_LORA
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 33
#define RADIO_BUSY_PIN 26
#define RADIO_RXEN 14
#define RADIO_TXEN 13
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#endif

View File

@@ -0,0 +1,8 @@
[env:OE5HWN_MeshCom]
board = esp32dev
build_flags =
${common.build_flags}
-D OE5HWN_MeshCom
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,33 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1268
#define RADIO_VCC_PIN 21
#define RADIO_SCLK_PIN 12
#define RADIO_MISO_PIN 13
#define RADIO_MOSI_PIN 11
#define RADIO_CS_PIN 10
#define RADIO_RST_PIN 9
#define RADIO_DIO1_PIN 5
#define RADIO_BUSY_PIN 6
#define RADIO_RXEN 42
#define RADIO_TXEN 14
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 3
#define OLED_SCL 4
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// Aditional Config
#define INTERNAL_LED_PIN 16
#define BATTERY_PIN 1
#define BUTTON_PIN 0
#endif

View File

@@ -0,0 +1,10 @@
[env:QRPLabs_LightGateway_1_0]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
${common.usb_flags}
-D LIGHTGATEWAY_1_0
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,33 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1278
#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_BUSY_PIN 26
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1
// GPS
#define HAS_GPS
#define GPS_RX 12
#define GPS_TX 34
// OTHER
#define INTERNAL_LED_PIN 2
#define BATTERY_PIN 35
#endif

View File

@@ -0,0 +1,8 @@
[env:TROY_LoRa_APRS]
board = esp32dev
build_flags =
${common.build_flags}
-D TROY_LoRa_APRS
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,25 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1278
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 13
#define RADIO_DIO1_PIN 14
#define RADIO_BUSY_PIN 12
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST 36
#endif

View File

@@ -0,0 +1,8 @@
[env:WEMOS-D1-R32-RA02]
board = wemos_d1_uno32
build_flags =
${common.build_flags}
-D WEMOS_D1_R32_RA02
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,24 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1278
#define RADIO_SCLK_PIN 15
#define RADIO_MISO_PIN 13
#define RADIO_MOSI_PIN 12
#define RADIO_CS_PIN 14
#define RADIO_RST_PIN 2
#define RADIO_BUSY_PIN 25
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 5
#define OLED_SCL 4
#define OLED_RST -1
#endif

View File

@@ -0,0 +1,8 @@
[env:WEMOS-LOLIN32-OLED-DIY]
board = lolin32
build_flags =
${common.build_flags}
-D WEMOS_LOLIN32_OLED_DIY_LoRa
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,16 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1278
#define RADIO_SCLK_PIN 36
#define RADIO_MISO_PIN 37
#define RADIO_MOSI_PIN 35
#define RADIO_CS_PIN 34
#define RADIO_RST_PIN 33
#define RADIO_BUSY_PIN 38
// Aditional Config
#define INTERNAL_LED_PIN 15
#endif

View File

@@ -0,0 +1,8 @@
[env:WEMOS_S2_MINI_DIY_LoRa]
board = lolin_s2_mini
build_flags =
${common.build_flags}
-D WEMOS_S2_MINI_DIY_LoRa
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,20 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1262
#define RADIO_SCLK_PIN 7
#define RADIO_MISO_PIN 8
#define RADIO_MOSI_PIN 9
#define RADIO_CS_PIN 41
#define RADIO_RST_PIN 42
#define RADIO_DIO1_PIN 39
#define RADIO_BUSY_PIN 40
#define RADIO_HAS_RF_SWITCH // DIO02
#define RADIO_RF_SWITCH 38
#define BUTTON_PIN 21
#define INTERNAL_LED_PIN 48
#endif

View File

@@ -0,0 +1,8 @@
[env:XIAO_ESP32S3_WIO_SX1262]
board = seeed_xiao_esp32s3
build_flags =
${common.build_flags}
${common.usb_flags}
-D XIAO_ESP32S3_LORA
lib_deps =
${common.lib_deps}

View File

@@ -0,0 +1,17 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1268
#define HAS_1W_LORA
#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

View File

@@ -0,0 +1,10 @@
[env:esp32c3_DIY_1W_LoRa]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
${common.build_flags}
${common.usb_flags}
-D ESP32C3_DIY_1W_LoRa
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,17 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1262
#define HAS_1W_LORA
#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

View File

@@ -0,0 +1,10 @@
[env:esp32c3_DIY_1W_LoRa_915]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
${common.build_flags}
${common.usb_flags}
-D ESP32C3_DIY_1W_LoRa_915
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,30 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1278
#define RADIO_SCLK_PIN 5
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 27
#define RADIO_CS_PIN 18
#define RADIO_RST_PIN 14
#define RADIO_BUSY_PIN 26
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
#define OLED_DISPLAY_HAS_RST_PIN
// Aditional Config
#define INTERNAL_LED_PIN 25
#define BATTERY_PIN 37
#define ADC_CTRL 21
#endif

View File

@@ -0,0 +1,8 @@
[env:heltec-lora32-v2]
board = ttgo-lora32-v21
build_flags =
${common.build_flags}
-D HELTEC_V2
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,17 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1262
#define RADIO_SCLK_PIN 10
#define RADIO_MISO_PIN 6
#define RADIO_MOSI_PIN 7
#define RADIO_CS_PIN 8
#define RADIO_RST_PIN 5
#define RADIO_DIO1_PIN 3
#define RADIO_BUSY_PIN 4
// Aditional Config
#define BATTERY_PIN 1
#endif

View File

@@ -0,0 +1,9 @@
[env:heltec_ht-ct62]
board = heltec_wireless_stick_lite
board_build.mcu = esp32c3
build_flags =
${common.build_flags}
-D HELTEC_HTCT62
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,34 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1262
#define RADIO_SCLK_PIN 9
#define RADIO_MISO_PIN 11
#define RADIO_MOSI_PIN 10
#define RADIO_CS_PIN 8
#define RADIO_RST_PIN 12
#define RADIO_DIO1_PIN 14
#define RADIO_BUSY_PIN 13
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 17
#define OLED_SCL 18
#define OLED_RST 21
#define OLED_DISPLAY_HAS_RST_PIN
// Aditional Config
#define INTERNAL_LED_PIN 35
#define BATTERY_PIN 1
#define VEXT_CTRL 36
#define ADC_CTRL 37
#define BOARD_I2C_SDA 41
#define BOARD_I2C_SCL 42
#endif

View File

@@ -0,0 +1,9 @@
[env:heltec_wifi_lora_32_V3]
board = heltec_wifi_lora_32_V3
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-D HELTEC_V3
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,34 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1262
#define RADIO_SCLK_PIN 9
#define RADIO_MISO_PIN 11
#define RADIO_MOSI_PIN 10
#define RADIO_CS_PIN 8
#define RADIO_RST_PIN 12
#define RADIO_DIO1_PIN 14
#define RADIO_BUSY_PIN 13
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 17
#define OLED_SCL 18
#define OLED_RST 21
#define OLED_DISPLAY_HAS_RST_PIN
// Aditional Config
#define INTERNAL_LED_PIN 35
#define BATTERY_PIN 1
#define VEXT_CTRL 36
#define ADC_CTRL 37
#define BOARD_I2C_SDA 41
#define BOARD_I2C_SCL 42
#endif

View File

@@ -0,0 +1,9 @@
[env:heltec_wifi_lora_32_V3_2]
board = heltec_wifi_lora_32_V3
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-D HELTEC_V3_2
lib_deps =
${common.lib_deps}
${common.display_libs}

View File

@@ -0,0 +1,32 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1262
#define RADIO_SCLK_PIN 9
#define RADIO_MISO_PIN 11
#define RADIO_MOSI_PIN 10
#define RADIO_CS_PIN 8
#define RADIO_RST_PIN 12
#define RADIO_DIO1_PIN 14
#define RADIO_BUSY_PIN 13
// Display
#define HAS_DISPLAY
#define HAS_EPAPER
#define EPAPER_BUSY 7
#define EPAPER_RST 6
#define EPAPER_DC 5
#define EPAPER_CS 4
#define EPAPER_SCL 3
#define EPAPER_SDA 2
// Aditional Config
#define INTERNAL_LED_PIN 18
#define BATTERY_PIN 20
#define ADC_CTRL 19
#define VEXT_CTRL 45
#define BOARD_I2C_SDA 37
#define BOARD_I2C_SCL 36
#endif

View File

@@ -0,0 +1,10 @@
[env:heltec_wireless_paper]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-D HELTEC_WP
-D WIRELESS_PAPER
lib_deps =
${common.lib_deps}
todd-herbert/heltec-eink-modules@^4.4.0

View File

@@ -0,0 +1,34 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1262
#define RADIO_SCLK_PIN 9
#define RADIO_MISO_PIN 11
#define RADIO_MOSI_PIN 10
#define RADIO_CS_PIN 8
#define RADIO_RST_PIN 12
#define RADIO_DIO1_PIN 14
#define RADIO_BUSY_PIN 13
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 17
#define OLED_SCL 18
#define OLED_RST 21
#define OLED_DISPLAY_HAS_RST_PIN
// Aditional Config
#define INTERNAL_LED_PIN 35
#define BATTERY_PIN 1
#define VEXT_CTRL 36
#define ADC_CTRL 37
#define BOARD_I2C_SDA 41
#define BOARD_I2C_SCL 42
#endif

View File

@@ -0,0 +1,9 @@
[env:heltec_wireless_stick]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
-D HELTEC_WS
lib_deps =
${common.lib_deps}
${common.display_libs}

Some files were not shown because too many files have changed in this diff Show More