├── .github
├── FUNDING.yml
└── workflows
│ ├── build.yml
│ └── commit.yml
├── .gitignore
├── .vscode
├── extensions.json
└── settings.json
├── LICENSE
├── README.md
├── common_settings.ini
├── data
└── tracker_conf.json
├── data_embed
├── bootstrap.css
├── bootstrap.js
├── favicon.png
├── index.html
├── script.js
└── style.css
├── extra
└── turn_slope_calculations.xlsx
├── images
├── OledScreen2.jpeg
├── Web001-Beacons.png
├── Web002-StationConfig.png
├── Web003-Display.png
├── Web004-LoRa.png
├── Web005-WxTelemetry.png
├── Web006-Bluetooth.png
├── Web007-Battery.png
├── Web008-Notifications.png
├── Web009-PttTrigger.png
├── Web010-Winlink.png
├── Web011-WiFiAP.png
├── WebFlasherTrackerGithub.png
├── github-sponsors.png
└── paypalme.png
├── include
├── battery_utils.h
├── ble_utils.h
├── bluetooth_utils.h
├── button_utils.h
├── configuration.h
├── custom_characters.h
├── custom_colors.h
├── display.h
├── gps_utils.h
├── joystick_utils.h
├── keyboard_utils.h
├── kiss_utils.h
├── lora_utils.h
├── menu_utils.h
├── msg_utils.h
├── notification_utils.h
├── power_utils.h
├── sleep_utils.h
├── smartbeacon_utils.h
├── station_utils.h
├── touch_utils.h
├── utils.h
├── web_utils.h
├── wifi_utils.h
├── winlink_utils.h
└── wx_utils.h
├── platformio.ini
├── src
├── LoRa_APRS_Tracker.cpp
├── battery_utils.cpp
├── ble_utils.cpp
├── bluetooth_utils.cpp
├── button_utils.cpp
├── configuration.cpp
├── display.cpp
├── gps_utils.cpp
├── joystick_utils.cpp
├── keyboard_utils.cpp
├── kiss_utils.cpp
├── lora_utils.cpp
├── menu_utils.cpp
├── msg_utils.cpp
├── notification_utils.cpp
├── power_utils.cpp
├── sleep_utils.cpp
├── smartbeacon_utils.cpp
├── station_utils.cpp
├── touch_utils.cpp
├── utils.cpp
├── web_utils.cpp
├── wifi_utils.cpp
├── winlink_utils.cpp
└── wx_utils.cpp
├── tools
└── compress.py
└── variants
├── ESP32S3_DIY_LoRa_GPS
├── board_pinout.h
└── platformio.ini
├── ESP32S3_DIY_LoRa_GPS_915
├── board_pinout.h
└── platformio.ini
├── ESP32_DIY_1W_LoRa_GPS
├── board_pinout.h
└── platformio.ini
├── ESP32_DIY_1W_LoRa_GPS_915
├── board_pinout.h
└── platformio.ini
├── ESP32_DIY_1W_LoRa_GPS_LLCC68
├── board_pinout.h
└── platformio.ini
├── ESP32_DIY_LoRa_GPS
├── board_pinout.h
└── platformio.ini
├── ESP32_DIY_LoRa_GPS_915
├── board_pinout.h
└── platformio.ini
├── F4GOH_1W_LoRa_Tracker
├── board_pinout.h
└── platformio.ini
├── F4GOH_1W_LoRa_Tracker_LLCC68
├── board_pinout.h
└── platformio.ini
├── OE5HWN_MeshCom
├── board_pinout.h
└── platformio.ini
├── QRPLabs_LightTracker_Plus_1_0
├── board_pinout.h
└── platformio.ini
├── TROY_LoRa_APRS
├── board_pinout.h
└── platformio.ini
├── Wemos_ESP32_Bat_LoRa_GPS
├── board_pinout.h
└── platformio.ini
├── esp32_c3_DIY_LoRa_GPS
├── board_pinout.h
└── platformio.ini
├── esp32_c3_DIY_LoRa_GPS_915
├── board_pinout.h
└── platformio.ini
├── heltec-lora32-v2_GPS
├── board_pinout.h
└── platformio.ini
├── heltec-lora32-v2_GPS_915
├── board_pinout.h
└── platformio.ini
├── heltec-lora32-v2_TNC
├── board_pinout.h
└── platformio.ini
├── heltec_ht-ct62_GPS
├── board_pinout.h
└── platformio.ini
├── heltec_wifi_lora_32_v3_2_GPS
├── board_pinout.h
└── platformio.ini
├── heltec_wifi_lora_32_v3_2_TNC
├── board_pinout.h
└── platformio.ini
├── heltec_wifi_lora_32_v3_GPS
├── board_pinout.h
└── platformio.ini
├── heltec_wifi_lora_32_v3_TNC
├── board_pinout.h
└── platformio.ini
├── heltec_wireless_stick_lite_v3_GPS_display
├── board_pinout.h
└── platformio.ini
├── heltec_wireless_tracker
├── board_pinout.h
└── platformio.ini
├── ttgo-t-beam-v0_7
├── board_pinout.h
└── platformio.ini
├── ttgo-t-beam-v1
├── board_pinout.h
└── platformio.ini
├── ttgo-t-beam-v1_2
├── board_pinout.h
└── platformio.ini
├── ttgo-t-beam-v1_2_915
├── board_pinout.h
└── platformio.ini
├── ttgo-t-beam-v1_2_SX1262
├── board_pinout.h
└── platformio.ini
├── ttgo-t-beam-v1_915
├── board_pinout.h
└── platformio.ini
├── ttgo-t-beam-v1_SX1268
├── board_pinout.h
└── platformio.ini
├── ttgo-t-lora32-v2_1_GPS
├── board_pinout.h
└── platformio.ini
├── ttgo-t-lora32-v2_1_GPS_915
├── board_pinout.h
└── platformio.ini
├── ttgo-t-lora32-v2_1_TNC
├── board_pinout.h
└── platformio.ini
├── ttgo-t-lora32-v2_1_TNC_915
├── board_pinout.h
└── platformio.ini
├── ttgo_t_beam_s3_SUPREME_v3
├── board_pinout.h
└── platformio.ini
├── ttgo_t_deck_GPS
├── board_pinout.h
└── platformio.ini
└── ttgo_t_deck_plus
├── board_pinout.h
└── platformio.ini
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: ['richonguzman']
4 | custom: ['paypal.me/richonguzman']
5 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build Release
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | strategy:
11 | fail-fast: false
12 | matrix:
13 | target:
14 | - name: ttgo-t-beam-v1
15 | chip: esp32
16 | - name: ttgo-t-beam-v1_915
17 | chip: esp32
18 | - name: ttgo-t-beam-v1_SX1268
19 | chip: esp32
20 | - name: ttgo-t-beam-v1_2
21 | chip: esp32
22 | - name: ttgo-t-beam-v1_2_915
23 | chip: esp32
24 | - name: ttgo-t-beam-v1_2_SX1262
25 | chip: esp32
26 | - name: ttgo_t_beam_s3_SUPREME_v3
27 | chip: esp32s3
28 | - name: ttgo_t_deck_GPS
29 | chip: esp32s3
30 | - name: ttgo_t_deck_plus
31 | chip: esp32s3
32 | - name: ttgo-t-beam-v0_7
33 | chip: esp32
34 | - name: heltec_wireless_tracker
35 | chip: esp32s3
36 | - name: heltec_wifi_lora_32_v3_GPS
37 | chip: esp32s3
38 | - name: heltec_wifi_lora_32_v3_TNC
39 | chip: esp32s3
40 | - name: heltec_wifi_lora_32_v3_2_GPS
41 | chip: esp32s3
42 | - name: heltec_wifi_lora_32_v3_2_TNC
43 | chip: esp32s3
44 | - name: heltec_wireless_stick_lite_v3_GPS_display
45 | chip: esp32s3
46 | - name: heltec-lora32-v2_GPS
47 | chip: esp32
48 | - name: heltec-lora32-v2_GPS_915
49 | chip: esp32
50 | - name: ttgo-t-lora32-v2_1_GPS
51 | chip: esp32
52 | - name: ttgo-t-lora32-v2_1_GPS_915
53 | chip: esp32
54 | - name: ttgo-t-lora32-v2_1_TNC
55 | chip: esp32
56 | - name: ttgo-t-lora32-v2_1_TNC_915
57 | chip: esp32
58 | - name: ESP32_DIY_LoRa_GPS
59 | chip: esp32
60 | - name: ESP32_DIY_LoRa_GPS_915
61 | chip: esp32
62 | - name: ESP32S3_DIY_LoRa_GPS
63 | chip: esp32s3
64 | - name: ESP32S3_DIY_LoRa_GPS_915
65 | chip: esp32s3
66 | - name: ESP32_DIY_1W_LoRa_GPS
67 | chip: esp32
68 | - name: ESP32_DIY_1W_LoRa_GPS_915
69 | chip: esp32
70 | - name: ESP32_DIY_1W_LoRa_GPS_LLCC68
71 | chip: esp32
72 | - name: OE5HWN_MeshCom
73 | chip: esp32
74 | - name: Wemos_ESP32_Bat_LoRa_GPS
75 | chip: esp32
76 | - name: esp32_c3_DIY_LoRa_GPS
77 | chip: esp32c3
78 | - name: esp32_c3_DIY_LoRa_GPS_915
79 | chip: esp32c3
80 | - name: heltec_ht-ct62_GPS
81 | chip: esp32c3
82 | - name: QRPLabs_LightTracker_Plus_1_0
83 | chip: esp32s3
84 | - name: TROY_LoRa_APRS
85 | chip: esp32
86 | - name: F4GOH_1W_LoRa_Tracker
87 | chip: esp32
88 | - name: F4GOH_1W_LoRa_Tracker_LLCC68
89 | chip: esp32
90 | steps:
91 | - uses: actions/checkout@v3
92 |
93 | - uses: actions/setup-python@v4
94 | with:
95 | python-version: "3.9"
96 |
97 | - name: Install esptool
98 | run: pip install esptool
99 |
100 | - name: Install PlatformIO Core
101 | run: pip install --upgrade platformio
102 |
103 | - name: Build target
104 | run: |
105 | pio run -e ${{ matrix.target.name }}
106 |
107 | - name: Build FS
108 | run: |
109 | pio run --target buildfs -e ${{ matrix.target.name }}
110 |
111 | - name: Move Files
112 | run: |
113 | mkdir -p installer/firmware
114 | cp .pio/build/${{ matrix.target.name }}/firmware.bin installer/ota_update.bin
115 | cp .pio/build/${{ matrix.target.name }}/firmware.bin installer/firmware/
116 | cp .pio/build/${{ matrix.target.name }}/bootloader.bin installer/firmware/
117 | cp .pio/build/${{ matrix.target.name }}/partitions.bin installer/firmware/
118 | cp .pio/build/${{ matrix.target.name }}/spiffs.bin installer/firmware/
119 | cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin installer/firmware/
120 |
121 | - name: Merge for web flashing
122 | run: |
123 | if [ "${{ matrix.target.chip }}" == "esp32" ]; then
124 | esptool.py --chip esp32 merge_bin \
125 | -o installer/web_factory.bin \
126 | --flash_mode dio \
127 | --flash_freq 40m \
128 | --flash_size 4MB \
129 | 0x1000 installer/firmware/bootloader.bin \
130 | 0x8000 installer/firmware/partitions.bin \
131 | 0xe000 installer/firmware/boot_app0.bin \
132 | 0x10000 installer/firmware/firmware.bin \
133 | 0x310000 installer/firmware/spiffs.bin
134 | elif [ "${{ matrix.target.chip }}" == "esp32s2" ]; then
135 | esptool.py --chip esp32s2 merge_bin \
136 | -o installer/web_factory.bin \
137 | --flash_mode dio \
138 | --flash_freq 40m \
139 | --flash_size 4MB \
140 | 0x1000 installer/firmware/bootloader.bin \
141 | 0x8000 installer/firmware/partitions.bin \
142 | 0xe000 installer/firmware/boot_app0.bin \
143 | 0x10000 installer/firmware/firmware.bin \
144 | 0x310000 installer/firmware/spiffs.bin
145 | elif [ "${{ matrix.target.chip }}" == "esp32s3" ]; then
146 | esptool.py --chip esp32s3 merge_bin \
147 | -o installer/web_factory.bin \
148 | --flash_mode dio \
149 | --flash_freq 40m \
150 | --flash_size 8MB \
151 | 0x0000 installer/firmware/bootloader.bin \
152 | 0x8000 installer/firmware/partitions.bin \
153 | 0xe000 installer/firmware/boot_app0.bin \
154 | 0x10000 installer/firmware/firmware.bin \
155 | 0x310000 installer/firmware/spiffs.bin
156 | elif [ "${{ matrix.target.chip }}" == "esp32c3" ]; then
157 | esptool.py --chip esp32c3 merge_bin \
158 | -o installer/web_factory.bin \
159 | --flash_mode dio \
160 | --flash_freq 40m \
161 | --flash_size 4MB \
162 | 0x1000 installer/firmware/bootloader.bin \
163 | 0x8000 installer/firmware/partitions.bin \
164 | 0xe000 installer/firmware/boot_app0.bin \
165 | 0x10000 installer/firmware/firmware.bin \
166 | 0x310000 installer/firmware/spiffs.bin
167 | fi
168 |
169 | - name: Install Zip
170 | run: sudo apt-get install zip
171 |
172 | - name: Archive Files
173 | run: zip -r installer.zip installer/
174 |
175 | - name: Upload Release Asset
176 | uses: actions/upload-release-asset@v1
177 | env:
178 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
179 | with:
180 | upload_url: ${{ github.event.release.upload_url }}
181 | asset_path: ./installer.zip
182 | asset_name: ${{ matrix.target.name }}.zip
183 | asset_content_type: application/zip
184 |
--------------------------------------------------------------------------------
/.github/workflows/commit.yml:
--------------------------------------------------------------------------------
1 | name: Commit Test Build
2 |
3 | on:
4 | push:
5 | branches:
6 | - '*'
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | strategy:
12 | fail-fast: false
13 | matrix:
14 | target:
15 | - name: ttgo-t-beam-v1_2
16 | chip: esp32
17 | steps:
18 | - uses: actions/checkout@v3
19 |
20 | - uses: actions/setup-python@v4
21 | with:
22 | python-version: "3.9"
23 |
24 | - name: Install PlatformIO Core
25 | run: pip install --upgrade platformio
26 |
27 | - name: Build target
28 | run: pio run -e ${{ matrix.target.name }}
29 |
30 | - name: Build FS
31 | run: pio run --target buildfs -e ${{ matrix.target.name }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .pio
2 | .vscode/.browse.c_cpp.db*
3 | .vscode/c_cpp_properties.json
4 | .vscode/launch.json
5 | .vscode/ipch
6 | .DS_Store
7 | /data_embed/*.gz
8 | installer/firmware
9 | installer/*.bin
10 | **/__pycache__/
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See http://go.microsoft.com/fwlink/?LinkId=827846
3 | // for the documentation about the extensions.json format
4 | "recommendations": [
5 | "platformio.platformio-ide"
6 | ],
7 | "unwantedRecommendations": [
8 | "ms-vscode.cpptools-extension-pack"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.tabSize": 4,
3 | "editor.formatOnSave": false
4 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Ricardo Guzman (Richonguzman)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CA2RXU LoRa APRS Tracker/Station
2 |
3 | This firmware is for using ESP32 based boards with LoRa Modules and GPS to live in the APRS world.
4 |
5 | 
6 |
7 | __(NOTE: To use Tx/Rx capabilities of this tracker you should have also an Tx/Rx LoRa iGate near you)__
8 |
9 |
10 | ____________________________________________________
11 |
12 | ## You can support this project to continue to grow:
13 |
14 | [
](https://github.com/sponsors/richonguzman) [
](http://paypal.me/richonguzman)
15 |
16 |
17 |
18 | # WEB FLASHER/INSTALLER is here
19 |
20 | ____________________________________________________
21 |
22 | - Tracker with complete MENU !!! (see Wiki to know how to access it)
23 | - Read, Write and Delete Messages (with I2C Keyboard or Phone).
24 | - Asking Weather Report.
25 | - Listening to other Trackers arround.
26 | - Changing Display Eco Mode (turn off after 4 seconds) and Screen Brightness.
27 | - Processor from 240Mhz to 80MHz to save almost 20% power consumption.
28 | - All GPS beacons/packets are encoded for less time on RF/LoRa Tx.
29 | - Oled Screen shows Altitude+Speed+Course or BME280 Wx Data or Number of New Messages Received.
30 | - Oled Screen shows Recent Heard Trackers/Station/iGates Tx.
31 | - Bluetooth capabilities to connect (Android + APRSDroid) or (iPhone + APRS.fi app) and use it as TNC.
32 | - Led Notifications for Tx and Messages Received.
33 | - Sound Notifications with YL44 Buzzer Module.
34 | - Wx data with BME280 Module showed on Screen and transmited as Wx Telemetry.
35 | - Winlink Mails through APRSLink.
36 | - Posibility to change between 3 major Frequencies used by LoRa APRS Worldwide.
37 | ____________________________________________________
38 |
39 | # WIKI (English / Español)
40 |
41 | ### FAQ: GPS, Bluetooth, Winlink, BME280 and more --> here
42 |
43 | ### Supported Boards and buying links --> here
44 |
45 | ### 1. Installation Guide --> here
46 |
47 | ### 2. Tracker Configuration and Explanation for each setting --> here
48 |
49 | ### 3. Upload Firmware and Filesystem --> here
50 |
51 | ### 4. Tracker Menu Guide --> here
52 |
53 | ____________________________________________________
54 | ## Timeline (Versions):
55 |
56 | - 2025.03.28 F4GOH DIY board with ESP32 + GPS + 1W LLCC68 added. APRSPacketLib Library Updated.
57 | - 2025.03.06 F4GOH DIY board with ESP32 + GPS + 1W SX1268 added.
58 | - 2025.02.09 Now Bluetooth connections lets you decide to use BLE/BT Classic and KISS/TNC.
59 | - 2025.01.11 Added HELTEC V3.2 board support.
60 | - 2025.01.07 TROY_LoRa_APRS board added.
61 | - 2025.01.02 Buttons added for DIY Boards and Boards without buttons.
62 | - 2024.11.13 Added Heltec Wireless Stick Lite V3 + GPS + Oled Display support for another DIY ESP32 Tracker.
63 | - 2024.11.13 T-Deck Joystick and Button Pressing Fix for smother operation.
64 | - 2024.10.24 Added QRP Labs LightTracker Plus1.0 support.
65 | - 2024.10.11 Added Lilygo TTGO T-Deck Plus support.
66 | - 2024.10.10 Configuration WiFiAP stops after 1 minute of no-client connected.
67 | - 2024.10.09 WEB INSTALLER/FLASHER.
68 | - 2024.10.07 Battery Monitor process added (Voltage Sleep to protect Battery).
69 | - 2024.09.17 Battery Voltage now as Encoded Telemetry in GPS Beacon.
70 | - 2024.08.26 New reformating of code ahead of WebInstaller: SmartBeacon change.
71 | - 2024.08.16 BLE support for Android devices (not APRSDroid yet).
72 | - 2024.08.12 Added support for EByte E220 400M30S 1Watt LoRa module for DIY ESP32 Tracker (LLCC68 supports spreading factor only in range of 5 - 11!)
73 | - 2024.08.02 New gpsEcoMode added for Testing.
74 | - 2024.08.02 ESP32S3 DIY LoRa GPS added.
75 | - 2024.07.30 HELTEC V3 TNC added.
76 | - 2024.07.01 All boards with 433MHZ and 915MHz versions now.
77 | - 2024.06.21 3rd Party Packets decode added following the corrections on iGate Firmware.
78 | - 2024.06.21 If Tracker Speed > 200km/hr and/or Altitude > 9.000 mts , path ("WIDE1-1") will be omited as its probably a plane.
79 | - 2024.06.21 Wx Telemetry Tx on Tracker only if standing still > 15min. (On screen Wx Data will be available but won't be sent if moving).
80 | - 2024.06.07 Dynamic Height Correction of the BME280 Pressure readings.
81 | - 2024.05.21 WEMOS ESP32 Battery Holder + LoRa SX1278 + GPS Module support added.
82 | - 2024.05.16 all boards now work with Radiolib (LoRa) library from @jgromes.
83 | - 2024.05.13 BME modules will be autodetected (I2C Address and if it is BME280/BMP280/BME680).
84 | - 2024.05.10 PacketBuffer for Rx (25 Seg) and Tx outputPacketBuffer for sending with ACK Request.
85 | - 2024.05.07 HELTEC V3 and Wireless Tracker Battery Measurements at 30seg to avoid accelerated discharge.
86 | - 2024.05.06 New Output Buffer for Messages with retry posibilities.
87 | - 2024.04.25 Added Lilygo TTGO T-Deck (add Neo6Mv2 GPS) support.
88 | - 2024.04.12 Added HELTEC Wireless Tracker support.
89 | - 2024.03.22 3 times pressing middle button for T-Beams turns the Tracker off.
90 | - 2024.03.08 ESP32_C3 DIY LoRa + GPS board added. Thanks Julian OE1JLN.
91 | - 2024.02.29 Now you can change between (EU,PL,UK) LoRa APRS frequencies used worldwide.
92 | - 2024.02.24 New Partitions: more memory for new code/firmware (still > 500 Rx messages available)
93 | - 2024.02.21 Winlink Mails through APRSLink ( https://www.winlink.org/APRSLink/ )
94 | - 2024.01.26 Added Helmut OE5HWN MeshCom PCB support.
95 | - 2024.01.18 BME modules have now a single reading per minute.
96 | - 2024.01.05 Added HELTEC V3 with NEO8M GPS. Thanks Asbjørn LA1HSA.
97 | - 2024.01.04 Added TTGO Lilygo T-Beam S3 Supreme V3 support. Thanks Johannes OE2JPO.
98 | - 2023.12.31 PowerManagment Library AXP192/AXP2101 updated.
99 | - 2023.12.27 Added Led-Flashlight like Baofeng UV5R Led.
100 | - 2023.12.27 Added LoRa APRS Packet Decoder to Stations Menu.
101 | - 2023.12.26 Added BME680 (to the already BME/BMP280) support for Wx Telemetry Tx.
102 | - 2023.12.22 Added APRSThrusday on Messages Menu to parcitipate from this exercise ( https://aprsph.net/aprsthursday/ )
103 | - 2023.12.19 Added support for T-Beam V1.2 with Neo8M GPS and SX1262 LoRa Modules.
104 | - 2023.12.18 Added Mic-E encoding and decoding.
105 | - 2023.12.12 Added BMP280 (to the already BME280) support for Wx Telemetry Tx.
106 | - 2023.12.11 Added support for EByte 400M30S 1Watt LoRa module for DIY ESP32 Tracker.
107 | - 2023.12.07 Added TTGO Lilygo LoRa32 v2.1 board as Bluetooth TNC(Android/Apple) and as a Tracker (with external GPS module).
108 | - 2023.12.07 Added ESP32 as DIY Tracker (with external GPS Module) with LoRa SX1278 module.
109 | - 2023.12.06 T-Beam V1.2 as default board.
110 | - 2023.12.05 Updated packets recognition (+Objects + Mic-E).
111 | - 2023.11.28 Adding BLE connection to use it as TNC with APRS.fi app for iOS.
112 | - 2023.11.07 Digipeater Mode added in Emergency Menu.
113 | - 2023.10.23 COMPLETE New Menu for Keyboard add-on.
114 | - 2023.10.22 Added Keyboard Support over I2C ( CARDKB from https://m5stack.com )
115 | - 2023.10.07 Screen Brightness control added.
116 | - 2023.10.01 Added Wx Telemetry Tx with BME280 Module attached to Tracker.
117 | - 2023.09.28 Added Support for V.1 board with SX1268 LoRa Module.
118 | - 2023.09.25 Wiki added.
119 | - 2023.09.16 Adding Led notification for Beacon Tx and for Message Received.
120 | - 2023.09.14 Adding buzzer sounds for BootUp, BeaconTx, MessageRx and more.
121 | - 2023.09.11 Saving last used Callsign into internal Memory to remember it at next boot.
122 | - 2023.09.05 Adding "simplified Tracker Mode": only GPS beacons Tx.
123 | - 2023.08.27 Adding support to connect BME280 and see Temperature, Humidity, Pressure.
124 | - 2023.08.12 Adding also support for old V0_7 board. Thanks Béla Török.
125 | - 2023.08.09 Adding Bluetooth capabilities with Kiss and TNC2, TTGO Lora 32. Thanks Thomas DL9SAU.
126 | - 2023.08.08 Added Maidenhead info on Screen. Thanks Mathias "mpbraendli".
127 | - 2023.08.06 Added Bluetooth Support for TNC in Android/APRSDroid. Thanks Valentin F4HVV.
128 | - 2023.08.05 New Support for SH1106 Oled Screen (0,96" and 1.3")
129 | - 2023.07.24 New Validation for Callsings, Overlay change and New Icons (Bike, Motorcycle).
130 | - 2023.07.18 Add Support for triggering PTT to external amplifier.
131 | - 2023.07.16 New Icons for Oled Screen (Runner, Car, Jeep)
132 | - 2023.07.01 Added Support for new T-Beam AXP2101 v1.2 Board.
133 | - 2023.06.26 Weather Report now stays until button pressed, to avoid missing it.
134 | - 2023.06.25 Sends comment after X count of beacons.
135 | - 2023.06.24 displayEcoMode=true doesn't turn the screen off at boot.
136 | - 2023.06.23 Return to from any Menu number to Main Menu (Tracker) after 30 segs.
137 | - 2023.06.20 Major Code Repacking.
138 | - 2023.06.01 Adding Turn Slope calculations for Smart Beacon and Display Eco Mode.
139 | - 2023.05.29 New Config file for adding more new ideas to the Tracker.
140 | - 2023.05.27 Adding Altitude + Speed or Course + Speed in the encoded GPS info.
141 | - 2023.05.21 Adding Last-Heard LoRa Stations/Trackers.
142 | - 2023.05.14 Adding Menu.
143 | - 2023.05.12 Saving Messages to Internal Memory.
144 | - 2023.04.16 Sending and Receiving LoRa Packets.
145 |
146 | ____________________________________________________
147 | ## This code was based on the work of :
148 | - https://github.com/aprs434/lora.tracker : Serge - ON4AA on base91 byte-saving/encoding
149 | - https://github.com/lora-aprs/LoRa_APRS_Tracker : Peter - OE5BPA LoRa Tracker
150 | - https://github.com/Mane76/LoRa_APRS_Tracker : Manfred - DC2MH (Mane76) mods for multiple Callsigns and processor speed
151 | - https://github.com/dl9sau/TTGO-T-Beam-LoRa-APRS : Thomas - DL9SAU for the Kiss <> TNC2 lib
152 | ____________________________________________________
153 |
154 | # Hope You Enjoy this, 73! CA2RXU, Valparaiso, Chile
--------------------------------------------------------------------------------
/common_settings.ini:
--------------------------------------------------------------------------------
1 | [common]
2 | build_flags =
3 | -Werror -Wall
4 | -DRADIOLIB_EXCLUDE_CC1101=1
5 | -DRADIOLIB_EXCLUDE_NRF24=1
6 | -DRADIOLIB_EXCLUDE_RF69=1
7 | -DRADIOLIB_EXCLUDE_SX1231=1
8 | -DRADIOLIB_EXCLUDE_SX1233=1
9 | -DRADIOLIB_EXCLUDE_SI443X=1
10 | -DRADIOLIB_EXCLUDE_RFM2X=1
11 | -DRADIOLIB_EXCLUDE_AFSK=1
12 | -DRADIOLIB_EXCLUDE_BELL=1
13 | -DRADIOLIB_EXCLUDE_HELLSCHREIBER=1
14 | -DRADIOLIB_EXCLUDE_MORSE=1
15 | -DRADIOLIB_EXCLUDE_RTTY=1
16 | -DRADIOLIB_EXCLUDE_SSTV=1
17 | -DRADIOLIB_EXCLUDE_AX25=1
18 | -DRADIOLIB_EXCLUDE_DIRECT_RECEIVE=1
19 | -DRADIOLIB_EXCLUDE_BELL=1
20 | -DRADIOLIB_EXCLUDE_PAGER=1
21 | -DRADIOLIB_EXCLUDE_FSK4=1
22 | -DRADIOLIB_EXCLUDE_APRS=1
23 | -DRADIOLIB_EXCLUDE_LORAWAN=1
24 | -I variants/${PIOENV}
25 | lib_deps =
26 | adafruit/Adafruit BusIO @ 1.16.1
27 | adafruit/Adafruit Unified Sensor @ 1.1.14
28 | adafruit/Adafruit BME280 Library @ 2.2.4
29 | adafruit/Adafruit BMP280 Library @ 2.6.8
30 | adafruit/Adafruit BME680 Library @ 2.0.4
31 | bblanchon/ArduinoJson @ 6.21.3
32 | h2zero/NimBLE-Arduino @ 1.4.1
33 | jgromes/RadioLib @ 7.1.0
34 | mathieucarbou/AsyncTCP @ 3.2.5
35 | mathieucarbou/ESPAsyncWebServer @ 3.2.3
36 | mikalhart/TinyGPSPlus @ 1.0.3
37 | paulstoffregen/Time @ 1.6.1
38 | peterus/esp-logger @ 1.0.0
39 | richonguzman/APRSPacketLib @ 0.9.0
40 | shaggydog/OneButton @ 1.5.0
41 | display_libs =
42 | adafruit/Adafruit GFX Library @ 1.11.9
43 | adafruit/Adafruit SSD1306 @ 2.5.10
44 | usb_flags=
45 | -DARDUINO_USB_MODE=1
46 | -DARDUINO_USB_CDC_ON_BOOT=1
--------------------------------------------------------------------------------
/data/tracker_conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "beacons": [
3 | {
4 | "callsign": "NOCALL-7",
5 | "gpsEcoMode": false,
6 | "symbol": "[",
7 | "overlay": "/",
8 | "micE": "",
9 | "comment": "",
10 | "smartBeaconActive": true,
11 | "smartBeaconSetting": 0
12 | },
13 | {
14 | "callsign": "NOCALL-7",
15 | "gpsEcoMode": false,
16 | "symbol": ">",
17 | "overlay": "/",
18 | "micE": "",
19 | "comment": "",
20 | "smartBeaconActive": true,
21 | "smartBeaconSetting": 2
22 | },
23 | {
24 | "callsign": "NOCALL-7",
25 | "gpsEcoMode": false,
26 | "symbol": "b",
27 | "overlay": "/",
28 | "micE": "",
29 | "comment": "",
30 | "smartBeaconActive": true,
31 | "smartBeaconSetting": 1
32 | }
33 | ],
34 | "display": {
35 | "showSymbol": true,
36 | "ecoMode": false,
37 | "timeout": 4,
38 | "turn180" : false
39 | },
40 | "battery": {
41 | "sendVoltage": false,
42 | "voltageAsTelemetry": false,
43 | "sendVoltageAlways": false,
44 | "monitorVoltage": false,
45 | "sleepVoltage": 2.9
46 | },
47 | "other": {
48 | "simplifiedTrackerMode": false,
49 | "sendCommentAfterXBeacons": 10,
50 | "path": "WIDE1-1",
51 | "nonSmartBeaconRate": 15,
52 | "rememberStationTime": 30,
53 | "standingUpdateTime": 15,
54 | "sendAltitude": true,
55 | "disableGPS": false,
56 | "acceptOwnFrameFromTNC": false,
57 | "email": ""
58 | },
59 | "winlink": {
60 | "password": "ABCDEF"
61 | },
62 | "wxsensor": {
63 | "active": false,
64 | "temperatureCorrection": 0.0,
65 | "sendTelemetry": false
66 | },
67 | "notification": {
68 | "ledTx": false,
69 | "ledTxPin": 13,
70 | "ledMessage": false,
71 | "ledMessagePin": 2,
72 | "ledFlashlight": false,
73 | "ledFlashlightPin": 14,
74 | "buzzerActive": false,
75 | "buzzerPinTone": 33,
76 | "buzzerPinVcc": 25,
77 | "bootUpBeep": false,
78 | "txBeep": false,
79 | "messageRxBeep": false,
80 | "stationBeep": false,
81 | "lowBatteryBeep": false,
82 | "shutDownBeep": false
83 | },
84 | "lora": [
85 | {
86 | "frequency": 433775000,
87 | "spreadingFactor": 12,
88 | "signalBandwidth": 125000,
89 | "codingRate4": 5,
90 | "power": 20
91 | },
92 | {
93 | "frequency": 434855000,
94 | "spreadingFactor": 9,
95 | "signalBandwidth": 125000,
96 | "codingRate4": 7,
97 | "power": 20
98 | },
99 | {
100 | "frequency": 439912500,
101 | "spreadingFactor": 12,
102 | "signalBandwidth": 125000,
103 | "codingRate4": 5,
104 | "power": 20
105 | }
106 | ],
107 | "bluetooth": {
108 | "active": false,
109 | "deviceName": "LoRaTracker",
110 | "useBLE": false,
111 | "useKISS": false
112 | },
113 | "pttTrigger": {
114 | "active": false,
115 | "io_pin": 4,
116 | "preDelay": 0,
117 | "postDelay": 0,
118 | "reverse": false
119 | },
120 | "wifiAP": {
121 | "active": false,
122 | "password": "1234567890"
123 | }
124 |
125 | }
--------------------------------------------------------------------------------
/data_embed/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/data_embed/favicon.png
--------------------------------------------------------------------------------
/data_embed/style.css:
--------------------------------------------------------------------------------
1 | .alert-fixed {
2 | position:fixed;
3 | top: 0px;
4 | left: 0px;
5 | width: 100%;
6 | z-index:9999;
7 | border-radius:0px
8 | }
--------------------------------------------------------------------------------
/extra/turn_slope_calculations.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/extra/turn_slope_calculations.xlsx
--------------------------------------------------------------------------------
/images/OledScreen2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/OledScreen2.jpeg
--------------------------------------------------------------------------------
/images/Web001-Beacons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web001-Beacons.png
--------------------------------------------------------------------------------
/images/Web002-StationConfig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web002-StationConfig.png
--------------------------------------------------------------------------------
/images/Web003-Display.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web003-Display.png
--------------------------------------------------------------------------------
/images/Web004-LoRa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web004-LoRa.png
--------------------------------------------------------------------------------
/images/Web005-WxTelemetry.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web005-WxTelemetry.png
--------------------------------------------------------------------------------
/images/Web006-Bluetooth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web006-Bluetooth.png
--------------------------------------------------------------------------------
/images/Web007-Battery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web007-Battery.png
--------------------------------------------------------------------------------
/images/Web008-Notifications.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web008-Notifications.png
--------------------------------------------------------------------------------
/images/Web009-PttTrigger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web009-PttTrigger.png
--------------------------------------------------------------------------------
/images/Web010-Winlink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web010-Winlink.png
--------------------------------------------------------------------------------
/images/Web011-WiFiAP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/Web011-WiFiAP.png
--------------------------------------------------------------------------------
/images/WebFlasherTrackerGithub.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/WebFlasherTrackerGithub.png
--------------------------------------------------------------------------------
/images/github-sponsors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/github-sponsors.png
--------------------------------------------------------------------------------
/images/paypalme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richonguzman/LoRa_APRS_Tracker/01ed8794464eb697d2807f0107f97734076e0006/images/paypalme.png
--------------------------------------------------------------------------------
/include/battery_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef BATTERY_UTILS_H_
2 | #define BATTERY_UTILS_H_
3 |
4 | #include
5 |
6 |
7 | namespace BATTERY_Utils {
8 |
9 | String generateEncodedTelemetry(float voltage);
10 | String getPercentVoltageBattery(float voltage);
11 | void checkVoltageWithoutGPSFix();
12 |
13 | }
14 |
15 | #endif
--------------------------------------------------------------------------------
/include/ble_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef BLE_UTILS_H_
2 | #define BLE_UTILS_H_
3 |
4 | #include
5 |
6 | namespace BLE_Utils {
7 |
8 | void stop();
9 | void setup();
10 | void sendToLoRa();
11 | void sendToPhone(const String& packet);
12 |
13 | }
14 |
15 | #endif
--------------------------------------------------------------------------------
/include/bluetooth_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef BLUETOOTH_UTILS_H
2 | #define BLUETOOTH_UTILS_H
3 |
4 | #include
5 |
6 | namespace BLUETOOTH_Utils {
7 |
8 | void setup();
9 | void bluetoothCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param);
10 | void getData(const uint8_t *buffer, size_t size);
11 | void sendToLoRa();
12 | void sendToPhone(const String& packet);
13 |
14 | }
15 |
16 | #endif
17 |
--------------------------------------------------------------------------------
/include/button_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef BUTTON_UTILS_H_
2 | #define BUTTON_UTILS_H_
3 |
4 | #include
5 |
6 | namespace BUTTON_Utils {
7 |
8 | void longPress();
9 | void doublePress();
10 |
11 | void loop();
12 | void setup();
13 |
14 | }
15 |
16 | #endif
--------------------------------------------------------------------------------
/include/configuration.h:
--------------------------------------------------------------------------------
1 | #ifndef CONFIGURATION_H_
2 | #define CONFIGURATION_H_
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | class WiFiAP {
9 | public:
10 | bool active;
11 | String password;
12 | };
13 |
14 | class Beacon {
15 | public:
16 | String callsign;
17 | String symbol;
18 | String overlay;
19 | String comment;
20 | bool smartBeaconActive;
21 | byte smartBeaconSetting;
22 | String micE;
23 | bool gpsEcoMode;
24 | };
25 |
26 | class Display {
27 | public:
28 | bool showSymbol;
29 | bool ecoMode;
30 | int timeout;
31 | bool turn180;
32 | };
33 |
34 | class Battery {
35 | public:
36 | bool sendVoltage;
37 | bool voltageAsTelemetry;
38 | bool sendVoltageAlways;
39 | bool monitorVoltage;
40 | float sleepVoltage;
41 | };
42 |
43 | class Winlink {
44 | public:
45 | String password;
46 | };
47 |
48 | class WXSENSOR {
49 | public:
50 | bool active;
51 | float temperatureCorrection;
52 | bool sendTelemetry;
53 | };
54 |
55 | class Notification {
56 | public:
57 | bool ledTx;
58 | int ledTxPin;
59 | bool ledMessage;
60 | int ledMessagePin;
61 | bool ledFlashlight;
62 | int ledFlashlightPin;
63 | bool buzzerActive;
64 | int buzzerPinTone;
65 | int buzzerPinVcc;
66 | bool bootUpBeep;
67 | bool txBeep;
68 | bool messageRxBeep;
69 | bool stationBeep;
70 | bool lowBatteryBeep;
71 | bool shutDownBeep;
72 | };
73 |
74 | class LoraType {
75 | public:
76 | long frequency;
77 | int spreadingFactor;
78 | long signalBandwidth;
79 | int codingRate4;
80 | int power;
81 | };
82 |
83 | class PTT {
84 | public:
85 | bool active;
86 | int io_pin;
87 | int preDelay;
88 | int postDelay;
89 | bool reverse;
90 | };
91 |
92 | class BLUETOOTH {
93 | public:
94 | bool active;
95 | String deviceName;
96 | bool useBLE;
97 | bool useKISS;
98 | };
99 |
100 |
101 | class Configuration {
102 | public:
103 |
104 | WiFiAP wifiAP;
105 | std::vector beacons;
106 | Display display;
107 | Battery battery;
108 | Winlink winlink;
109 | WXSENSOR wxsensor;
110 | Notification notification;
111 | std::vector loraTypes;
112 | PTT ptt;
113 | BLUETOOTH bluetooth;
114 |
115 | bool simplifiedTrackerMode;
116 | int sendCommentAfterXBeacons;
117 | String path;
118 | String email;
119 | int nonSmartBeaconRate;
120 | int rememberStationTime;
121 | int standingUpdateTime;
122 | bool sendAltitude;
123 | bool disableGPS;
124 | bool acceptOwnFrameFromTNC;
125 |
126 | void init();
127 | void writeFile();
128 | Configuration();
129 | bool validateConfigFile(const String& currentBeaconCallsign);
130 | bool validateMicE(const String& currentBeaconMicE);
131 |
132 | private:
133 | bool readFile();
134 | };
135 |
136 | #endif
--------------------------------------------------------------------------------
/include/custom_characters.h:
--------------------------------------------------------------------------------
1 | #ifndef CUSTOM_CHARACTERS_H_
2 | #define CUSTOM_CHARACTERS_H_
3 |
4 | #include
5 |
6 | static const unsigned char bluetoothSymbol[] PROGMEM = {
7 | 0b00001100, 0b00000000,
8 | 0b00001111, 0b00000000,
9 | 0b00001100, 0b11000000,
10 | 0b11001100, 0b00110000,
11 | 0b00111100, 0b11000000,
12 | 0b00001111, 0b00000000,
13 | 0b00001111, 0b00000000,
14 | 0b00111100, 0b11000000,
15 | 0b11001100, 0b00110000,
16 | 0b00001100, 0b11000000,
17 | 0b00001111, 0b00000000,
18 | 0b00001100, 0b00000000,
19 | 0b00000000, 0b00000000,
20 | 0b00000000, 0b00000000
21 | };
22 |
23 | static const unsigned char runnerSymbol[] PROGMEM = {
24 | 0b00000000, 0b11100000,
25 | 0b00000000, 0b11100000,
26 | 0b00000000, 0b01000110,
27 | 0b00000001, 0b11100110,
28 | 0b00000111, 0b11111100,
29 | 0b00000110, 0b11111000,
30 | 0b00001100, 0b11100000,
31 | 0b00001100, 0b11100000,
32 | 0b00000000, 0b11110000,
33 | 0b00000001, 0b11111000,
34 | 0b00000001, 0b10011000,
35 | 0b00000011, 0b10001100,
36 | 0b00001111, 0b00001100,
37 | 0b00011100, 0b00000110
38 | };
39 |
40 | static const unsigned char carSymbol[] PROGMEM = {
41 | 0b00000000, 0b00000000,
42 | 0b01000000, 0b00000000,
43 | 0b00111111, 0b11000000,
44 | 0b00100100, 0b00100000,
45 | 0b01000100, 0b00010000,
46 | 0b01000100, 0b00010000,
47 | 0b01000100, 0b00001000,
48 | 0b11111111, 0b11111111,
49 | 0b10111111, 0b11111101,
50 | 0b11111111, 0b11111111,
51 | 0b11001111, 0b11110011,
52 | 0b01001000, 0b00010010,
53 | 0b00110000, 0b00001100,
54 | 0b00000000, 0b00000000
55 | };
56 |
57 | static const unsigned char jeepSymbol[] PROGMEM = {
58 | 0b00000000, 0b00000000,
59 | 0b00000000, 0b00000000,
60 | 0b00000000, 0b00000000,
61 | 0b00000100, 0b01000000,
62 | 0b00001100, 0b00100000,
63 | 0b00010100, 0b00100000,
64 | 0b00100100, 0b00010000,
65 | 0b11111100, 0b00011111,
66 | 0b11111111, 0b11111101,
67 | 0b11111111, 0b11111111,
68 | 0b11001111, 0b11110011,
69 | 0b01001000, 0b00010010,
70 | 0b00110000, 0b00001100,
71 | 0b00000000, 0b00000000
72 | };
73 |
74 | static const unsigned char bikeSymbol[] PROGMEM = {
75 | 0b00000001, 0b10000000,
76 | 0b00000011, 0b11000000,
77 | 0b00000001, 0b10000000,
78 | 0b00000011, 0b10000000,
79 | 0b00000111, 0b11000000,
80 | 0b00001110, 0b11100000,
81 | 0b00001110, 0b01111000,
82 | 0b00011111, 0b11010000,
83 | 0b00110111, 0b00101100,
84 | 0b01001011, 0b10010010,
85 | 0b10110101, 0b11101101,
86 | 0b10110111, 0b10101101,
87 | 0b01001001, 0b10010010,
88 | 0b00110000, 0b00001100
89 | };
90 |
91 | static const unsigned char motorcycleSymbol[] PROGMEM = {
92 | 0b00000001, 0b10000000,
93 | 0b00000011, 0b11000000,
94 | 0b00000001, 0b10000000,
95 | 0b00000011, 0b10000000,
96 | 0b00000111, 0b11001000,
97 | 0b00001110, 0b11100100,
98 | 0b11101110, 0b01111110,
99 | 0b01111111, 0b11111110,
100 | 0b00110111, 0b00101100,
101 | 0b01001011, 0b10010010,
102 | 0b10110101, 0b11101101,
103 | 0b11111111, 0b10101101,
104 | 0b01001001, 0b10010010,
105 | 0b00110000, 0b00001100
106 | };
107 |
108 | static const unsigned char shipSymbol[] PROGMEM = {
109 | 0b00100000, 0b00000000,
110 | 0b00010000, 0b00000000,
111 | 0b00001000, 0b00000000,
112 | 0b00111111, 0b10000000,
113 | 0b00001111, 0b11000000,
114 | 0b00001100, 0b00100000,
115 | 0b00001100, 0b00010000,
116 | 0b01001100, 0b00001000,
117 | 0b01111111, 0b11111111,
118 | 0b10000000, 0b00000001,
119 | 0b11111111, 0b11111110,
120 | 0b11111111, 0b11111000,
121 | 0b00000000, 0b00000000,
122 | 0b00000000, 0b00000000
123 | };
124 |
125 | static const unsigned char truck18Symbol[] PROGMEM = {
126 | 0b00000000, 0b00100000,
127 | 0b00000000, 0b00010000,
128 | 0b11111111, 0b11010000,
129 | 0b11111111, 0b11011111,
130 | 0b11111111, 0b11011001,
131 | 0b11111111, 0b11011001,
132 | 0b11111111, 0b11011001,
133 | 0b11111111, 0b11011111,
134 | 0b11111111, 0b11011111,
135 | 0b11111111, 0b11011101,
136 | 0b10000000, 0b01111111,
137 | 0b11111111, 0b10000001,
138 | 0b01111101, 0b11111111,
139 | 0b01101100, 0b11000110
140 | };
141 |
142 | static const unsigned char recreationalVehicleSymbol[] PROGMEM = {
143 | 0b00000111, 0b11111000,
144 | 0b01111110, 0b01001100,
145 | 0b11111110, 0b01001110,
146 | 0b11111111, 0b11111110,
147 | 0b11111111, 0b11111000,
148 | 0b10000100, 0b00100100,
149 | 0b10000100, 0b00100010,
150 | 0b11111100, 0b00100001,
151 | 0b11111011, 0b11011111,
152 | 0b10111011, 0b11011101,
153 | 0b11111000, 0b00011101,
154 | 0b11001111, 0b11110011,
155 | 0b01001000, 0b00010010,
156 | 0b00110000, 0b00001100
157 | };
158 |
159 | static const unsigned char vanSymbol[] PROGMEM = {
160 | 0b00000000, 0b00000000,
161 | 0b00000000, 0b00000000,
162 | 0b01111111, 0b11110000,
163 | 0b11111111, 0b11111000,
164 | 0b10000100, 0b00100100,
165 | 0b10000100, 0b00100010,
166 | 0b10000100, 0b00100001,
167 | 0b11111111, 0b11111111,
168 | 0b10100000, 0b00000101,
169 | 0b11111111, 0b11111101,
170 | 0b11001111, 0b11100111,
171 | 0b01001000, 0b00100100,
172 | 0b00110000, 0b00011000,
173 | 0b00000000, 0b00000000
174 | };
175 |
176 | static const unsigned char carsateliteSymbol[] PROGMEM = {
177 | 0b00000000, 0b00000100,
178 | 0b01000000, 0b00000100,
179 | 0b00111111, 0b11011111,
180 | 0b00100100, 0b00100100,
181 | 0b01000100, 0b00010100,
182 | 0b01000100, 0b00010000,
183 | 0b01000100, 0b00001000,
184 | 0b11111111, 0b11111111,
185 | 0b10111111, 0b11111101,
186 | 0b11111111, 0b11111111,
187 | 0b11001111, 0b11110011,
188 | 0b01001000, 0b00010010,
189 | 0b00110000, 0b00001100,
190 | 0b00000000, 0b00000000
191 | };
192 |
193 | static const unsigned char tentSymbol[] PROGMEM = {
194 | 0b00000000, 0b00000000,
195 | 0b00000000, 0b00000000,
196 | 0b00001111, 0b11110000,
197 | 0b00001000, 0b00110000,
198 | 0b00010000, 0b01111000,
199 | 0b00010000, 0b01011000,
200 | 0b00100000, 0b10010100,
201 | 0b00100000, 0b10010100,
202 | 0b01000001, 0b00010010,
203 | 0b01000001, 0b00010010,
204 | 0b11100010, 0b00010001,
205 | 0b00011111, 0b11111111,
206 | 0b00000000, 0b00000000,
207 | 0b00000000, 0b00000000
208 | };
209 |
210 | static const unsigned char houseSymbol[] PROGMEM = {
211 | 0b00000011, 0b11000000,
212 | 0b00000111, 0b11100000,
213 | 0b00001111, 0b11110110,
214 | 0b00011111, 0b11111110,
215 | 0b00111111, 0b11111110,
216 | 0b01111111, 0b11111110,
217 | 0b11111111, 0b11111111,
218 | 0b01000000, 0b00000010,
219 | 0b01001111, 0b10111010,
220 | 0b01001000, 0b10101010,
221 | 0b01001001, 0b10111010,
222 | 0b01001000, 0b10000010,
223 | 0b01001000, 0b10000010,
224 | 0b01111111, 0b11111110
225 | };
226 |
227 | static const unsigned char truckSymbol[] PROGMEM = {
228 | 0b00000000, 0b00000000,
229 | 0b00000011, 0b11100000,
230 | 0b00000010, 0b00100000,
231 | 0b00000010, 0b00010000,
232 | 0b00000010, 0b00010000,
233 | 0b00000010, 0b00001000,
234 | 0b11111111, 0b11111111,
235 | 0b11111111, 0b11111101,
236 | 0b11111111, 0b11111101,
237 | 0b11111111, 0b11111111,
238 | 0b11001111, 0b11110011,
239 | 0b01001000, 0b00010010,
240 | 0b00110000, 0b00001100,
241 | 0b00000000, 0b00000000
242 | };
243 |
244 | static const unsigned char canoeSymbol[] PROGMEM = {
245 | 0b00000000, 0b00000000,
246 | 0b00000001, 0b10000000,
247 | 0b00000011, 0b11000000,
248 | 0b00000001, 0b10000000,
249 | 0b00000011, 0b10000000,
250 | 0b00000011, 0b11110000,
251 | 0b00000011, 0b00100000,
252 | 0b11111111, 0b11111111,
253 | 0b01000000, 0b10000010,
254 | 0b00111111, 0b11111100,
255 | 0b00000010, 0b00000000,
256 | 0b00001110, 0b00000000,
257 | 0b00011100, 0b00000000,
258 | 0b00000000, 0b00000000
259 | };
260 |
261 | static const unsigned char ambulanceSymbol[] PROGMEM = {
262 | 0b00000000, 0b00000000,
263 | 0b11111111, 0b11000000,
264 | 0b11111111, 0b11000000,
265 | 0b11110111, 0b11000000,
266 | 0b11110111, 0b11110000,
267 | 0b11000001, 0b11001000,
268 | 0b11110111, 0b11001000,
269 | 0b11110111, 0b11000100,
270 | 0b11111111, 0b11111111,
271 | 0b10000000, 0b00000011,
272 | 0b11111111, 0b11111101,
273 | 0b11001111, 0b11100111,
274 | 0b01001000, 0b00100100,
275 | 0b00110000, 0b00011000
276 | };
277 |
278 | static const unsigned char yatchSymbol[] PROGMEM = {
279 | 0b00000000, 0b01000000,
280 | 0b00000001, 0b01010000,
281 | 0b00000001, 0b01010000,
282 | 0b00000011, 0b01011000,
283 | 0b00000111, 0b01011000,
284 | 0b00001111, 0b01011100,
285 | 0b00011111, 0b01011100,
286 | 0b00111111, 0b01011110,
287 | 0b01111111, 0b01011110,
288 | 0b00000001, 0b01000000,
289 | 0b00000010, 0b10110000,
290 | 0b00111111, 0b11111111,
291 | 0b01100000, 0b00000010,
292 | 0b01111111, 0b11111100
293 | };
294 |
295 | static const unsigned char baloonSymbol[] PROGMEM = {
296 | 0b00001111, 0b11110000,
297 | 0b00111111, 0b11111100,
298 | 0b01000000, 0b00000010,
299 | 0b01111111, 0b11111110,
300 | 0b01111111, 0b11111110,
301 | 0b01000000, 0b00000010,
302 | 0b00111111, 0b11111100,
303 | 0b00011111, 0b11111000,
304 | 0b00001000, 0b00010000,
305 | 0b00000111, 0b11100000,
306 | 0b00000011, 0b11000000,
307 | 0b00000001, 0b10000000,
308 | 0b00000001, 0b10000000,
309 | 0b00000001, 0b10000000
310 | };
311 |
312 | static const unsigned char aircraftSymbol[] PROGMEM = {
313 | 0b00000001, 0b10000000,
314 | 0b00000001, 0b10000000,
315 | 0b00000001, 0b10000000,
316 | 0b00000001, 0b10000000,
317 | 0b00000111, 0b11100000,
318 | 0b00111111, 0b11111100,
319 | 0b11111111, 0b11111111,
320 | 0b11111111, 0b11111111,
321 | 0b11100001, 0b10000111,
322 | 0b00000001, 0b10000000,
323 | 0b00000001, 0b10000000,
324 | 0b00000001, 0b10000000,
325 | 0b00000011, 0b11000000,
326 | 0b00000111, 0b11100000
327 | };
328 |
329 | static const unsigned char trainSymbol[] PROGMEM = {
330 | 0b00000000, 0b00110000,
331 | 0b11111110, 0b00000000,
332 | 0b10000100, 0b01111000,
333 | 0b10000100, 0b00110000,
334 | 0b10000100, 0b00110000,
335 | 0b10000100, 0b00110000,
336 | 0b11111111, 0b11111100,
337 | 0b11111111, 0b11111110,
338 | 0b11111111, 0b11111110,
339 | 0b11111111, 0b11111100,
340 | 0b11111111, 0b11111110,
341 | 0b01000011, 0b00110011,
342 | 0b00100111, 0b00110010,
343 | 0b00011000, 0b11001100
344 | };
345 |
346 | static const unsigned char yagiSymbol[] PROGMEM = {
347 | 0b01010000, 0b00000000,
348 | 0b11110001, 0b10000000,
349 | 0b01000111, 0b11100000,
350 | 0b01011111, 0b11111000,
351 | 0b01111111, 0b11111110,
352 | 0b11111111, 0b11111111,
353 | 0b01000000, 0b00000010,
354 | 0b01011000, 0b00011010,
355 | 0b01011000, 0b00011010,
356 | 0b01000011, 0b11000010,
357 | 0b01000010, 0b01000010,
358 | 0b01000010, 0b11000010,
359 | 0b01000010, 0b01000010,
360 | 0b01111111, 0b11111110
361 | };
362 |
363 | static const unsigned char busSymbol[] PROGMEM = {
364 | 0b00000000, 0b00000000,
365 | 0b00000000, 0b00000000,
366 | 0b11111111, 0b11110000,
367 | 0b10001000, 0b10010000,
368 | 0b10001000, 0b10010000,
369 | 0b10001000, 0b10010000,
370 | 0b11111111, 0b11111110,
371 | 0b10000000, 0b00000011,
372 | 0b10000000, 0b00000001,
373 | 0b10011000, 0b00011001,
374 | 0b11100111, 0b11100111,
375 | 0b00100100, 0b00100100,
376 | 0b00011000, 0b00011000,
377 | 0b00000000, 0b00000000
378 | };
379 |
380 | static const unsigned char dogSymbol[] PROGMEM = {
381 | 0b00000000, 0b01100000,
382 | 0b00000000, 0b10010000,
383 | 0b00000001, 0b00001000,
384 | 0b00000001, 0b00101010,
385 | 0b01000001, 0b00000101,
386 | 0b10100001, 0b00100010,
387 | 0b10010001, 0b11100010,
388 | 0b01001111, 0b10111100,
389 | 0b00100000, 0b00010000,
390 | 0b00100000, 0b00010000,
391 | 0b01001111, 0b11001000,
392 | 0b01010000, 0b00101000,
393 | 0b01001000, 0b00100100,
394 | 0b00110000, 0b00011000
395 | };
396 |
397 | static const unsigned char wxSymbol[] PROGMEM = {
398 | 0b00000000, 0b00000000,
399 | 0b00000000, 0b00000000,
400 | 0b10001000, 0b10000000,
401 | 0b10001000, 0b10000000,
402 | 0b10001000, 0b10000000,
403 | 0b10001000, 0b10000000,
404 | 0b01010101, 0b00100010,
405 | 0b01010101, 0b00010100,
406 | 0b01010101, 0b00001000,
407 | 0b01010101, 0b00010100,
408 | 0b00100010, 0b00100010,
409 | 0b00000000, 0b00000000,
410 | 0b00000000, 0b00000000,
411 | 0b00000000, 0b00000000
412 | };
413 |
414 | /*static const unsigned char noSymbol[] PROGMEM = {
415 | 0b00000000, 0b00000000,
416 | 0b00000000, 0b00000000,
417 | 0b00000000, 0b00000000,
418 | 0b00000000, 0b00000000,
419 | 0b00000000, 0b00000000,
420 | 0b00000000, 0b00000000,
421 | 0b00000000, 0b00000000,
422 | 0b00000000, 0b00000000,
423 | 0b00000000, 0b00000000,
424 | 0b00000000, 0b00000000,
425 | 0b00000000, 0b00000000,
426 | 0b00000000, 0b00000000,
427 | 0b00000000, 0b00000000,
428 | 0b00000000, 0b00000000
429 | };*/
430 |
431 | #endif
--------------------------------------------------------------------------------
/include/custom_colors.h:
--------------------------------------------------------------------------------
1 | #ifndef CUSTOM_COLORS_H_
2 | #define CUSTOM_COLORS_H_
3 |
4 | #include
5 |
6 |
7 | // COLORS https://rgbcolorpicker.com/565
8 |
9 | uint16_t redColor = 0xc8a2;
10 | uint16_t redColorLight = 0xd8c4;
11 | uint16_t redColorDark = 0xa082;
12 |
13 | uint16_t greyColor = 0x7BEF;
14 | uint16_t greyColorLight = 0xBDF7;
15 | uint16_t greyColorDark = 0x39E7;
16 |
17 | uint16_t greenColor = 0x1482;
18 | uint16_t greenColorLight = 0x1d63;
19 | uint16_t greenColorDark = 0x0b22;
20 |
21 | #endif
--------------------------------------------------------------------------------
/include/display.h:
--------------------------------------------------------------------------------
1 | #ifndef DISPLAY_H_
2 | #define DISPLAY_H_
3 |
4 | #include
5 |
6 | void displaySetup();
7 | void displayToggle(bool toggle);
8 |
9 | void displayShow(const String& header, const String& line1, const String& line2, int wait = 0);
10 | void displayShow(const String& header, const String& line1, const String& line2, const String& line3, const String& line4, const String& line5, int wait = 0);
11 |
12 | void startupScreen(uint8_t index, const String& version);
13 |
14 | #endif
--------------------------------------------------------------------------------
/include/gps_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef GPS_UTILS_H_
2 | #define GPS_UTILS_H_
3 |
4 | #include
5 |
6 | namespace GPS_Utils {
7 |
8 | void setup();
9 | void calculateDistanceCourse(const String& callsign, double checkpointLatitude, double checkPointLongitude);
10 | void getData();
11 | void setDateFromData();
12 | void calculateDistanceTraveled();
13 | void calculateHeadingDelta(int speed);
14 | void checkStartUpFrames();
15 | String getCardinalDirection(float course);
16 |
17 | }
18 |
19 | #endif
--------------------------------------------------------------------------------
/include/joystick_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef JOYSTICK_UTILS_H_
2 | #define JOYSTICK_UTILS_H_
3 |
4 | #include
5 |
6 | namespace JOYSTICK_Utils {
7 |
8 | void loop();
9 | void setup();
10 |
11 | }
12 |
13 | #endif
--------------------------------------------------------------------------------
/include/keyboard_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef KEYBOARD_UTILS_H
2 | #define KEYBOARD_UTILS_H
3 |
4 | #include
5 |
6 | namespace KEYBOARD_Utils {
7 |
8 | void upArrow();
9 | void downArrow();
10 | void leftArrow();
11 | void rightArrow();
12 |
13 | void processPressedKey(char key);
14 | void read();
15 |
16 | void setup();
17 |
18 | }
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/include/kiss_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef KISS_UTILS_H
2 | #define KISS_UTILS_H
3 |
4 | #include
5 |
6 |
7 | enum KissChar {
8 | FEND = 0xc0,
9 | FESC = 0xdb,
10 | TFEND = 0xdc,
11 | TFESC = 0xdd
12 | };
13 |
14 | enum KissCmd {
15 | Data = 0x00
16 | };
17 |
18 | enum AX25Char {
19 | ControlField = 0x03,
20 | InformationField = 0xF0
21 | };
22 |
23 | #define HAS_BEEN_DIGIPITED_MASK 0b10000000
24 | #define IS_LAST_ADDRESS_POSITION_MASK 0b1
25 |
26 |
27 | namespace KISS_Utils {
28 |
29 | bool validateTNC2Frame(const String& tnc2FormattedFrame);
30 | bool validateKISSFrame(const String& kissFormattedFrame);
31 |
32 | String encodeKISS(const String& frame);
33 | String decodeKISS(const String& inputFrame, bool& dataFrame);
34 |
35 | //String encapsulateKISS(const String& ax25Frame, uint8_t command);
36 | //String decapsulateKISS(const String& frame);
37 |
38 | }
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/include/lora_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef LORA_UTILS_H_
2 | #define LORA_UTILS_H_
3 |
4 | #include
5 |
6 | struct ReceivedLoRaPacket {
7 | String text;
8 | int rssi;
9 | float snr;
10 | int freqError;
11 | };
12 |
13 |
14 | namespace LoRa_Utils {
15 |
16 | void setFlag();
17 | void changeFreq();
18 | void setup();
19 | void sendNewPacket(const String& newPacket);
20 | void wakeRadio();
21 | ReceivedLoRaPacket receiveFromSleep();
22 | ReceivedLoRaPacket receivePacket();
23 | void sleepRadio();
24 |
25 | }
26 |
27 | #endif
--------------------------------------------------------------------------------
/include/menu_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef MENU_UTILS_H_
2 | #define MENU_UTILS_H_
3 |
4 | #include
5 |
6 | namespace MENU_Utils {
7 |
8 | const String checkBTType();
9 | const String checkProcessActive(const bool process);
10 | const String screenBrightnessAsString(const uint8_t bright);
11 | void showOnScreen();
12 |
13 | }
14 |
15 | #endif
--------------------------------------------------------------------------------
/include/msg_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef MSG_UTILS_H_
2 | #define MSG_UTILS_H_
3 |
4 | #include
5 | #include "lora_utils.h"
6 |
7 | struct Packet15SegBuffer {
8 | uint32_t receivedTime;
9 | String station;
10 | String payload;
11 | };
12 |
13 | namespace MSG_Utils {
14 |
15 | bool warnNoAPRSMessages();
16 | bool warnNoWLNKMails();
17 | const String getLastHeardTracker();
18 | int getNumAPRSMessages();
19 | int getNumWLNKMails();
20 | void loadNumMessages();
21 | void loadMessagesFromMemory(uint8_t typeOfMessage);
22 | void ledNotification();
23 | void deleteFile(uint8_t typeOfFile);
24 | void saveNewMessage(uint8_t typeMessage, const String& station, const String& newMessage);
25 | void sendMessage(const String& station, const String& textMessage);
26 | const String ackRequestNumberGenerator();
27 | void addToOutputBuffer(uint8_t typeOfMessage, const String& station, const String& textMessage);
28 | void processOutputBuffer();
29 | void clean15SegBuffer();
30 | bool check15SegBuffer(const String& station, const String& textMessage);
31 | void checkReceivedMessage(ReceivedLoRaPacket packetReceived);
32 |
33 | }
34 |
35 | #endif
--------------------------------------------------------------------------------
/include/notification_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef NOTIFICATION_UTILS_H_
2 | #define NOTIFICATION_UTILS_H_
3 |
4 | #include
5 |
6 | namespace NOTIFICATION_Utils {
7 |
8 | void playTone(int frequency, uint8_t duration);
9 | void beaconTxBeep();
10 | void messageBeep();
11 | void stationHeardBeep();
12 | void shutDownBeep();
13 | void lowBatteryBeep();
14 | void start();
15 |
16 | }
17 |
18 | #endif
--------------------------------------------------------------------------------
/include/power_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef POWER_UTILS_H_
2 | #define POWER_UTILS_H_
3 |
4 | #include
5 | #include "board_pinout.h"
6 | #if defined(HAS_AXP2101) || defined(HAS_AXP192)
7 | #include "XPowersLib.h"
8 | #else
9 | #include
10 | #endif
11 |
12 | namespace POWER_Utils {
13 |
14 | double getBatteryVoltage();
15 | const String getBatteryInfoVoltage();
16 | const String getBatteryInfoCurrent();
17 | bool getBatteryInfoIsConnected();
18 |
19 | void enableChgLed();
20 | void disableChgLed();
21 |
22 | bool isCharging();
23 | void handleChargingLed();
24 | double getBatteryChargeDischargeCurrent();
25 | bool isBatteryConnected();
26 | void obtainBatteryInfo();
27 | void batteryManager();
28 |
29 | void activateMeasurement();
30 |
31 | void activateGPS();
32 | void deactivateGPS();
33 |
34 | void activateLoRa();
35 | void deactivateLoRa();
36 |
37 | void externalPinSetup();
38 |
39 | bool begin(TwoWire &port);
40 | void setup();
41 |
42 | void lowerCpuFrequency();
43 | void shutdown();
44 |
45 | }
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/include/sleep_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef SLEEP_UTILS_H_
2 | #define SLEEP_UTILS_H_
3 |
4 | #include
5 |
6 | namespace SLEEP_Utils {
7 |
8 | void gpsSleep();
9 | void gpsWakeUp();
10 | void checkIfGPSShouldSleep();
11 |
12 | }
13 |
14 | #endif
--------------------------------------------------------------------------------
/include/smartbeacon_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef SMARTBEACON_UTILS_H_
2 | #define SMARTBEACON_UTILS_H_
3 |
4 | #include
5 |
6 | struct SmartBeaconValues {
7 | int slowRate;
8 | int slowSpeed;
9 | int fastRate;
10 | int fastSpeed;
11 | int minTxDist;
12 | int minDeltaBeacon;
13 | int turnMinDeg;
14 | int turnSlope;
15 | };
16 |
17 |
18 | namespace SMARTBEACON_Utils {
19 |
20 | void checkSettings(byte index);
21 | void checkInterval(int speed);
22 | void checkFixedBeaconTime();
23 | void checkState();
24 |
25 | }
26 |
27 | #endif
--------------------------------------------------------------------------------
/include/station_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef STATION_UTILS_H_
2 | #define STATION_UTILS_H_
3 |
4 | #include
5 |
6 | namespace STATION_Utils {
7 |
8 | void nearTrackerInit();
9 | const String getNearTracker(uint8_t position);
10 |
11 | void deleteListenedTrackersbyTime();
12 | void checkListenedTrackersByTimeAndDelete();
13 | void orderListenedTrackersByDistance(const String& callsign, float distance, float course);
14 |
15 | void checkStandingUpdateTime();
16 | void sendBeacon(uint8_t type);
17 | void checkTelemetryTx();
18 | void saveIndex(uint8_t type, uint8_t index);
19 | void loadIndex(uint8_t type);
20 |
21 | }
22 |
23 | #endif
--------------------------------------------------------------------------------
/include/touch_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef TOUCH_UTILS_H_
2 | #define TOUCH_UTILS_H_
3 |
4 | #include
5 |
6 |
7 | struct TouchButton {
8 | int Xmin;
9 | int Xmax;
10 | int Ymin;
11 | int Ymax;
12 | String label; // Optional: for button text or identification
13 | int color;
14 | void (*action)(); // Pointer to a function for button press action
15 | };
16 |
17 |
18 | namespace TOUCH_Utils {
19 |
20 | void loop();
21 | void setup();
22 |
23 | }
24 |
25 | #endif
--------------------------------------------------------------------------------
/include/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H_
2 | #define UTILS_H_
3 |
4 | #include
5 | #include
6 |
7 | namespace Utils {
8 |
9 | char *getMaidenheadLocator(double lat, double lon, uint8_t size);
10 | String createDateString(time_t t);
11 | String createTimeString(time_t t);
12 | void checkStatus();
13 | void checkDisplayEcoMode();
14 | String getSmartBeaconState();
15 | void checkFlashlight();
16 | void i2cScannerForPeripherals();
17 |
18 | }
19 |
20 | #endif
--------------------------------------------------------------------------------
/include/web_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef WEB_UTILS_H_
2 | #define WEB_UTILS_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 |
11 | namespace WEB_Utils {
12 |
13 | void handleNotFound(AsyncWebServerRequest *request);
14 | void handleStatus(AsyncWebServerRequest *request);
15 | void handleHome(AsyncWebServerRequest *request);
16 | void handleStyle(AsyncWebServerRequest *request);
17 | void handleScript(AsyncWebServerRequest *request);
18 | void handleBootstrapStyle(AsyncWebServerRequest *request);
19 | void handleBootstrapScript(AsyncWebServerRequest *request);
20 |
21 | void setup();
22 |
23 | }
24 |
25 | #endif
--------------------------------------------------------------------------------
/include/wifi_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef WIFI_UTILS_H_
2 | #define WIFI_UTILS_H_
3 |
4 | #include
5 |
6 |
7 | namespace WIFI_Utils {
8 |
9 | void startAutoAP();
10 | void checkIfWiFiAP();
11 |
12 | }
13 |
14 | #endif
--------------------------------------------------------------------------------
/include/winlink_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef WINLINK_UTILS_H_
2 | #define WINLINK_UTILS_H_
3 |
4 | #include
5 |
6 | namespace WINLINK_Utils {
7 |
8 | void processWinlinkChallenge(const String& winlinkInteger);
9 | void login();
10 |
11 | }
12 |
13 | #endif
--------------------------------------------------------------------------------
/include/wx_utils.h:
--------------------------------------------------------------------------------
1 | #ifndef WX_UTILS_H_
2 | #define WX_UTILS_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 |
11 | namespace WX_Utils {
12 |
13 | void setup();
14 | const String generateTempString(const float sensorTemp, const uint8_t type);
15 | const String generateHumString(const float sensorHum, const uint8_t type);
16 | const String generatePresString(const float sensorPress, const uint8_t type);
17 | const String readDataSensor(const uint8_t type);
18 |
19 | }
20 |
21 | #endif
--------------------------------------------------------------------------------
/platformio.ini:
--------------------------------------------------------------------------------
1 | ; PlatformIO Project Configuration File
2 | ;
3 | ; Build options: build flags, source filter
4 | ; Upload options: custom upload port, speed and extra flags
5 | ; Library options: dependencies, extra library storages
6 | ; Advanced options: extra scripting
7 | ;
8 | ; Please visit documentation for the other options and examples
9 | ; https://docs.platformio.org/page/projectconf.html
10 |
11 | [platformio]
12 | default_envs = ttgo-t-beam-v1_2
13 |
14 | extra_configs =
15 | common_settings.ini
16 | variants/*/platformio.ini
17 |
18 | [env]
19 | framework = arduino
20 | monitor_speed = 115200
21 | lib_ldf_mode = deep+
22 |
23 | [env:esp32]
24 | extends = env
25 | platform = espressif32 @ 6.7.0
26 | board_build.partitions = huge_app.csv
27 | monitor_filters = esp32_exception_decoder
28 | board_build.embed_files =
29 | data_embed/index.html.gz
30 | data_embed/style.css.gz
31 | data_embed/script.js.gz
32 | data_embed/bootstrap.css.gz
33 | data_embed/bootstrap.js.gz
34 | data_embed/favicon.png.gz
35 | extra_scripts =
36 | pre:tools/compress.py
37 | debug_tool = esp-prog
--------------------------------------------------------------------------------
/src/LoRa_APRS_Tracker.cpp:
--------------------------------------------------------------------------------
1 | /*___________________________________________________________________
2 |
3 | ██╗ ██████╗ ██████╗ █████╗ █████╗ ██████╗ ██████╗ ███████╗
4 | ██║ ██╔═══██╗██╔══██╗██╔══██╗ ██╔══██╗██╔══██╗██╔══██╗██╔════╝
5 | ██║ ██║ ██║██████╔╝███████║ ███████║██████╔╝██████╔╝███████╗
6 | ██║ ██║ ██║██╔══██╗██╔══██║ ██╔══██║██╔═══╝ ██╔══██╗╚════██║
7 | ███████╗╚██████╔╝██║ ██║██║ ██║ ██║ ██║██║ ██║ ██║███████║
8 | ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚══════╝
9 |
10 | ████████╗██████╗ █████╗ ██████╗██╗ ██╗███████╗██████╗
11 | ╚══██╔══╝██╔══██╗██╔══██╗██╔════╝██║ ██╔╝██╔════╝██╔══██╗
12 | ██║ ██████╔╝███████║██║ █████╔╝ █████╗ ██████╔╝
13 | ██║ ██╔══██╗██╔══██║██║ ██╔═██╗ ██╔══╝ ██╔══██╗
14 | ██║ ██║ ██║██║ ██║╚██████╗██║ ██╗███████╗██║ ██║
15 | ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
16 |
17 | Ricardo Guzman - CA2RXU
18 | https://github.com/richonguzman/LoRa_APRS_Tracker
19 | (donations : http://paypal.me/richonguzman)
20 | ____________________________________________________________________*/
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include "smartbeacon_utils.h"
29 | #include "bluetooth_utils.h"
30 | #include "keyboard_utils.h"
31 | #include "joystick_utils.h"
32 | #include "configuration.h"
33 | #include "battery_utils.h"
34 | #include "station_utils.h"
35 | #include "board_pinout.h"
36 | #include "button_utils.h"
37 | #include "power_utils.h"
38 | #include "sleep_utils.h"
39 | #include "menu_utils.h"
40 | #include "lora_utils.h"
41 | #include "wifi_utils.h"
42 | #include "msg_utils.h"
43 | #include "gps_utils.h"
44 | #include "web_utils.h"
45 | #include "ble_utils.h"
46 | #include "wx_utils.h"
47 | #include "display.h"
48 | #include "utils.h"
49 | #ifdef HAS_TOUCHSCREEN
50 | #include "touch_utils.h"
51 | #endif
52 |
53 | Configuration Config;
54 | HardwareSerial gpsSerial(1);
55 | TinyGPSPlus gps;
56 | #ifdef HAS_BT_CLASSIC
57 | BluetoothSerial SerialBT;
58 | #endif
59 |
60 | String versionDate = "2025.04.11";
61 |
62 | uint8_t myBeaconsIndex = 0;
63 | int myBeaconsSize = Config.beacons.size();
64 | Beacon *currentBeacon = &Config.beacons[myBeaconsIndex];
65 | uint8_t loraIndex = 0;
66 | int loraIndexSize = Config.loraTypes.size();
67 | LoraType *currentLoRaType = &Config.loraTypes[loraIndex];
68 |
69 | int menuDisplay = 100;
70 |
71 | bool statusState = true;
72 | bool displayEcoMode = Config.display.ecoMode;
73 | bool displayState = true;
74 | uint32_t displayTime = millis();
75 | uint32_t refreshDisplayTime = millis();
76 |
77 | bool sendUpdate = true;
78 |
79 | bool bluetoothActive = Config.bluetooth.active;
80 | bool bluetoothConnected = false;
81 |
82 | uint32_t lastTx = 0.0;
83 | uint32_t txInterval = 60000L;
84 | uint32_t lastTxTime = 0;
85 | double lastTxLat = 0.0;
86 | double lastTxLng = 0.0;
87 | double lastTxDistance = 0.0;
88 |
89 | uint32_t menuTime = millis();
90 |
91 | bool flashlight = false;
92 | bool digipeaterActive = false;
93 | bool sosActive = false;
94 |
95 | bool miceActive = false;
96 |
97 | bool smartBeaconActive = true;
98 |
99 | int ackRequestNumber;
100 |
101 | uint32_t lastGPSTime = 0;
102 |
103 | APRSPacket lastReceivedPacket;
104 |
105 | logging::Logger logger;
106 | //#define DEBUG
107 |
108 | extern bool gpsIsActive;
109 |
110 | void setup() {
111 | Serial.begin(115200);
112 |
113 | #ifndef DEBUG
114 | logger.setDebugLevel(logging::LoggerLevel::LOGGER_LEVEL_INFO);
115 | #endif
116 |
117 | POWER_Utils::setup();
118 | displaySetup();
119 | POWER_Utils::externalPinSetup();
120 |
121 | STATION_Utils::loadIndex(0); // callsign Index
122 | STATION_Utils::loadIndex(1); // lora freq settins Index
123 | STATION_Utils::nearTrackerInit();
124 | startupScreen(loraIndex, versionDate);
125 |
126 | WIFI_Utils::checkIfWiFiAP();
127 |
128 | MSG_Utils::loadNumMessages();
129 | GPS_Utils::setup();
130 | currentLoRaType = &Config.loraTypes[loraIndex];
131 | LoRa_Utils::setup();
132 | Utils::i2cScannerForPeripherals();
133 | WX_Utils::setup();
134 |
135 | ackRequestNumber = random(1,999);
136 |
137 | WiFi.mode(WIFI_OFF);
138 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "Main", "WiFi controller stopped");
139 |
140 | if (bluetoothActive) {
141 | if (Config.bluetooth.useBLE) {
142 | BLE_Utils::setup();
143 | } else {
144 | #ifdef HAS_BT_CLASSIC
145 | BLUETOOTH_Utils::setup();
146 | #endif
147 | }
148 | }
149 |
150 | if (!Config.simplifiedTrackerMode) {
151 | #ifdef BUTTON_PIN
152 | BUTTON_Utils::setup();
153 | #endif
154 | #ifdef HAS_JOYSTICK
155 | JOYSTICK_Utils::setup();
156 | #endif
157 | KEYBOARD_Utils::setup();
158 | #ifdef HAS_TOUCHSCREEN
159 | TOUCH_Utils::setup();
160 | #endif
161 | }
162 |
163 | POWER_Utils::lowerCpuFrequency();
164 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "Main", "Smart Beacon is: %s", Utils::getSmartBeaconState());
165 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "Setup Done!");
166 | menuDisplay = 0;
167 | }
168 |
169 | void loop() {
170 | currentBeacon = &Config.beacons[myBeaconsIndex];
171 | if (statusState) {
172 | if (Config.validateConfigFile(currentBeacon->callsign)) {
173 | KEYBOARD_Utils::rightArrow();
174 | currentBeacon = &Config.beacons[myBeaconsIndex];
175 | }
176 | miceActive = Config.validateMicE(currentBeacon->micE);
177 | }
178 | POWER_Utils::batteryManager();
179 |
180 | SMARTBEACON_Utils::checkSettings(currentBeacon->smartBeaconSetting);
181 | SMARTBEACON_Utils::checkState();
182 |
183 | if (!Config.simplifiedTrackerMode) {
184 | #ifdef BUTTON_PIN
185 | BUTTON_Utils::loop();
186 | #endif
187 | }
188 |
189 | Utils::checkDisplayEcoMode();
190 |
191 | KEYBOARD_Utils::read();
192 | #ifdef HAS_JOYSTICK
193 | JOYSTICK_Utils::loop();
194 | #endif
195 | #ifdef HAS_TOUCHSCREEN
196 | TOUCH_Utils::loop();
197 | #endif
198 |
199 |
200 | ReceivedLoRaPacket packet = LoRa_Utils::receivePacket();
201 |
202 | MSG_Utils::checkReceivedMessage(packet);
203 | MSG_Utils::processOutputBuffer();
204 | MSG_Utils::clean15SegBuffer();
205 |
206 | if (bluetoothActive && bluetoothConnected) {
207 | if (Config.bluetooth.useBLE) {
208 | BLE_Utils::sendToPhone(packet.text.substring(3));
209 | BLE_Utils::sendToLoRa();
210 | } else {
211 | #ifdef HAS_BT_CLASSIC
212 | BLUETOOTH_Utils::sendToPhone(packet.text.substring(3));
213 | BLUETOOTH_Utils::sendToLoRa();
214 | #endif
215 | }
216 | }
217 |
218 | MSG_Utils::ledNotification();
219 | Utils::checkFlashlight();
220 | STATION_Utils::checkListenedTrackersByTimeAndDelete();
221 |
222 | lastTx = millis() - lastTxTime;
223 | if (gpsIsActive) {
224 | GPS_Utils::getData();
225 | bool gps_time_update = gps.time.isUpdated();
226 | bool gps_loc_update = gps.location.isUpdated();
227 | GPS_Utils::setDateFromData();
228 |
229 | int currentSpeed = (int) gps.speed.kmph();
230 |
231 | if (gps_loc_update) {
232 | Utils::checkStatus();
233 | STATION_Utils::checkTelemetryTx();
234 | }
235 |
236 | if (!gps.location.isValid()) BATTERY_Utils::checkVoltageWithoutGPSFix();
237 |
238 | if (!sendUpdate && gps_loc_update && smartBeaconActive) {
239 | GPS_Utils::calculateDistanceTraveled();
240 | if (!sendUpdate) GPS_Utils::calculateHeadingDelta(currentSpeed);
241 | STATION_Utils::checkStandingUpdateTime();
242 | }
243 | SMARTBEACON_Utils::checkFixedBeaconTime();
244 | if (sendUpdate && gps_loc_update) STATION_Utils::sendBeacon(0);
245 | if (gps_time_update) SMARTBEACON_Utils::checkInterval(currentSpeed);
246 |
247 | if (millis() - refreshDisplayTime >= 1000 || gps_time_update) {
248 | GPS_Utils::checkStartUpFrames();
249 | MENU_Utils::showOnScreen();
250 | refreshDisplayTime = millis();
251 | }
252 | SLEEP_Utils::checkIfGPSShouldSleep();
253 | } else {
254 | if (millis() - lastGPSTime > txInterval) {
255 | SLEEP_Utils::gpsWakeUp();
256 | }
257 | STATION_Utils::checkStandingUpdateTime();
258 | if (millis() - refreshDisplayTime >= 1000) {
259 | MENU_Utils::showOnScreen();
260 | refreshDisplayTime = millis();
261 | }
262 | }
263 | }
264 |
265 | // eliminar keyboardConnected y reemplazar por validar si es distinto de 0x00 ?
--------------------------------------------------------------------------------
/src/battery_utils.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "battery_utils.h"
3 | #include "board_pinout.h"
4 | #include "power_utils.h"
5 | #include "display.h"
6 |
7 |
8 | int telemetryCounter = random(1,999);
9 | uint32_t lastNoGPSCheckTime = 0;
10 |
11 |
12 | namespace BATTERY_Utils {
13 |
14 | String generateEncodedTelemetryBytes(float value, bool firstBytes, byte voltageType) { // 0 = internal battery(0-4,2V) , 1 = external battery(0-15V)
15 | String encodedBytes;
16 | int tempValue;
17 |
18 | if (firstBytes) {
19 | tempValue = value;
20 | } else {
21 | switch (voltageType) {
22 | case 0:
23 | tempValue = value * 100; // Internal voltage calculation
24 | break;
25 | case 1:
26 | tempValue = (value * 100) / 2; // External voltage calculation
27 | break;
28 | default:
29 | tempValue = value;
30 | break;
31 | }
32 | }
33 |
34 | int firstByte = tempValue / 91;
35 | tempValue -= firstByte * 91;
36 |
37 | encodedBytes = char(firstByte + 33);
38 | encodedBytes += char(tempValue + 33);
39 | return encodedBytes;
40 | }
41 |
42 | String generateEncodedTelemetry(float voltage) {
43 | String telemetry = "|";
44 | telemetry += generateEncodedTelemetryBytes(telemetryCounter, true, 0);
45 | telemetryCounter++;
46 | if (telemetryCounter == 1000) {
47 | telemetryCounter = 0;
48 | }
49 | telemetry += generateEncodedTelemetryBytes(voltage, false, 0);
50 | telemetry += "|";
51 | return telemetry;
52 | }
53 |
54 | String getPercentVoltageBattery(float voltage) {
55 | int percent = ((voltage - 3.0) / (4.2 - 3.0)) * 100;
56 | return (percent < 100) ? (((percent < 10) ? " ": " ") + String(percent)) : "100";
57 | }
58 |
59 | void checkVoltageWithoutGPSFix() {
60 | #ifdef BATTERY_PIN
61 | if (lastNoGPSCheckTime == 0 || millis() - lastNoGPSCheckTime > 15 * 60 * 1000) {
62 | String batteryVoltage = POWER_Utils::getBatteryInfoVoltage();
63 | if (batteryVoltage.toFloat() < 3.0) {
64 | displayShow("!BATTERY!", "", "LOW BATTERY VOLTAGE!",5000);
65 | POWER_Utils::shutdown();
66 | }
67 | lastNoGPSCheckTime = millis();
68 | }
69 | #endif
70 | }
71 |
72 | }
--------------------------------------------------------------------------------
/src/ble_utils.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "configuration.h"
3 | #include "lora_utils.h"
4 | #include "kiss_utils.h"
5 | #include "ble_utils.h"
6 | #include "display.h"
7 | #include "logger.h"
8 |
9 | #define BLE_CHUNK_SIZE 256
10 |
11 |
12 | // APPLE - APRS.fi app
13 | #define SERVICE_UUID_0 "00000001-ba2a-46c9-ae49-01b0961f68bb"
14 | #define CHARACTERISTIC_UUID_TX_0 "00000003-ba2a-46c9-ae49-01b0961f68bb"
15 | #define CHARACTERISTIC_UUID_RX_0 "00000002-ba2a-46c9-ae49-01b0961f68bb"
16 |
17 | // ANDROID - BLE Terminal app (Serial Bluetooth Terminal from Playstore)
18 | #define SERVICE_UUID_1 "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
19 | #define CHARACTERISTIC_UUID_TX_1 "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
20 | #define CHARACTERISTIC_UUID_RX_1 "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
21 |
22 | BLEServer *pServer;
23 | BLECharacteristic *pCharacteristicTx;
24 | BLECharacteristic *pCharacteristicRx;
25 |
26 | extern Configuration Config;
27 | extern Beacon *currentBeacon;
28 | extern logging::Logger logger;
29 | extern bool bluetoothConnected;
30 | extern bool bluetoothActive;
31 |
32 | bool shouldSendBLEtoLoRa = false;
33 | String BLEToLoRaPacket = "";
34 | String kissSerialBuffer = "";
35 |
36 |
37 | class MyServerCallbacks : public NimBLEServerCallbacks {
38 | void onConnect(NimBLEServer* pServer) {
39 | bluetoothConnected = true;
40 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BLE", "%s", "BLE Client Connected");
41 | delay(100);
42 | }
43 |
44 | void onDisconnect(NimBLEServer* pServer) {
45 | bluetoothConnected = false;
46 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BLE", "%s", "BLE client Disconnected, Started Advertising");
47 | delay(100);
48 | pServer->startAdvertising();
49 | }
50 | };
51 |
52 | class MyCallbacks : public NimBLECharacteristicCallbacks {
53 | void onWrite(NimBLECharacteristic *pCharacteristic) {
54 | if (Config.bluetooth.useKISS) { // KISS (AX.25)
55 | std::string receivedData = pCharacteristic->getValue();
56 | delay(100);
57 | for (int i = 0; i < receivedData.length(); i++) {
58 | char character = receivedData[i];
59 |
60 | if (kissSerialBuffer.length() == 0 && character != (char)KissChar::FEND) continue;
61 | kissSerialBuffer += receivedData[i];
62 |
63 | if (character == (char)KissChar::FEND && kissSerialBuffer.length() > 3) {
64 | bool isDataFrame = false;
65 |
66 | BLEToLoRaPacket = KISS_Utils::decodeKISS(kissSerialBuffer, isDataFrame);
67 |
68 | if (isDataFrame) {
69 | shouldSendBLEtoLoRa = true;
70 | kissSerialBuffer = "";
71 | }
72 | }
73 | }
74 | } else { // TNC2
75 | std::string receivedData = pCharacteristic->getValue();
76 | String receivedString = "";
77 | for (int i = 0; i < receivedData.length(); i++) receivedString += receivedData[i];
78 | BLEToLoRaPacket = receivedString;
79 | shouldSendBLEtoLoRa = true;
80 | }
81 | }
82 | };
83 |
84 |
85 | namespace BLE_Utils {
86 |
87 | void stop() {
88 | BLEDevice::deinit();
89 | }
90 |
91 | void setup() {
92 | String BLEid = Config.bluetooth.deviceName;
93 | BLEDevice::init(BLEid.c_str());
94 | pServer = BLEDevice::createServer();
95 | pServer->setCallbacks(new MyServerCallbacks());
96 |
97 | BLEService *pService = nullptr;
98 |
99 | // KISS (AX.25) or TNC2
100 | bool useKISS = Config.bluetooth.useKISS;
101 | pService = pServer->createService(useKISS ? SERVICE_UUID_0 : SERVICE_UUID_1);
102 | pCharacteristicTx = pService->createCharacteristic(useKISS ? CHARACTERISTIC_UUID_TX_0 : CHARACTERISTIC_UUID_TX_1, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
103 | pCharacteristicRx = pService->createCharacteristic(useKISS ? CHARACTERISTIC_UUID_RX_0 : CHARACTERISTIC_UUID_RX_1, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR);
104 |
105 | if (pService != nullptr) {
106 | pCharacteristicRx->setCallbacks(new MyCallbacks());
107 | pService->start();
108 |
109 | BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
110 | pAdvertising->addServiceUUID(useKISS ? SERVICE_UUID_0 : SERVICE_UUID_1);
111 |
112 | pServer->getAdvertising()->setScanResponse(true);
113 | pServer->getAdvertising()->setMinPreferred(0x06);
114 | pServer->getAdvertising()->setMaxPreferred(0x0C);
115 | pAdvertising->start();
116 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BLE", "%s", "Waiting for BLE central to connect...");
117 | } else {
118 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "BLE", "Failed to create BLE service");
119 | }
120 | }
121 |
122 | void sendToLoRa() {
123 | if (!shouldSendBLEtoLoRa) return;
124 |
125 | if (!Config.acceptOwnFrameFromTNC && BLEToLoRaPacket.indexOf("::") == -1) {
126 | String sender = BLEToLoRaPacket.substring(0, BLEToLoRaPacket.indexOf(">"));
127 | if (sender == currentBeacon->callsign) {
128 | BLEToLoRaPacket = "";
129 | shouldSendBLEtoLoRa = false;
130 | return;
131 | }
132 | }
133 |
134 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BLE Tx", "%s", BLEToLoRaPacket.c_str());
135 | displayShow("BLE Tx >>", "", BLEToLoRaPacket, 1000);
136 | LoRa_Utils::sendNewPacket(BLEToLoRaPacket);
137 | BLEToLoRaPacket = "";
138 | shouldSendBLEtoLoRa = false;
139 | }
140 |
141 | void txBLE(uint8_t p) {
142 | pCharacteristicTx->setValue(&p,1);
143 | pCharacteristicTx->notify();
144 | delay(3);
145 | }
146 |
147 | void txToPhoneOverBLE(const String& frame) {
148 | if (Config.bluetooth.useKISS) { // KISS (AX.25)
149 | const String kissEncodedFrame = KISS_Utils::encodeKISS(frame);
150 |
151 | const char* t = kissEncodedFrame.c_str();
152 | int length = kissEncodedFrame.length();
153 | for (int i = 0; i < length; i += BLE_CHUNK_SIZE) {
154 | int chunkSize = (length - i < BLE_CHUNK_SIZE) ? (length - i) : BLE_CHUNK_SIZE;
155 |
156 | uint8_t* chunk = new uint8_t[chunkSize];
157 | memcpy(chunk, t + i, chunkSize);
158 |
159 | pCharacteristicTx->setValue(chunk, chunkSize);
160 | pCharacteristicTx->notify();
161 | delete[] chunk;
162 | delay(200);
163 | }
164 | } else { // TNC2
165 | for (int n = 0; n < frame.length(); n++) txBLE(frame[n]);
166 | txBLE('\n');
167 | }
168 | }
169 |
170 | void sendToPhone(const String& packet) {
171 | if (!packet.isEmpty() && bluetoothConnected) {
172 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BLE Rx", "%s", packet.c_str());
173 | String receivedPacketString = "";
174 | for (int i = 0; i < packet.length(); i++) receivedPacketString += packet[i];
175 | txToPhoneOverBLE(receivedPacketString);
176 | }
177 | }
178 |
179 | }
--------------------------------------------------------------------------------
/src/bluetooth_utils.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "bluetooth_utils.h"
4 | #include "configuration.h"
5 | #include "lora_utils.h"
6 | #include "kiss_utils.h"
7 | #include "display.h"
8 | #include "logger.h"
9 |
10 |
11 | extern Configuration Config;
12 | extern Beacon *currentBeacon;
13 | extern BluetoothSerial SerialBT;
14 | extern logging::Logger logger;
15 | extern TinyGPSPlus gps;
16 | extern bool bluetoothConnected;
17 | extern bool bluetoothActive;
18 |
19 | namespace BLUETOOTH_Utils {
20 | String serialReceived;
21 | bool shouldSendToLoRa = false;
22 | bool useKiss = Config.bluetooth.useKISS? true : false;
23 |
24 | void setup() {
25 | if (!bluetoothActive) {
26 | btStop();
27 | esp_bt_controller_disable();
28 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "BT controller disabled");
29 | return;
30 | }
31 |
32 | serialReceived.reserve(255);
33 |
34 | SerialBT.register_callback(BLUETOOTH_Utils::bluetoothCallback);
35 | SerialBT.onData(BLUETOOTH_Utils::getData); // callback instead of while to avoid RX buffer limit when NMEA data received
36 |
37 | String BTid = Config.bluetooth.deviceName;
38 |
39 | if (!SerialBT.begin(String(BTid))) {
40 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "Bluetooth", "Starting Bluetooth failed!");
41 | displayShow("ERROR", "Starting Bluetooth failed!", "");
42 | while(true) {
43 | delay(1000);
44 | }
45 | }
46 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Bluetooth Classic init done!");
47 | }
48 |
49 | void bluetoothCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
50 | if (event == ESP_SPP_SRV_OPEN_EVT) {
51 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Client connected !");
52 | bluetoothConnected = true;
53 | } else if (event == ESP_SPP_CLOSE_EVT) {
54 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Client disconnected !");
55 | bluetoothConnected = false;
56 | } else {
57 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "Bluetooth", "Status: %d", event);
58 | }
59 | }
60 |
61 | void getData(const uint8_t *buffer, size_t size) {
62 | if (size == 0) return;
63 | shouldSendToLoRa = false;
64 | serialReceived.clear();
65 | bool isNmea = buffer[0] == '$';
66 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "bluetooth", "Received buffer size %d. Nmea=%d. %s", size, isNmea, buffer);
67 |
68 | for (int i = 0; i < size; i++) {
69 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "bluetooth", "[%d/%d] %x -> %c", i + 1, size, buffer[i], buffer[i]);
70 | }
71 | for (int i = 0; i < size; i++) {
72 | char c = (char) buffer[i];
73 | if (isNmea) {
74 | gps.encode(c);
75 | } else {
76 | serialReceived += c;
77 | }
78 | }
79 | // Test if we have to send frame
80 | isNmea = serialReceived.indexOf("$G") != -1 || serialReceived.indexOf("$B") != -1;
81 | if (isNmea) useKiss = false;
82 | if (isNmea || serialReceived.isEmpty()) return;
83 | if (KISS_Utils::validateKISSFrame(serialReceived)) {
84 | bool dataFrame;
85 | String decodeKiss = KISS_Utils::decodeKISS(serialReceived, dataFrame);
86 | serialReceived.clear();
87 | serialReceived += decodeKiss;
88 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "bluetooth", "It's a kiss frame. dataFrame: %d", dataFrame);
89 | useKiss = true;
90 | } else {
91 | useKiss = false;
92 | }
93 | if (KISS_Utils::validateTNC2Frame(serialReceived)) {
94 | shouldSendToLoRa = true;
95 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "bluetooth", "Data received should be transmitted to RF => %s", serialReceived.c_str());
96 | }
97 | }
98 |
99 | void sendToLoRa() {
100 | if (!shouldSendToLoRa) return;
101 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BT TX", "%s", serialReceived.c_str());
102 | displayShow("BT Tx >>", "", serialReceived, 1000);
103 | LoRa_Utils::sendNewPacket(serialReceived);
104 | shouldSendToLoRa = false;
105 | }
106 |
107 | void sendToPhone(const String& packet) {
108 | if (!packet.isEmpty()) {
109 | if (useKiss) {
110 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BT RX Kiss", "%s", serialReceived.c_str());
111 | SerialBT.println(KISS_Utils::encodeKISS(packet));
112 | } else {
113 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BT RX TNC2", "%s", serialReceived.c_str());
114 | SerialBT.println(packet);
115 | }
116 | }
117 | }
118 |
119 | }
--------------------------------------------------------------------------------
/src/button_utils.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "keyboard_utils.h"
3 | #include "board_pinout.h"
4 | #include "button_utils.h"
5 | #include "power_utils.h"
6 | #include "display.h"
7 |
8 | #ifdef BUTTON_PIN
9 |
10 | extern int menuDisplay;
11 | extern uint32_t displayTime;
12 | extern uint32_t menuTime;
13 |
14 |
15 | namespace BUTTON_Utils {
16 |
17 | OneButton userButton = OneButton(BUTTON_PIN, true, true);
18 |
19 | static bool buttonSinglePressed;
20 | static bool buttonLongPressed;
21 | static bool buttonDoublePressed;
22 | static bool buttonMultiPressed;
23 |
24 | void singlePress() {
25 | menuTime = millis();
26 | KEYBOARD_Utils::downArrow();
27 | }
28 |
29 | void longPress() {
30 | menuTime = millis();
31 | KEYBOARD_Utils::rightArrow();
32 | }
33 |
34 | void doublePress() {
35 | displayToggle(true);
36 | menuTime = millis();
37 | if (menuDisplay == 0) {
38 | menuDisplay = 1;
39 | } else if (menuDisplay > 0) {
40 | menuDisplay = 0;
41 | displayTime = millis();
42 | }
43 | }
44 |
45 | void multiPress() {
46 | displayToggle(true);
47 | menuTime = millis();
48 | menuDisplay = 9000;
49 | }
50 |
51 | void isrSinglePress() {
52 | buttonSinglePressed = true;
53 | }
54 |
55 | void isrLongPress() {
56 | buttonLongPressed = true;
57 | }
58 |
59 | void isrDoublePress() {
60 | buttonDoublePressed = true;
61 | }
62 |
63 | void isrMultiPress() {
64 | buttonMultiPressed = true;
65 | }
66 |
67 | void IRAM_ATTR buttonIsr() { // Interrupt Service Routine
68 | userButton.tick();
69 | }
70 |
71 | void loop() {
72 | noInterrupts();
73 | userButton.tick();
74 | interrupts();
75 |
76 | if (buttonSinglePressed) {
77 | buttonSinglePressed = false;
78 | singlePress();
79 | }
80 | if (buttonLongPressed) {
81 | buttonLongPressed = false;
82 | longPress();
83 | }
84 | if (buttonDoublePressed) {
85 | buttonDoublePressed = false;
86 | doublePress();
87 | }
88 | if (buttonMultiPressed) {
89 | buttonMultiPressed = false;
90 | multiPress();
91 | }
92 | }
93 |
94 | void setup() {
95 | userButton.attachClick(BUTTON_Utils::isrSinglePress);
96 | userButton.attachLongPressStart(BUTTON_Utils::isrLongPress);
97 | userButton.attachDoubleClick(BUTTON_Utils::isrDoublePress);
98 | userButton.attachMultiClick(BUTTON_Utils::isrMultiPress);
99 | attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonIsr, FALLING);
100 | }
101 |
102 | }
103 |
104 | #endif
--------------------------------------------------------------------------------
/src/gps_utils.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "TimeLib.h"
3 | #include
4 | #include "smartbeacon_utils.h"
5 | #include "configuration.h"
6 | #include "station_utils.h"
7 | #include "board_pinout.h"
8 | #include "power_utils.h"
9 | #include "sleep_utils.h"
10 | #include "gps_utils.h"
11 | #include "display.h"
12 | #include "logger.h"
13 |
14 |
15 | #ifdef GPS_BAUDRATE
16 | #define GPS_BAUD GPS_BAUDRATE
17 | #else
18 | #define GPS_BAUD 9600
19 | #endif
20 |
21 |
22 | extern Configuration Config;
23 | extern HardwareSerial gpsSerial;
24 | extern TinyGPSPlus gps;
25 | extern Beacon *currentBeacon;
26 | extern logging::Logger logger;
27 | extern bool sendUpdate;
28 | extern bool sendStandingUpdate;
29 |
30 | extern uint32_t lastTxTime;
31 | extern uint32_t txInterval;
32 | extern double lastTxLat;
33 | extern double lastTxLng;
34 | extern double lastTxDistance;
35 | extern uint32_t lastTx;
36 | extern bool disableGPS;
37 | extern bool gpsShouldSleep;
38 | extern SmartBeaconValues currentSmartBeaconValues;
39 |
40 | double currentHeading = 0;
41 | double previousHeading = 0;
42 | float bearing = 0;
43 |
44 | bool gpsIsActive = true;
45 |
46 |
47 | namespace GPS_Utils {
48 |
49 | void setup() {
50 | if (disableGPS) {
51 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_WARN, "Main", "GPS disabled");
52 | return;
53 | }
54 | #ifdef LIGHTTRACKER_PLUS_1_0
55 | pinMode(GPS_VCC, OUTPUT);
56 | digitalWrite(GPS_VCC, LOW);
57 | delay(200);
58 | #endif
59 | #if defined(F4GOH_1W_LoRa_Tracker) || defined(F4GOH_1W_LoRa_Tracker_LLCC68)
60 | pinMode(GPS_VCC, OUTPUT);
61 | digitalWrite(GPS_VCC, HIGH);
62 | delay(200);
63 | #endif
64 |
65 | gpsSerial.begin(GPS_BAUD, SERIAL_8N1, GPS_TX, GPS_RX);
66 | }
67 |
68 | void calculateDistanceCourse(const String& callsign, double checkpointLatitude, double checkPointLongitude) {
69 | double distanceKm = TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), checkpointLatitude, checkPointLongitude) / 1000.0;
70 | double courseTo = TinyGPSPlus::courseTo(gps.location.lat(), gps.location.lng(), checkpointLatitude, checkPointLongitude);
71 | STATION_Utils::deleteListenedTrackersbyTime();
72 | STATION_Utils::orderListenedTrackersByDistance(callsign, distanceKm, courseTo);
73 | }
74 |
75 | void getData() {
76 | if (disableGPS) return;
77 | while (gpsSerial.available() > 0) gps.encode(gpsSerial.read());
78 | }
79 |
80 | void setDateFromData() {
81 | if (gps.time.isValid()) setTime(gps.time.hour(), gps.time.minute(), gps.time.second(), gps.date.day(), gps.date.month(), gps.date.year());
82 | }
83 |
84 | void calculateDistanceTraveled() {
85 | currentHeading = gps.course.deg();
86 | lastTxDistance = TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), lastTxLat, lastTxLng);
87 | if (lastTx >= txInterval) {
88 | if (lastTxDistance > currentSmartBeaconValues.minTxDist) {
89 | sendUpdate = true;
90 | sendStandingUpdate = false;
91 | } else {
92 | if (currentBeacon->gpsEcoMode) {
93 | //
94 | Serial.print("minTxDistance not achieved : ");
95 | Serial.println(lastTxDistance);
96 | //
97 | gpsShouldSleep = true;
98 | }
99 | }
100 | }
101 | }
102 |
103 | void calculateHeadingDelta(int speed) {
104 | uint8_t TurnMinAngle;
105 | double headingDelta = abs(previousHeading - currentHeading);
106 | if (lastTx > currentSmartBeaconValues.minDeltaBeacon * 1000) {
107 | if (speed == 0) {
108 | TurnMinAngle = currentSmartBeaconValues.turnMinDeg + (currentSmartBeaconValues.turnSlope/(speed + 1));
109 | } else {
110 | TurnMinAngle = currentSmartBeaconValues.turnMinDeg + (currentSmartBeaconValues.turnSlope/speed);
111 | }
112 | if (headingDelta > TurnMinAngle && lastTxDistance > currentSmartBeaconValues.minTxDist) {
113 | sendUpdate = true;
114 | sendStandingUpdate = false;
115 | }
116 | }
117 | }
118 |
119 | void checkStartUpFrames() {
120 | if (disableGPS) return;
121 | if ((millis() > 10000 && gps.charsProcessed() < 10)) {
122 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "GPS",
123 | "No GPS frames detected! Try to reset the GPS Chip with this "
124 | "firmware: https://github.com/richonguzman/TTGO_T_BEAM_GPS_RESET");
125 | displayShow("ERROR", "No GPS frames!", "Reset the GPS Chip", 2000);
126 | }
127 | }
128 |
129 | String getHumanBearing(const String& left, const String& center, const String& right) {
130 | String bearing = ">.";
131 | bearing += left;
132 | for (int i = 0; i < 9; i++) {
133 | bearing += ".";
134 | }
135 | bearing += "(";
136 | bearing += center;
137 | bearing += ").....";
138 | if (right.length() == 1 && center.length() != 2) bearing += ".";
139 | bearing += right;
140 | bearing += ".<";
141 | return bearing;
142 | }
143 |
144 | String getCardinalDirection(float course) {
145 | if (gps.speed.kmph() > 0.5) bearing = course;
146 |
147 | if (bearing >= 354.375 || bearing < 5.625) return ">.NW.....(N).....NE.<"; // N
148 | if (bearing >= 5.675 && bearing < 16.875) return ">.......N.|.....NE..<";
149 | if (bearing >= 16.875 && bearing < 28.125) return ">.....N...|...NE....<"; // NEN
150 | if (bearing >= 28.125 && bearing < 39.375) return ">...N.....|.NE......<";
151 | if (bearing >= 39.375 && bearing < 50.625) return ">.N......(NE).....E.<"; // NE
152 | if (bearing >= 50.625 && bearing < 61.875) return ">.......NE|.....E...<";
153 | if (bearing >= 61.875 && bearing < 73.125) return ">.....NE..|...E.....<"; // ENE
154 | if (bearing >= 73.125 && bearing < 84.375) return ">...NE....|.E.......<";
155 | if (bearing >= 84.375 && bearing < 95.625) return ">.NE.....(E).....SE.<"; // E
156 | if (bearing >= 95.625 && bearing < 106.875) return ">.......E.|.....SE..<";
157 | if (bearing >= 106.875 && bearing < 118.125) return ">.....E...|...SE....<"; // ESE
158 | if (bearing >= 118.125 && bearing < 129.375) return ">...E.....|.SE......<";
159 | if (bearing >= 129.375 && bearing < 140.625) return ">.E......(SE).....S.<"; // SE
160 | if (bearing >= 140.625 && bearing < 151.875) return ">.......SE|.....S...<";
161 | if (bearing >= 151.875 && bearing < 163.125) return ">.....SE..|...S.....<"; // SES
162 | if (bearing >= 163.125 && bearing < 174.375) return ">...SE....|.S.......<";
163 | if (bearing >= 174.375 && bearing < 185.625) return ">.SE.....(S).....SW.<"; // S
164 | if (bearing >= 185.625 && bearing < 196.875) return ">.......S.|.....SW..<";
165 | if (bearing >= 196.875 && bearing < 208.125) return ">.....S...|...SW....<"; // SWS
166 | if (bearing >= 208.125 && bearing < 219.375) return ">...S.....|.SW......<";
167 | if (bearing >= 219.375 && bearing < 230.625) return ">.S......(SW).....W.<"; // SW
168 | if (bearing >= 230.625 && bearing < 241.875) return ">.......SW|.....W...<";
169 | if (bearing >= 241.875 && bearing < 253.125) return ">.....SW..|...W.....<"; // WSW
170 | if (bearing >= 253.125 && bearing < 264.375) return ">...SW....|.W.......<";
171 | if (bearing >= 264.375 && bearing < 275.625) return ">.SW.....(W).....NW.<"; // W
172 | if (bearing >= 275.625 && bearing < 286.875) return ">.......W.|.....NW..<";
173 | if (bearing >= 286.875 && bearing < 298.125) return ">.....W...|...NW....<"; // WNW
174 | if (bearing >= 298.125 && bearing < 309.375) return ">...W.....|.NW......<";
175 | if (bearing >= 309.375 && bearing < 320.625) return ">.W......(NW).....N.<"; // NW
176 | if (bearing >= 320.625 && bearing < 331.875) return ">.......NW|.....N...<";
177 | if (bearing >= 331.875 && bearing < 343.125) return ">.....NW..|...N.....<"; // NWN
178 | if (bearing >= 343.125 && bearing < 354.375) return ">...NW....|.N.......<";
179 | return "";
180 | }
181 |
182 | }
--------------------------------------------------------------------------------
/src/joystick_utils.cpp:
--------------------------------------------------------------------------------
1 | #include "joystick_utils.h"
2 | #include "keyboard_utils.h"
3 | #include "board_pinout.h"
4 | #include "button_utils.h"
5 |
6 | extern int menuDisplay;
7 |
8 | bool exitJoystickInterrupt = false;
9 |
10 | typedef void (*DirectionFunc)();
11 |
12 | #ifdef HAS_JOYSTICK
13 |
14 | namespace JOYSTICK_Utils {
15 |
16 | int debounceDelay = 400;
17 | uint32_t lastInterruptTime = 0;
18 |
19 | bool checkLastJoystickInterrupTime() {
20 | if ((millis() - lastInterruptTime) > debounceDelay) {
21 | lastInterruptTime = millis();
22 | return true;
23 | } else {
24 | return false;
25 | }
26 | }
27 |
28 | bool checkMenuDisplayToExitInterrupt(int menu) {
29 | if (menu == 10 || menu == 120 || (menu >= 130 && menu <= 133) || menu == 200 || menu == 210 || menu == 1300 || menu == 1310 || (menu >= 2210 && menu <= 2212) || menu == 51 || (menu >= 50100 && menu <= 50101) || (menu >= 50110 && menu <= 50111) || menu == 9001) {
30 | return true; // read / delete/ callsignIndex / loraIndex / brightness x 3 / readW / readW / delete / enter WiFiAP
31 | } else {
32 | return false;
33 | }
34 | }
35 |
36 | void loop() { // for running process with SPIFFS outside interrupt
37 | if (checkMenuDisplayToExitInterrupt(menuDisplay) && exitJoystickInterrupt) BUTTON_Utils::longPress();
38 | }
39 |
40 | void IRAM_ATTR joystickHandler(DirectionFunc directionFunc) {
41 | if (checkLastJoystickInterrupTime() && menuDisplay != 0) {
42 | if (checkMenuDisplayToExitInterrupt(menuDisplay) && directionFunc == BUTTON_Utils::longPress) {
43 | exitJoystickInterrupt = true;
44 | } else {
45 | exitJoystickInterrupt = false;
46 | directionFunc();
47 | }
48 | }
49 | }
50 |
51 | void IRAM_ATTR joystickUp() { joystickHandler(KEYBOARD_Utils::upArrow); }
52 | void IRAM_ATTR joystickDown() { joystickHandler(KEYBOARD_Utils::downArrow); }
53 | void IRAM_ATTR joystickLeft() { joystickHandler(KEYBOARD_Utils::leftArrow); }
54 | void IRAM_ATTR joystickRight() { joystickHandler(BUTTON_Utils::longPress); }
55 |
56 | void setup() {
57 | pinMode(JOYSTICK_CENTER, INPUT_PULLUP);
58 | pinMode(JOYSTICK_UP, INPUT_PULLUP);
59 | pinMode(JOYSTICK_DOWN, INPUT_PULLUP);
60 | pinMode(JOYSTICK_LEFT, INPUT_PULLUP);
61 | pinMode(JOYSTICK_RIGHT, INPUT_PULLUP);
62 |
63 | attachInterrupt(digitalPinToInterrupt(JOYSTICK_UP), joystickUp, FALLING);
64 | attachInterrupt(digitalPinToInterrupt(JOYSTICK_DOWN), joystickDown, FALLING);
65 | attachInterrupt(digitalPinToInterrupt(JOYSTICK_LEFT), joystickLeft, FALLING);
66 | attachInterrupt(digitalPinToInterrupt(JOYSTICK_RIGHT), joystickRight, FALLING);
67 | }
68 | }
69 |
70 | #endif
--------------------------------------------------------------------------------
/src/kiss_utils.cpp:
--------------------------------------------------------------------------------
1 | #include "kiss_utils.h"
2 |
3 |
4 | namespace KISS_Utils {
5 |
6 | bool validateTNC2Frame(const String& tnc2FormattedFrame) {
7 | int colonPos = tnc2FormattedFrame.indexOf(':');
8 | int greaterThanPos = tnc2FormattedFrame.indexOf('>');
9 | return (colonPos != -1) && (greaterThanPos != -1) && (colonPos > greaterThanPos);
10 | }
11 |
12 | bool validateKISSFrame(const String& kissFormattedFrame) {
13 | return kissFormattedFrame.charAt(0) == (char)KissChar::FEND && kissFormattedFrame.charAt(kissFormattedFrame.length() - 1) == (char)KissChar::FEND;
14 | }
15 |
16 | String decodeAddressAX25(const String& ax25Address, bool& isLastAddress, bool isRelay) {
17 | String address = "";
18 | for (int i = 0; i < 6; ++i) {
19 | uint8_t currentCharacter = ax25Address.charAt(i);
20 | currentCharacter >>= 1;
21 | if (currentCharacter != ' ') address += (char)currentCharacter;
22 | }
23 | auto ssidChar = (uint8_t)ax25Address.charAt(6);
24 | bool hasBeenDigipited = ssidChar & HAS_BEEN_DIGIPITED_MASK;
25 | isLastAddress = ssidChar & IS_LAST_ADDRESS_POSITION_MASK;
26 | ssidChar >>= 1;
27 |
28 | int ssid = 0b1111 & ssidChar;
29 | if (ssid) {
30 | address += '-';
31 | address += ssid;
32 | }
33 | if (isRelay && hasBeenDigipited) address += '*';
34 | return address;
35 | }
36 |
37 | String decapsulateKISS(const String& frame) {
38 | String ax25Frame = "";
39 | for (int i = 2; i < frame.length() - 1; ++i) {
40 | char currentChar = frame.charAt(i);
41 | if (currentChar == (char)KissChar::FESC) {
42 | char nextChar = frame.charAt(i + 1);
43 | if (nextChar == (char)KissChar::TFEND) {
44 | ax25Frame += (char)KissChar::FEND;
45 | } else if (nextChar == (char)KissChar::TFESC) {
46 | ax25Frame += (char)KissChar::FESC;
47 | }
48 | i++;
49 | } else {
50 | ax25Frame += currentChar;
51 | }
52 | }
53 | return ax25Frame;
54 | }
55 |
56 | String encapsulateKISS(const String& ax25Frame, uint8_t command) {
57 | String kissFrame = "";
58 | kissFrame += (char)KissChar::FEND;
59 | kissFrame += (char)(0x0f & command);
60 |
61 | for (int i = 0; i < ax25Frame.length(); ++i) {
62 | char currentChar = ax25Frame.charAt(i);
63 | if (currentChar == (char)KissChar::FEND) {
64 | kissFrame += (char)KissChar::FESC;
65 | kissFrame += (char)KissChar::TFEND;
66 | } else if (currentChar == (char)KissChar::FESC) {
67 | kissFrame += (char)KissChar::FESC;
68 | kissFrame += (char)KissChar::TFESC;
69 | } else {
70 | kissFrame += currentChar;
71 | }
72 | }
73 | kissFrame += (char)KissChar::FEND; // end of frame
74 | return kissFrame;
75 | }
76 |
77 | String encodeAddressAX25(String address) {
78 | bool hasBeenDigipited = address.indexOf('*') != -1;
79 | if (address.indexOf('-') == -1) {
80 | if (hasBeenDigipited) address = address.substring(0, address.length() - 1);
81 | address += "-0";
82 | }
83 |
84 | int separatorIndex = address.indexOf('-');
85 | int ssid = address.substring(separatorIndex + 1).toInt();
86 | String kissAddress = "";
87 | for (int i = 0; i < 6; ++i) {
88 | char addressChar = ' ';
89 | if (address.length() > i && i < separatorIndex) addressChar = address.charAt(i);
90 | kissAddress += (char)(addressChar << 1);
91 | }
92 | kissAddress += (char)((ssid << 1) | 0b01100000 | (hasBeenDigipited ? HAS_BEEN_DIGIPITED_MASK : 0));
93 | return kissAddress;
94 | }
95 |
96 | String decodeKISS(const String& inputFrame, bool& dataFrame) {
97 | String frame = "";
98 | if (KISS_Utils::validateKISSFrame(inputFrame)) {
99 | dataFrame = inputFrame.charAt(1) == KissCmd::Data;
100 | if (dataFrame) {
101 | String ax25Frame = decapsulateKISS(inputFrame);
102 | bool isLastAddress = false;
103 | String dstAddr = decodeAddressAX25(ax25Frame.substring(0, 7), isLastAddress, false);
104 | String srcAddr = decodeAddressAX25(ax25Frame.substring(7, 14), isLastAddress, false);
105 |
106 | frame = srcAddr + ">" + dstAddr;
107 |
108 | int digiInfoIndex = 14;
109 | while (!isLastAddress && digiInfoIndex + 7 < ax25Frame.length()) {
110 | String digiAddr = decodeAddressAX25(ax25Frame.substring(digiInfoIndex, digiInfoIndex + 7), isLastAddress, true);
111 | frame += ',' + digiAddr;
112 | digiInfoIndex += 7;
113 | }
114 | frame += ':';
115 | frame += ax25Frame.substring(digiInfoIndex + 2);
116 | } else {
117 | frame += inputFrame;
118 | }
119 | }
120 | return frame;
121 | }
122 |
123 | String encodeKISS(const String& frame) {
124 | String ax25Frame = "";
125 |
126 | if (KISS_Utils::validateTNC2Frame(frame)) {
127 | int colonIndex = frame.indexOf(':');
128 |
129 | String address = "";
130 | bool destinationAddressWritten = false;
131 | for (int i = 0; i <= colonIndex; i++) {
132 | char currentChar = frame.charAt(i);
133 | if (currentChar == ':' || currentChar == '>' || currentChar == ',') {
134 | if (!destinationAddressWritten && (currentChar == ',' || currentChar == ':')) {
135 | ax25Frame = encodeAddressAX25(address) + ax25Frame;
136 | destinationAddressWritten = true;
137 | } else {
138 | ax25Frame += encodeAddressAX25(address);
139 | }
140 | address = "";
141 | } else {
142 | address += currentChar;
143 | }
144 | }
145 | auto lastAddressChar = (uint8_t)ax25Frame.charAt(ax25Frame.length() - 1);
146 | ax25Frame.setCharAt(ax25Frame.length() - 1, (char)(lastAddressChar | IS_LAST_ADDRESS_POSITION_MASK));
147 | ax25Frame += (char)AX25Char::ControlField;
148 | ax25Frame += (char)AX25Char::InformationField;
149 | ax25Frame += frame.substring(colonIndex + 1);
150 | }
151 | String kissFrame = encapsulateKISS(ax25Frame, KissCmd::Data);
152 | return kissFrame;
153 | }
154 |
155 | }
--------------------------------------------------------------------------------
/src/lora_utils.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "notification_utils.h"
5 | #include "configuration.h"
6 | #include "board_pinout.h"
7 | #include "lora_utils.h"
8 | #include "display.h"
9 |
10 | extern logging::Logger logger;
11 | extern Configuration Config;
12 | extern LoraType *currentLoRaType;
13 | extern uint8_t loraIndex;
14 | extern int loraIndexSize;
15 |
16 | bool operationDone = true;
17 | bool transmitFlag = true;
18 |
19 | #if defined(HAS_SX1262)
20 | SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
21 | #endif
22 | #if defined(HAS_SX1268)
23 | #if defined(LIGHTTRACKER_PLUS_1_0)
24 | SPIClass loraSPI(FSPI);
25 | SX1268 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN, loraSPI);
26 | #else
27 | SX1268 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
28 | #endif
29 | #endif
30 | #if defined(HAS_SX1278)
31 | SX1278 radio = new Module(RADIO_CS_PIN, RADIO_BUSY_PIN, RADIO_RST_PIN);
32 | #endif
33 | #if defined(HAS_SX1276)
34 | SX1276 radio = new Module(RADIO_CS_PIN, RADIO_BUSY_PIN, RADIO_RST_PIN);
35 | #endif
36 | #if defined(HAS_LLCC68) // LLCC68 supports spreading factor only in range of 5-11!
37 | LLCC68 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
38 | #endif
39 |
40 | namespace LoRa_Utils {
41 |
42 | void setFlag(void) {
43 | operationDone = true;
44 | }
45 |
46 | void changeFreq() {
47 | if(loraIndex >= (loraIndexSize - 1)) {
48 | loraIndex = 0;
49 | } else {
50 | loraIndex++;
51 | }
52 | currentLoRaType = &Config.loraTypes[loraIndex];
53 |
54 | float freq = (float)currentLoRaType->frequency/1000000;
55 | radio.setFrequency(freq);
56 | radio.setSpreadingFactor(currentLoRaType->spreadingFactor);
57 | float signalBandwidth = currentLoRaType->signalBandwidth/1000;
58 | radio.setBandwidth(signalBandwidth);
59 | radio.setCodingRate(currentLoRaType->codingRate4);
60 | #if (defined(HAS_SX1268) || defined(HAS_SX1262)) && !defined(HAS_1W_LORA)
61 | radio.setOutputPower(currentLoRaType->power + 2); // values available: 10, 17, 22 --> if 20 in tracker_conf.json it will be updated to 22.
62 | #endif
63 | #if defined(HAS_SX1278) || defined(HAS_SX1276) || defined(HAS_1W_LORA)
64 | radio.setOutputPower(currentLoRaType->power);
65 | #endif
66 |
67 | String loraCountryFreq;
68 | switch (loraIndex) {
69 | case 0: loraCountryFreq = "EU/WORLD"; break;
70 | case 1: loraCountryFreq = "POLAND"; break;
71 | case 2: loraCountryFreq = "UK"; break;
72 | }
73 | String currentLoRainfo = "LoRa ";
74 | currentLoRainfo += loraCountryFreq;
75 | currentLoRainfo += " / Freq: ";
76 | currentLoRainfo += String(currentLoRaType->frequency);
77 | currentLoRainfo += " / SF:";
78 | currentLoRainfo += String(currentLoRaType->spreadingFactor);
79 | currentLoRainfo += " / CR: ";
80 | currentLoRainfo += String(currentLoRaType->codingRate4);
81 |
82 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "LoRa", currentLoRainfo.c_str());
83 | displayShow("LORA FREQ>", "", "CHANGED TO: " + loraCountryFreq, "", "", "", 2000);
84 | }
85 |
86 | void setup() {
87 | #ifdef LIGHTTRACKER_PLUS_1_0
88 | pinMode(RADIO_VCC_PIN,OUTPUT);
89 | digitalWrite(RADIO_VCC_PIN,HIGH);
90 | #endif
91 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "LoRa", "Set SPI pins!");
92 | #if defined(LIGHTTRACKER_PLUS_1_0)
93 | loraSPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN, RADIO_CS_PIN);
94 | #else
95 | SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN);
96 | #endif
97 | float freq = (float)currentLoRaType->frequency/1000000;
98 | #if defined(RADIO_HAS_XTAL)
99 | radio.XTAL = true;
100 | #endif
101 | int state = radio.begin(freq);
102 | if (state == RADIOLIB_ERR_NONE) {
103 | #if defined(HAS_SX1262) || defined(HAS_SX1268)
104 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", "Initializing SX126X ...");
105 | #else
106 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", "Initializing SX127X ...");
107 | #endif
108 | } else {
109 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "Starting LoRa failed! State: %d", state);
110 | while (true);
111 | }
112 | #if defined(HAS_SX1262) || defined(HAS_SX1268) || defined(HAS_LLCC68)
113 | radio.setDio1Action(setFlag);
114 | #endif
115 | #if defined(HAS_SX1278) || defined(HAS_SX1276)
116 | radio.setDio0Action(setFlag, RISING);
117 | #endif
118 | radio.setSpreadingFactor(currentLoRaType->spreadingFactor);
119 | float signalBandwidth = currentLoRaType->signalBandwidth/1000;
120 | radio.setBandwidth(signalBandwidth);
121 | radio.setCodingRate(currentLoRaType->codingRate4);
122 | radio.setCRC(true);
123 |
124 | #if defined(RADIO_RXEN) && defined(RADIO_TXEN)
125 | radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN);
126 | #endif
127 |
128 | #ifdef HAS_1W_LORA // Ebyte E22 400M30S (SX1268) / 900M30S (SX1262) / Ebyte E220 400M30S (LLCC68)
129 | state = radio.setOutputPower(currentLoRaType->power); // max value 20 (when 20dB in setup 30dB in output as 400M30S has Low Noise Amp)
130 | radio.setCurrentLimit(140); // to be validated (100 , 120, 140)?
131 | #endif
132 |
133 | #if (defined(HAS_SX1268) || defined(HAS_SX1262)) && !defined(HAS_1W_LORA)
134 | state = radio.setOutputPower(currentLoRaType->power + 2); // values available: 10, 17, 22 --> if 20 in tracker_conf.json it will be updated to 22.
135 | radio.setCurrentLimit(140);
136 | #endif
137 |
138 | #if defined(HAS_SX1278) || defined(HAS_SX1276)
139 | state = radio.setOutputPower(currentLoRaType->power);
140 | radio.setCurrentLimit(100); // to be validated (80 , 100)?
141 | #endif
142 |
143 | #if defined(HAS_SX1262) || defined(HAS_SX1268) || defined(HAS_LLCC68)
144 | radio.setRxBoostedGainMode(true);
145 | #endif
146 |
147 | if (state == RADIOLIB_ERR_NONE) {
148 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", "LoRa init done!");
149 | } else {
150 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "Starting LoRa failed! State: %d", state);
151 | while (true);
152 | }
153 | }
154 |
155 | void sendNewPacket(const String& newPacket) {
156 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa Tx","---> %s", newPacket.c_str());
157 | /*logger.log(logging::LoggerLevel::LOGGER_LEVEL_WARN, "LoRa","Send data: %s", newPacket.c_str());
158 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa","Send data: %s", newPacket.c_str());
159 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "LoRa","Send data: %s", newPacket.c_str());*/
160 |
161 | if (Config.ptt.active) {
162 | digitalWrite(Config.ptt.io_pin, Config.ptt.reverse ? LOW : HIGH);
163 | delay(Config.ptt.preDelay);
164 | }
165 | if (Config.notification.ledTx) digitalWrite(Config.notification.ledTxPin, HIGH);
166 | if (Config.notification.buzzerActive && Config.notification.txBeep) NOTIFICATION_Utils::beaconTxBeep();
167 |
168 | int state = radio.transmit("\x3c\xff\x01" + newPacket);
169 | transmitFlag = true;
170 | if (state == RADIOLIB_ERR_NONE) {
171 | //Serial.println(F("success!"));
172 | } else {
173 | Serial.print(F("failed, code "));
174 | Serial.println(state);
175 | }
176 |
177 | if (Config.notification.ledTx) digitalWrite(Config.notification.ledTxPin, LOW);
178 | if (Config.ptt.active) {
179 | delay(Config.ptt.postDelay);
180 | digitalWrite(Config.ptt.io_pin, Config.ptt.reverse ? HIGH : LOW);
181 | }
182 | /*#ifdef HAS_TFT
183 | cleanTFT();
184 | #endif*/
185 | }
186 |
187 | void wakeRadio() {
188 | radio.startReceive();
189 | }
190 |
191 | ReceivedLoRaPacket receiveFromSleep() {
192 | ReceivedLoRaPacket receivedLoraPacket;
193 | String packet = "";
194 | int state = radio.readData(packet);
195 | if (state == RADIOLIB_ERR_NONE) {
196 | receivedLoraPacket.text = packet;
197 | receivedLoraPacket.rssi = radio.getRSSI();
198 | receivedLoraPacket.snr = radio.getSNR();
199 | receivedLoraPacket.freqError = radio.getFrequencyError();
200 | } else {
201 | //
202 | }
203 | return receivedLoraPacket;
204 | }
205 |
206 | ReceivedLoRaPacket receivePacket() {
207 | ReceivedLoRaPacket receivedLoraPacket;
208 | String packet = "";
209 | if (operationDone) {
210 | operationDone = false;
211 | if (transmitFlag) {
212 | radio.startReceive();
213 | transmitFlag = false;
214 | } else {
215 | int state = radio.readData(packet);
216 | if (state == RADIOLIB_ERR_NONE) {
217 | if(!packet.isEmpty()) {
218 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa Rx","---> %s", packet.substring(3).c_str());
219 | receivedLoraPacket.text = packet;
220 | receivedLoraPacket.rssi = radio.getRSSI();
221 | receivedLoraPacket.snr = radio.getSNR();
222 | receivedLoraPacket.freqError = radio.getFrequencyError();
223 | }
224 | } else {
225 | Serial.print(F("failed, code ")); // 7 = CRC mismatch
226 | Serial.println(state);
227 | }
228 | }
229 | }
230 | return receivedLoraPacket;
231 | }
232 |
233 | void sleepRadio() {
234 | radio.sleep();
235 | }
236 |
237 | }
--------------------------------------------------------------------------------
/src/notification_utils.cpp:
--------------------------------------------------------------------------------
1 | #include "notification_utils.h"
2 | #include "configuration.h"
3 |
4 | uint8_t channel = 0;
5 | uint8_t resolution = 8;
6 | uint8_t pauseDuration = 20;
7 |
8 | int startUpSound[] = {440, 880, 440, 1760};
9 | uint8_t startUpSoundDuration[] = {100, 100, 100, 200};
10 |
11 | int shutDownSound[] = {1720, 880, 400};
12 | uint8_t shutDownSoundDuration[] = {60, 60, 200};
13 |
14 | extern Configuration Config;
15 | extern bool digipeaterActive;
16 |
17 | namespace NOTIFICATION_Utils {
18 |
19 | void playTone(int frequency, uint8_t duration) {
20 | ledcSetup(channel, frequency, resolution);
21 | ledcAttachPin(Config.notification.buzzerPinTone, 0);
22 | ledcWrite(channel, 128);
23 | delay(duration);
24 | ledcWrite(channel, 0);
25 | delay(pauseDuration);
26 | }
27 |
28 | void beaconTxBeep() {
29 | digitalWrite(Config.notification.buzzerPinVcc, HIGH);
30 | playTone(1320,100);
31 | if (digipeaterActive) {
32 | playTone(1560,100);
33 | }
34 | digitalWrite(Config.notification.buzzerPinVcc, LOW);
35 | }
36 |
37 | void messageBeep() {
38 | digitalWrite(Config.notification.buzzerPinVcc, HIGH);
39 | playTone(1100,100);
40 | playTone(1100,100);
41 | digitalWrite(Config.notification.buzzerPinVcc, LOW);
42 | }
43 |
44 | void stationHeardBeep() {
45 | digitalWrite(Config.notification.buzzerPinVcc, HIGH);
46 | playTone(1200,100);
47 | playTone(600,100);
48 | digitalWrite(Config.notification.buzzerPinVcc, LOW);
49 | }
50 |
51 | void shutDownBeep() {
52 | digitalWrite(Config.notification.buzzerPinVcc, HIGH);
53 | for (int i = 0; i < sizeof(shutDownSound) / sizeof(shutDownSound[0]); i++) {
54 | playTone(shutDownSound[i], shutDownSoundDuration[i]);
55 | }
56 | digitalWrite(Config.notification.buzzerPinVcc, LOW);
57 | }
58 |
59 | void lowBatteryBeep() {
60 | digitalWrite(Config.notification.buzzerPinVcc, HIGH);
61 | playTone(1550,100);
62 | playTone(650,100);
63 | playTone(1550,100);
64 | playTone(650,100);
65 | digitalWrite(Config.notification.buzzerPinVcc, LOW);
66 | }
67 |
68 | void start() {
69 | digitalWrite(Config.notification.buzzerPinVcc, HIGH);
70 | for (int i = 0; i < sizeof(startUpSound) / sizeof(startUpSound[0]); i++) {
71 | playTone(startUpSound[i], startUpSoundDuration[i]);
72 | }
73 | digitalWrite(Config.notification.buzzerPinVcc, LOW);
74 | }
75 |
76 | }
--------------------------------------------------------------------------------
/src/sleep_utils.cpp:
--------------------------------------------------------------------------------
1 | #include "board_pinout.h"
2 | #include "sleep_utils.h"
3 | #include "power_utils.h"
4 |
5 |
6 | extern uint32_t lastGPSTime;
7 | extern bool gpsIsActive;
8 |
9 | bool gpsShouldSleep = false;
10 |
11 |
12 | namespace SLEEP_Utils {
13 |
14 | void gpsSleep() {
15 | #ifdef HAS_GPS_CTRL
16 | if (gpsIsActive) {
17 | POWER_Utils::deactivateGPS();
18 | lastGPSTime = millis();
19 | //
20 | Serial.println("GPS SLEEPING");
21 | //
22 | }
23 | #endif
24 | }
25 |
26 | void gpsWakeUp() {
27 | #ifdef HAS_GPS_CTRL
28 | if (!gpsIsActive) {
29 | POWER_Utils::activateGPS();
30 | gpsShouldSleep = false;
31 | //
32 | Serial.println("GPS WAKEUP");
33 | //
34 | }
35 | #endif
36 | }
37 |
38 | void checkIfGPSShouldSleep() {
39 | if (gpsShouldSleep) {
40 | gpsSleep();
41 | }
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/src/smartbeacon_utils.cpp:
--------------------------------------------------------------------------------
1 | #include "smartbeacon_utils.h"
2 | #include "configuration.h"
3 | #include "winlink_utils.h"
4 |
5 | extern Configuration Config;
6 | extern Beacon *currentBeacon;
7 | extern bool smartBeaconActive;
8 | extern uint32_t txInterval;
9 | extern uint32_t lastTxTime;
10 | extern bool sendUpdate;
11 | extern uint8_t winlinkStatus;
12 |
13 |
14 | SmartBeaconValues currentSmartBeaconValues;
15 | byte smartBeaconSettingsIndex = 10;
16 | bool wxRequestStatus = false;
17 | uint32_t wxRequestTime = 0;
18 |
19 |
20 | SmartBeaconValues smartBeaconSettings[3] = {
21 | {120, 3, 60, 15, 50, 20, 12, 60}, // Runner settings = SLOW
22 | {120, 5, 60, 40, 100, 12, 12, 60}, // Bike settings = MEDIUM
23 | {120, 10, 60, 70, 100, 12, 10, 80} // Car settings = FAST
24 | };
25 |
26 |
27 | namespace SMARTBEACON_Utils {
28 |
29 | void checkSettings(byte index) {
30 | if (smartBeaconSettingsIndex != index) {
31 | currentSmartBeaconValues = smartBeaconSettings[index];
32 | smartBeaconSettingsIndex = index;
33 | }
34 | }
35 |
36 | void checkInterval(int speed) {
37 | if (smartBeaconActive) {
38 | if (speed < currentSmartBeaconValues.slowSpeed) {
39 | txInterval = currentSmartBeaconValues.slowRate * 1000;
40 | } else if (speed > currentSmartBeaconValues.fastSpeed) {
41 | txInterval = currentSmartBeaconValues.fastRate * 1000;
42 | } else {
43 | txInterval = min(currentSmartBeaconValues.slowRate, currentSmartBeaconValues.fastSpeed * currentSmartBeaconValues.fastRate / speed) * 1000;
44 | }
45 | }
46 | }
47 |
48 | void checkFixedBeaconTime() {
49 | if (!smartBeaconActive) {
50 | uint32_t lastTxSmartBeacon = millis() - lastTxTime;
51 | if (lastTxSmartBeacon >= Config.nonSmartBeaconRate * 60 * 1000) sendUpdate = true;
52 | }
53 | }
54 |
55 | void checkState() {
56 | if (wxRequestStatus && (millis() - wxRequestTime) > 20000) wxRequestStatus = false;
57 | smartBeaconActive = (winlinkStatus == 0 && !wxRequestStatus) ? currentBeacon->smartBeaconActive : false;
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/src/touch_utils.cpp:
--------------------------------------------------------------------------------
1 | #include "board_pinout.h"
2 | #include "button_utils.h"
3 | #include "touch_utils.h"
4 |
5 | #ifdef HAS_TOUCHSCREEN
6 |
7 | #define TOUCH_MODULES_GT911
8 | #include
9 |
10 | extern uint8_t touchModuleAddress;
11 |
12 | TouchLib touch(Wire, BOARD_I2C_SDA, BOARD_I2C_SCL, 0x00);
13 |
14 | void (*lastCalledAction)() = nullptr; // keep track of last calledAction from Touch
15 |
16 | extern bool sendUpdate;
17 |
18 | int16_t xCalibratedMin = 5;
19 | int16_t xCalibratedMax = 314;
20 | int16_t yCalibratedMin = 6;
21 | int16_t yCalibratedMax = 233;
22 |
23 | int16_t xValueMax = 320;
24 | int16_t yValueMax = 240;
25 |
26 | int touchDebounce = 300;
27 | uint32_t lastTouchTime = 0;
28 |
29 | int16_t xlastValue = 0;
30 | int16_t ylastValue = 0;
31 |
32 | extern int menuDisplay;
33 |
34 |
35 | namespace TOUCH_Utils {
36 |
37 | void sendBeaconFromTouch() { sendUpdate = true;}
38 |
39 | void enterMenuFromTouch() { BUTTON_Utils::doublePress();}
40 |
41 | void exitFromTouch() {
42 | menuDisplay = 0;
43 | //Serial.println("CANCEL BUTTON PRESSED");
44 | }
45 |
46 | TouchButton touchButtons_0[] = {
47 | {30, 110, 0, 28, "Send", 1, sendBeaconFromTouch}, // Button Send //drawButton(30, 210, 80, 28, "Send", 1);
48 | {125, 205, 0, 28, "Menu", 0, enterMenuFromTouch}, // Button Menu //drawButton(125, 210, 80, 28, "Menu", 0);
49 | {210, 305, 0, 28, "Exit", 2, exitFromTouch} // Button Exit //drawButton(210, 210, 95, 28, "Exit", 2);
50 | };
51 |
52 |
53 | bool touchButtonPressed(int touchX, int touchY, int Xmin, int Xmax, int Ymin, int Ymax) {
54 | return (touchX >= (Xmin - 5) && touchX <= (Xmax + 5) && touchY >= (Ymin - 5) && touchY <= (Ymax + 5));
55 | }
56 |
57 | void checkLiveButtons(uint16_t x, uint16_t y) {
58 | for (int i = 0; i < sizeof(touchButtons_0) / sizeof(touchButtons_0[0]); i++) {
59 | if (touchButtonPressed(x, y, touchButtons_0[i].Xmin, touchButtons_0[i].Xmax, touchButtons_0[i].Ymin, touchButtons_0[i].Ymax)) {
60 |
61 | if (touchButtons_0[i].action != nullptr && touchButtons_0[i].action != lastCalledAction) { // Call the action function associated with the button
62 | Serial.println(touchButtons_0[i].label + " pressed");
63 | touchButtons_0[i].action(); // Call the function pointer
64 | lastCalledAction = touchButtons_0[i].action; // Update the last called action
65 | } else {
66 | Serial.println("No action assigned to this button!");
67 | }
68 | }
69 | }
70 | }
71 |
72 | void loop() {
73 | if (touch.read() && (millis() - lastTouchTime > touchDebounce)) {
74 | TP_Point touchPoint = touch.getPoint(0);
75 | uint16_t xValueTouched = map(touchPoint.y, xCalibratedMin, xCalibratedMax, 0, xValueMax); // x and y values are inverted because
76 | uint16_t yValueTouched = map(touchPoint.x, yCalibratedMin, yCalibratedMax, 0, yValueMax); // TFT screen is rotated!!!!
77 | lastTouchTime = millis();
78 | //Serial.print(" X="); Serial.print(xValueTouched); Serial.print(" Y="); Serial.println(yValueTouched);
79 | checkLiveButtons(xValueTouched, yValueTouched);
80 | }
81 | if (millis() - lastTouchTime > 1000) lastCalledAction = nullptr; // reset touchButton when staying in same menu (like Tx/Send)
82 | }
83 |
84 | void setup() {
85 | if (touchModuleAddress != 0x00) {
86 | if (touchModuleAddress == 0x14) {
87 | touch = TouchLib(Wire, BOARD_I2C_SDA, BOARD_I2C_SCL, GT911_SLAVE_ADDRESS2);
88 | touch.init();
89 | } else if (touchModuleAddress == 0x5d) {
90 | touch = TouchLib(Wire, BOARD_I2C_SDA, BOARD_I2C_SCL, GT911_SLAVE_ADDRESS1);
91 | touch.init();
92 | } else {
93 | Serial.println("No Touch Module Address found");
94 | }
95 | }
96 | }
97 |
98 | }
99 |
100 | #endif
--------------------------------------------------------------------------------
/src/utils.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "configuration.h"
5 | #include "board_pinout.h"
6 | #include "lora_utils.h"
7 | #include "display.h"
8 | #include "utils.h"
9 |
10 | extern Beacon *currentBeacon;
11 | extern Configuration Config;
12 | extern logging::Logger logger;
13 |
14 | extern uint32_t lastTx;
15 | extern uint32_t lastTxTime;
16 |
17 | extern bool displayEcoMode;
18 | extern uint32_t displayTime;
19 | extern bool displayState;
20 | extern int menuDisplay;
21 | extern String versionDate;
22 | extern bool flashlight;
23 |
24 | extern bool statusState;
25 |
26 | uint32_t statusTime = millis();
27 | uint8_t wxModuleAddress = 0x00;
28 | uint8_t keyboardAddress = 0x00;
29 | uint8_t touchModuleAddress = 0x00;
30 |
31 |
32 | namespace Utils {
33 |
34 | static char locator[11]; // letterize and getMaidenheadLocator functions are Copyright (c) 2021 Mateusz Salwach - MIT License
35 |
36 | static char letterize(int x) {
37 | return (char) x + 65;
38 | }
39 |
40 | char *getMaidenheadLocator(double lat, double lon, uint8_t size) {
41 | double LON_F[]={20,2.0,0.083333,0.008333,0.0003472083333333333};
42 | double LAT_F[]={10,1.0,0.0416665,0.004166,0.0001735833333333333};
43 | int i;
44 | lon += 180;
45 | lat += 90;
46 |
47 | if (size <= 0 || size > 10) size = 6;
48 | size/=2; size*=2;
49 |
50 | for (i = 0; i < size/2; i++) {
51 | if (i % 2 == 1) {
52 | locator[i*2] = (char) (lon/LON_F[i] + '0');
53 | locator[i*2+1] = (char) (lat/LAT_F[i] + '0');
54 | } else {
55 | locator[i*2] = letterize((int) (lon/LON_F[i]));
56 | locator[i*2+1] = letterize((int) (lat/LAT_F[i]));
57 | }
58 | lon = fmod(lon, LON_F[i]);
59 | lat = fmod(lat, LAT_F[i]);
60 | }
61 | locator[i*2]=0;
62 | return locator;
63 | }
64 |
65 | static String padding(unsigned int number, unsigned int width) {
66 | String result;
67 | String num(number);
68 | if (num.length() > width) width = num.length();
69 | for (unsigned int i = 0; i < width - num.length(); i++) {
70 | result.concat('0');
71 | }
72 | result.concat(num);
73 | return result;
74 | }
75 |
76 | String createDateString(time_t t) {
77 | String dateString = padding(year(t), 4);
78 | dateString += "-";
79 | dateString += padding(month(t), 2);
80 | dateString += "-";
81 | dateString += padding(day(t), 2);
82 | return dateString;
83 | }
84 |
85 | String createTimeString(time_t t) {
86 | String timeString = padding(hour(t), 2);
87 | timeString += ":";
88 | timeString += padding(minute(t), 2);
89 | timeString += ":";
90 | timeString += padding(second(t), 2);
91 | return timeString;
92 | }
93 |
94 | void checkStatus() {
95 | if (statusState) {
96 | uint32_t currentTime = millis();
97 | uint32_t statusTx = currentTime - statusTime;
98 | lastTx = currentTime - lastTxTime;
99 | if (statusTx > 10 * 60 * 1000 && lastTx > 10 * 1000) {
100 | LoRa_Utils::sendNewPacket(APRSPacketLib::generateStatusPacket(currentBeacon->callsign, "APLRT1", Config.path, "https://github.com/richonguzman/LoRa_APRS_Tracker " + versionDate));
101 | statusState = false;
102 | }
103 | }
104 | }
105 |
106 | void checkDisplayEcoMode() {
107 | if (displayState && displayEcoMode && menuDisplay == 0) {
108 | uint32_t currentTime = millis();
109 | uint32_t lastDisplayTime = currentTime - displayTime;
110 | if (currentTime > 10 * 1000 && lastDisplayTime >= Config.display.timeout * 1000) {
111 | displayToggle(false);
112 | displayState = false;
113 | }
114 | }
115 | }
116 |
117 | String getSmartBeaconState() {
118 | if (currentBeacon->smartBeaconActive) return "On";
119 | return "Off";
120 | }
121 |
122 | void checkFlashlight() {
123 | if (flashlight && !digitalRead(Config.notification.ledFlashlightPin)) {
124 | digitalWrite(Config.notification.ledFlashlightPin, HIGH);
125 | } else if (!flashlight && digitalRead(Config.notification.ledFlashlightPin)) {
126 | digitalWrite(Config.notification.ledFlashlightPin, LOW);
127 | }
128 | }
129 |
130 | void i2cScannerForPeripherals() {
131 | uint8_t err, addr;
132 | if (Config.wxsensor.active) {
133 | for (addr = 1; addr < 0x7F; addr++) {
134 | #if defined(HELTEC_V3_GPS) || defined(HELTEC_V3_2_GPS)
135 | Wire1.beginTransmission(addr);
136 | err = Wire1.endTransmission();
137 | #else
138 | Wire.beginTransmission(addr);
139 | err = Wire.endTransmission();
140 | #endif
141 | if (err == 0) {
142 | //Serial.println(addr); this shows any connected board to I2C
143 | if (addr == 0x76 || addr == 0x77) {
144 | wxModuleAddress = addr;
145 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "Wx Module Connected to I2C");
146 | }
147 | }
148 | }
149 | }
150 |
151 | for (addr = 1; addr < 0x7F; addr++) {
152 | Wire.beginTransmission(addr);
153 | err = Wire.endTransmission();
154 | if (err == 0) {
155 | //Serial.println(addr); this shows any connected board to I2C
156 | if (addr == 0x55) { // T-Deck internal keyboard (Keyboard Backlight On = ALT + B)
157 | keyboardAddress = addr;
158 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "T-Deck Keyboard Connected to I2C");
159 | } else if (addr == 0x5F) { // CARDKB from m5stack.com (YEL - SDA / WTH SCL)
160 | keyboardAddress = addr;
161 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "CARDKB Keyboard Connected to I2C");
162 | }
163 | }
164 | }
165 |
166 | #ifdef HAS_TOUCHSCREEN
167 | for (addr = 1; addr < 0x7F; addr++) {
168 | Wire.beginTransmission(addr);
169 | err = Wire.endTransmission();
170 | if (err == 0) {
171 | if (addr == 0x14 || addr == 0x5D ) {
172 | touchModuleAddress = addr;
173 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "Touch Module Connected to I2C");
174 | }
175 | }
176 | }
177 | #endif
178 | }
179 |
180 | }
--------------------------------------------------------------------------------
/src/wifi_utils.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "configuration.h"
4 | #include "web_utils.h"
5 | #include "display.h"
6 |
7 |
8 | extern Configuration Config;
9 | extern logging::Logger logger;
10 |
11 | uint32_t noClientsTime = 0;
12 |
13 |
14 | namespace WIFI_Utils {
15 |
16 | void startAutoAP() {
17 | WiFi.mode(WIFI_MODE_NULL);
18 | WiFi.mode(WIFI_AP);
19 | WiFi.softAP("LoRaTracker-AP", Config.wifiAP.password);
20 | }
21 |
22 | void checkIfWiFiAP() {
23 | if (Config.wifiAP.active || Config.beacons[0].callsign == "NOCALL-7"){
24 | displayShow(" LoRa APRS", " ** WEB-CONF **","", "WiFiAP:LoRaTracker-AP", "IP : 192.168.4.1","");
25 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_WARN, "Main", "WebConfiguration Started!");
26 | startAutoAP();
27 | WEB_Utils::setup();
28 | while (true) {
29 | if (WiFi.softAPgetStationNum() > 0) {
30 | noClientsTime = 0;
31 | } else {
32 | if (noClientsTime == 0) {
33 | noClientsTime = millis();
34 | } else if ((millis() - noClientsTime) > 2 * 60 * 1000) {
35 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_WARN, "Main", "WebConfiguration Stopped!");
36 | displayShow("", "", " STOPPING WiFi AP", 2000);
37 | Config.wifiAP.active = false;
38 | Config.writeFile();
39 | WiFi.softAPdisconnect(true);
40 | ESP.restart();
41 | }
42 | }
43 | }
44 | } else {
45 | WiFi.mode(WIFI_OFF);
46 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "Main", "WiFi controller stopped");
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/winlink_utils.cpp:
--------------------------------------------------------------------------------
1 | #include "winlink_utils.h"
2 | #include "configuration.h"
3 | #include "msg_utils.h"
4 | #include "display.h"
5 | #include "logger.h"
6 |
7 |
8 | extern Configuration Config;
9 | extern int menuDisplay;
10 | extern logging::Logger logger;
11 |
12 | uint8_t winlinkStatus = 0;
13 | String winlinkMailNumber = "_?";
14 | String winlinkAddressee = "";
15 | String winlinkSubject = "";
16 | String winlinkBody = "";
17 | String winlinkAlias = "";
18 | String winlinkAliasComplete = "";
19 | bool winlinkCommentState = false;
20 |
21 | uint32_t lastChallengeTime = 0;
22 | String challengeAnswer;
23 |
24 |
25 |
26 | namespace WINLINK_Utils {
27 |
28 | void processWinlinkChallenge(const String& winlinkInteger) {
29 | uint32_t currenTime = millis();
30 | if (lastChallengeTime == 0 || (currenTime - lastChallengeTime) > 10 * 60 * 10000) {
31 | challengeAnswer = "";
32 | for (char c : winlinkInteger) {
33 | int digit = c - '0'; // Convert '0'-'9' to 0-9
34 | if (digit < 1 || digit > Config.winlink.password.length()) { // Ensure valid range
35 | displayShow(" WINLINK", "", "PASS Length Start Login");
51 | displayShow(" WINLINK", "" , "Login Initiation ...", "", "" , "
2 | #include
3 | #ifdef LIGHTTRACKER_PLUS_1_0
4 | #include "Adafruit_SHTC3.h"
5 | #endif
6 | #include "wx_utils.h"
7 | #include "configuration.h"
8 | #include "display.h"
9 |
10 | #define SEALEVELPRESSURE_HPA (1013.25)
11 | #define CORRECTION_FACTOR (8.2296) // for meters
12 |
13 | extern Configuration Config;
14 | extern logging::Logger logger;
15 | extern TinyGPSPlus gps;
16 |
17 | extern uint8_t wxModuleAddress;
18 |
19 | float newHum, newTemp, newPress, newGas;
20 |
21 | uint32_t sensorLastReading = -60000;
22 | int wxModuleType = 0;
23 |
24 | bool wxModuleFound = false;
25 |
26 |
27 | Adafruit_BME280 bme280;
28 | #if defined(HELTEC_V3_GPS) || defined(HELTEC_V3_TNC) || defined(HELTEC_V3_2_GPS) || defined(HELTEC_V3_2_TNC)
29 | Adafruit_BMP280 bmp280(&Wire1);
30 | #else
31 | Adafruit_BMP280 bmp280;
32 | Adafruit_BME680 bme680;
33 | #endif
34 | #ifdef LIGHTTRACKER_PLUS_1_0
35 | Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();
36 | #endif
37 |
38 |
39 |
40 | namespace WX_Utils {
41 |
42 | void setup() {
43 | if (Config.wxsensor.active) {
44 | #ifdef LIGHTTRACKER_PLUS_1_0
45 | if (!shtc3.begin()) {
46 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BME", " SHTC3 sensor not found");
47 | while (1) delay(1);
48 | }
49 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BME", " SHTC3 sensor found");
50 | wxModuleFound = true;
51 | wxModuleType = 4;
52 | #else
53 | if (wxModuleAddress != 0x00) {
54 | #if defined(HELTEC_V3_GPS) || defined(HELTEC_V3_TNC) || defined(HELTEC_V3_2_GPS) || defined(HELTEC_V3_2_TNC)
55 | if (bme280.begin(wxModuleAddress, &Wire1)) {
56 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BME", " BME280 sensor found");
57 | wxModuleType = 1;
58 | wxModuleFound = true;
59 | }
60 | #else
61 | if (bme280.begin(wxModuleAddress)) {
62 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BME", " BME280 sensor found");
63 | wxModuleType = 1;
64 | wxModuleFound = true;
65 | }
66 | if (!wxModuleFound) {
67 | if (bme680.begin(wxModuleAddress)) {
68 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BME", " BME680 sensor found");
69 | wxModuleType = 3;
70 | wxModuleFound = true;
71 | }
72 | }
73 | #endif
74 | if (!wxModuleFound) {
75 | if (bmp280.begin(wxModuleAddress)) {
76 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BME", " BMP280 sensor found");
77 | wxModuleType = 2;
78 | wxModuleFound = true;
79 | }
80 | }
81 | if (!wxModuleFound) {
82 | displayShow("ERROR", "BME/BMP sensor active", "but no sensor found...", 2000);
83 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_WARN, "BME", " BME/BMP sensor Active in config but not found! Check Wiring");
84 | } else {
85 | switch (wxModuleType) {
86 | case 1:
87 | bme280.setSampling(Adafruit_BME280::MODE_FORCED,
88 | Adafruit_BME280::SAMPLING_X1,
89 | Adafruit_BME280::SAMPLING_X1,
90 | Adafruit_BME280::SAMPLING_X1,
91 | Adafruit_BME280::FILTER_OFF
92 | );
93 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BME", " BME280 Module init done!");
94 | break;
95 | case 2:
96 | bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
97 | Adafruit_BMP280::SAMPLING_X1,
98 | Adafruit_BMP280::SAMPLING_X1,
99 | Adafruit_BMP280::FILTER_OFF
100 | );
101 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BMP", " BMP280 Module init done!");
102 | break;
103 | case 3:
104 | #if !defined(HELTEC_V3_GPS) && !defined(HELTEC_V3_TNC) && !defined(HELTEC_V3_2_GPS) && !defined(HELTEC_V3_2_TNC)
105 | bme680.setTemperatureOversampling(BME680_OS_1X);
106 | bme680.setHumidityOversampling(BME680_OS_1X);
107 | bme680.setPressureOversampling(BME680_OS_1X);
108 | bme680.setIIRFilterSize(BME680_FILTER_SIZE_0);
109 | logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BME", " BMP680 Module init done!");
110 | #endif
111 | break;
112 | }
113 | }
114 | }
115 | #endif
116 | }
117 | }
118 |
119 | const String generateTempString(const float sensorTemp, const uint8_t type) {
120 | String strTemp;
121 | if (type == 1) { // OLED
122 | strTemp = String((int)sensorTemp);
123 | } else {
124 | strTemp = String((int)((sensorTemp * 1.8) + 32));
125 | }
126 | switch (strTemp.length()) {
127 | case 1:
128 | if (type == 1) {
129 | return " " + strTemp;
130 | } else {
131 | return "00" + strTemp;
132 | }
133 | case 2:
134 | if (type == 1) {
135 | return " " + strTemp;
136 | } else {
137 | return "0" + strTemp;
138 | }
139 | case 3:
140 | return strTemp;
141 | default:
142 | return "-999";
143 | }
144 | }
145 |
146 | const String generateHumString(const float sensorHum, const uint8_t type) {
147 | String strHum = String((int)sensorHum);
148 | switch (strHum.length()) {
149 | case 1:
150 | if (type == 1) {
151 | return " " + strHum;
152 | } else {
153 | return "0" + strHum;
154 | }
155 | case 2:
156 | return strHum;
157 | case 3:
158 | if ((int)sensorHum == 100) {
159 | if (type == 1) {
160 | return " ";
161 | } else {
162 | return "00";
163 | }
164 | } else {
165 | return "-99";
166 | }
167 | default:
168 | return "-99";
169 | }
170 | }
171 |
172 | const String generatePresString(const float sensorPress, const uint8_t type) {
173 | String strPress = String((int)sensorPress);
174 | String decPress = String(int((sensorPress - int(sensorPress)) * 10));
175 | switch (strPress.length()) {
176 | case 1:
177 | if (type == 1) {
178 | return "000" + strPress;
179 | } else {
180 | return "000" + strPress + decPress;
181 | }
182 | case 2:
183 | if (type == 1) {
184 | return "00" + strPress;
185 | } else {
186 | return "00" + strPress + decPress;
187 | }
188 | case 3:
189 | if (type == 1) {
190 | return "0" + strPress;
191 | } else {
192 | return "0" + strPress + decPress;
193 | }
194 | case 4:
195 | if (type == 1) {
196 | return strPress;
197 | } else {
198 | return strPress + decPress;
199 | }
200 | case 5:
201 | return strPress;
202 | default:
203 | return "-99999";
204 | }
205 | }
206 |
207 | const String readDataSensor(const uint8_t type) {
208 | uint32_t lastReading = millis() - sensorLastReading;
209 | if (lastReading > 60 * 1000) {
210 | #ifdef LIGHTTRACKER_PLUS_1_0
211 | sensors_event_t humidity, temp;
212 | shtc3.getEvent(&humidity, &temp);
213 | newTemp = temp.temperature;
214 | newHum = humidity.relative_humidity;
215 | newPress = 0;
216 | #else
217 | switch (wxModuleType) {
218 | case 1: // BME280
219 | bme280.takeForcedMeasurement();
220 | newTemp = bme280.readTemperature();
221 | newPress = (bme280.readPressure() / 100.0F);
222 | newHum = bme280.readHumidity();
223 | break;
224 | case 2: // BMP280
225 | bmp280.takeForcedMeasurement();
226 | newTemp = bmp280.readTemperature();
227 | newPress = (bmp280.readPressure() / 100.0F);
228 | newHum = 0;
229 | break;
230 | case 3: // BME680
231 | #if !defined(HELTEC_V3_GPS) && !defined(HELTEC_V3_TNC) && !defined(HELTEC_V3_2_GPS) && !defined(HELTEC_V3_2_TNC)
232 | bme680.performReading();
233 | delay(50);
234 | if (bme680.endReading()) {
235 | newTemp = bme680.temperature;
236 | newPress = (bme680.pressure / 100.0F);
237 | newHum = bme680.humidity;
238 | newGas = bme680.gas_resistance / 1000.0; // in Kilo ohms
239 | }
240 | #endif
241 | break;
242 | }
243 | #endif
244 | sensorLastReading = millis();
245 | }
246 |
247 | String wx;
248 | if (isnan(newTemp) || isnan(newHum) || isnan(newPress)) {
249 | Serial.println("WX Sensor data failed");
250 | wx = ((type == 1) ? " - C - % - hPa" : ".../...g...t...");
251 | return wx;
252 | } else {
253 | String tempStr = generateTempString(newTemp + Config.wxsensor.temperatureCorrection, type);
254 | String humStr;
255 | #ifdef LIGHTTRACKER_PLUS_1_0
256 | humStr = generateHumString(newHum,type);
257 | #else
258 | if (wxModuleType == 1 || wxModuleType == 3) {
259 | humStr = generateHumString(newHum,type);
260 | } else if (wxModuleType == 2) {
261 | humStr = "..";
262 | }
263 | #endif
264 | String presStr = generatePresString(newPress + (gps.altitude.meters()/CORRECTION_FACTOR), type);
265 | #ifdef LIGHTTRACKER_PLUS_1_0
266 | if (type == 1) {
267 | wx = tempStr;
268 | wx += "C ";
269 | wx += humStr;
270 | wx += "% ";
271 | } else {
272 | wx = ".../...g...t";
273 | wx += tempStr;
274 | wx += "h";
275 | wx += humStr;
276 | }
277 | #else
278 | if (type == 1) {
279 | if (wxModuleType == 1 || wxModuleType == 3) {
280 | wx = tempStr;
281 | wx += "C ";
282 | wx += humStr;
283 | wx += "% ";
284 | wx += presStr;
285 | wx += "hPa";
286 | } else if (wxModuleType == 2) {
287 | wx = "T: ";
288 | wx += tempStr;
289 | wx += "C P: ";
290 | wx += presStr;
291 | wx += "hPa";
292 | }
293 | } else {
294 | wx = ".../...g...t";
295 | wx += tempStr;
296 | wx += "h";
297 | wx += humStr;
298 | wx += "b";
299 | wx += presStr;
300 | if (wxModuleType == 3) {
301 | wx += "Gas: ";
302 | wx += String(newGas);
303 | wx += "Kohms";
304 | }
305 | }
306 | #endif
307 | return wx;
308 | }
309 | }
310 |
311 | }
--------------------------------------------------------------------------------
/tools/compress.py:
--------------------------------------------------------------------------------
1 | import gzip
2 | import os
3 | import datetime
4 | Import("env")
5 |
6 | files = [
7 | 'data_embed/index.html',
8 | 'data_embed/script.js',
9 | 'data_embed/style.css',
10 | 'data_embed/bootstrap.js',
11 | 'data_embed/bootstrap.css',
12 | 'data_embed/favicon.png',
13 | ]
14 |
15 | string_to_find_str = "String"
16 | string_to_find_ver = "versionDate"
17 |
18 | with open('src/LoRa_APRS_Tracker.cpp', encoding='utf-8') as cpp_file:
19 | for line in cpp_file:
20 | if string_to_find_str in line and string_to_find_ver in line:
21 | start = line.find('"') + 1
22 | end = line.find('"', start)
23 | if start > 0 and end > start:
24 | versionDate = line[start:end]
25 | break
26 |
27 | for src in files:
28 | out = src + ".gz"
29 |
30 |
31 | with open(src, 'rb') as f:
32 | content = f.read()
33 |
34 | if src == 'data_embed/index.html':
35 | env_vars = env["BOARD"] + "
" + ','.join(env["BUILD_FLAGS"]).replace('-Werror -Wall,', '').replace(',-DELEGANTOTA_USE_ASYNC_WEBSERVER=1', '') + "
" + "Version date: " + versionDate
36 | current_date = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') + " UTC"
37 | build_info = f'{env_vars}
Build date: {current_date}'.encode()
38 |
39 | content = content.replace(b'%BUILD_INFO%', build_info)
40 |
41 | with open(out, 'wb') as f:
42 | f.write(gzip.compress(content, compresslevel=9))
--------------------------------------------------------------------------------
/variants/ESP32S3_DIY_LoRa_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define GPS_RX 12
24 | #define GPS_TX 34
25 |
26 | // OTHER
27 | #define BUTTON_PIN 15
28 | #define BATTERY_PIN 35 //LoRa32 Battery PIN 100k/100k
29 |
30 | #endif
--------------------------------------------------------------------------------
/variants/ESP32S3_DIY_LoRa_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ESP32S3_DIY_LoRa_GPS]
2 | extends = env:esp32
3 | board = esp32-s3-devkitc-1
4 | board_build.mcu = esp32s3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D ESP32S3_DIY_LoRa_GPS
9 | lib_deps =
10 | ${common.lib_deps}
11 | ${common.display_libs}
12 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ESP32S3_DIY_LoRa_GPS_915/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1276
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define GPS_RX 12
24 | #define GPS_TX 34
25 |
26 | // OTHER
27 | #define BUTTON_PIN 15
28 | #define BATTERY_PIN 35 //LoRa32 Battery PIN 100k/100k
29 |
30 | #endif
--------------------------------------------------------------------------------
/variants/ESP32S3_DIY_LoRa_GPS_915/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ESP32S3_DIY_LoRa_GPS_915]
2 | extends = env:esp32
3 | board = esp32-s3-devkitc-1
4 | board_build.mcu = esp32s3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D ESP32S3_DIY_LoRa_GPS_915
9 | lib_deps =
10 | ${common.lib_deps}
11 | ${common.display_libs}
12 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ESP32_DIY_1W_LoRa_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1268
6 | #define HAS_1W_LORA
7 | #define RADIO_SCLK_PIN 18
8 | #define RADIO_MISO_PIN 19
9 | #define RADIO_MOSI_PIN 23
10 | #define RADIO_CS_PIN 5
11 | #define RADIO_RST_PIN 27
12 | #define RADIO_DIO1_PIN 12
13 | #define RADIO_BUSY_PIN 14
14 | #define RADIO_RXEN 32
15 | #define RADIO_TXEN 25
16 |
17 | // Display
18 | #undef OLED_SDA
19 | #undef OLED_SCL
20 | #undef OLED_RST
21 |
22 | #define OLED_SDA 21
23 | #define OLED_SCL 22
24 | #define OLED_RST -1
25 |
26 | // GPS
27 | #define GPS_RX 17
28 | #define GPS_TX 16
29 |
30 | // OTHER
31 | #define BUTTON_PIN 15
32 | #define BATTERY_PIN 35
33 |
34 | #define HAS_BT_CLASSIC
35 |
36 | #endif
--------------------------------------------------------------------------------
/variants/ESP32_DIY_1W_LoRa_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ESP32_DIY_1W_LoRa_GPS]
2 | extends = env:esp32
3 | board = esp32dev
4 | build_flags =
5 | ${common.build_flags}
6 | -D ESP32_DIY_1W_LoRa_GPS
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ESP32_DIY_1W_LoRa_GPS_915/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define HAS_1W_LORA
7 | #define RADIO_SCLK_PIN 18
8 | #define RADIO_MISO_PIN 19
9 | #define RADIO_MOSI_PIN 23
10 | #define RADIO_CS_PIN 5
11 | #define RADIO_RST_PIN 27
12 | #define RADIO_DIO1_PIN 12
13 | #define RADIO_BUSY_PIN 14
14 | #define RADIO_RXEN 32
15 | #define RADIO_TXEN 25
16 |
17 | // Display
18 | #undef OLED_SDA
19 | #undef OLED_SCL
20 | #undef OLED_RST
21 |
22 | #define OLED_SDA 21
23 | #define OLED_SCL 22
24 | #define OLED_RST -1
25 |
26 | // GPS
27 | #define GPS_RX 17
28 | #define GPS_TX 16
29 |
30 | // OTHER
31 | #define BUTTON_PIN 15
32 | #define BATTERY_PIN 35
33 |
34 | #define HAS_BT_CLASSIC
35 |
36 | #endif
--------------------------------------------------------------------------------
/variants/ESP32_DIY_1W_LoRa_GPS_915/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ESP32_DIY_1W_LoRa_GPS_915]
2 | extends = env:esp32
3 | board = esp32dev
4 | build_flags =
5 | ${common.build_flags}
6 | -D ESP32_DIY_1W_LoRa_GPS_915
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ESP32_DIY_1W_LoRa_GPS_LLCC68/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_LLCC68
6 | #define HAS_1W_LORA
7 | #define RADIO_SCLK_PIN 18
8 | #define RADIO_MISO_PIN 19
9 | #define RADIO_MOSI_PIN 23
10 | #define RADIO_CS_PIN 5
11 | #define RADIO_RST_PIN 27
12 | #define RADIO_DIO1_PIN 12
13 | #define RADIO_BUSY_PIN 14
14 | #define RADIO_RXEN 32
15 | #define RADIO_TXEN 25
16 |
17 | // Display
18 | #undef OLED_SDA
19 | #undef OLED_SCL
20 | #undef OLED_RST
21 |
22 | #define OLED_SDA 21
23 | #define OLED_SCL 22
24 | #define OLED_RST -1
25 |
26 | // GPS
27 | #define GPS_RX 17
28 | #define GPS_TX 16
29 |
30 | // OTHER
31 | #define BUTTON_PIN 15
32 | #define BATTERY_PIN 35
33 |
34 | #define HAS_BT_CLASSIC
35 |
36 | #endif
--------------------------------------------------------------------------------
/variants/ESP32_DIY_1W_LoRa_GPS_LLCC68/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ESP32_DIY_1W_LoRa_GPS_LLCC68]
2 | extends = env:esp32
3 | board = esp32dev
4 | build_flags =
5 | ${common.build_flags}
6 | -D ESP32_DIY_1W_LoRa_GPS_LLCC68
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ESP32_DIY_LoRa_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define GPS_RX 12
24 | #define GPS_TX 34
25 |
26 | // OTHER
27 | #define BUTTON_PIN 15
28 | #define BATTERY_PIN 35 //LoRa32 Battery PIN 100k/100k
29 |
30 | #define HAS_BT_CLASSIC
31 |
32 | #endif
--------------------------------------------------------------------------------
/variants/ESP32_DIY_LoRa_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ESP32_DIY_LoRa_GPS]
2 | extends = env:esp32
3 | board = esp32dev
4 | build_flags =
5 | ${common.build_flags}
6 | -D ESP32_DIY_LoRa_GPS
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ESP32_DIY_LoRa_GPS_915/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define GPS_RX 12
24 | #define GPS_TX 34
25 |
26 | // OTHER
27 | #define BUTTON_PIN 15
28 | #define BATTERY_PIN 35 //LoRa32 Battery PIN 100k/100k
29 |
30 | #define HAS_BT_CLASSIC
31 |
32 | #endif
--------------------------------------------------------------------------------
/variants/ESP32_DIY_LoRa_GPS_915/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ESP32_DIY_LoRa_GPS_915]
2 | extends = env:esp32
3 | board = esp32dev
4 | build_flags =
5 | ${common.build_flags}
6 | -D ESP32_DIY_LoRa_GPS_915
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/F4GOH_1W_LoRa_Tracker/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1268
6 | #define HAS_1W_LORA
7 | #define RADIO_SCLK_PIN 5
8 | #define RADIO_MISO_PIN 19
9 | #define RADIO_MOSI_PIN 27
10 | #define RADIO_CS_PIN 18
11 | #define RADIO_RST_PIN 23
12 | #define RADIO_DIO1_PIN 33
13 | #define RADIO_BUSY_PIN 32
14 | #define RADIO_RXEN 14
15 | #define RADIO_TXEN 13
16 |
17 | // Display
18 | #undef OLED_SDA
19 | #undef OLED_SCL
20 | #undef OLED_RST
21 |
22 | #define OLED_SDA 21
23 | #define OLED_SCL 22
24 | #define OLED_RST -1
25 |
26 | // GPS
27 | #define GPS_RX 17
28 | #define GPS_TX 16
29 | #define GPS_VCC 4
30 |
31 | // OTHER
32 | #define BUTTON_PIN 12
33 | #define BATTERY_PIN 35
34 |
35 | #define HAS_BT_CLASSIC
36 |
37 | #endif
--------------------------------------------------------------------------------
/variants/F4GOH_1W_LoRa_Tracker/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:F4GOH_1W_LoRa_Tracker]
2 | extends = env:esp32
3 | board = esp32dev
4 | build_flags =
5 | ${common.build_flags}
6 | -D F4GOH_1W_LoRa_Tracker
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/F4GOH_1W_LoRa_Tracker_LLCC68/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_LLCC68
6 | #define HAS_1W_LORA
7 | #define RADIO_SCLK_PIN 5
8 | #define RADIO_MISO_PIN 19
9 | #define RADIO_MOSI_PIN 27
10 | #define RADIO_CS_PIN 18
11 | #define RADIO_RST_PIN 23
12 | #define RADIO_DIO1_PIN 33
13 | #define RADIO_BUSY_PIN 32
14 | #define RADIO_RXEN 14
15 | #define RADIO_TXEN 13
16 |
17 | // Display
18 | #undef OLED_SDA
19 | #undef OLED_SCL
20 | #undef OLED_RST
21 |
22 | #define OLED_SDA 21
23 | #define OLED_SCL 22
24 | #define OLED_RST -1
25 |
26 | // GPS
27 | #define GPS_RX 17
28 | #define GPS_TX 16
29 | #define GPS_VCC 4
30 |
31 | // OTHER
32 | #define BUTTON_PIN 12
33 | #define BATTERY_PIN 35
34 |
35 | #define HAS_BT_CLASSIC
36 |
37 | #endif
--------------------------------------------------------------------------------
/variants/F4GOH_1W_LoRa_Tracker_LLCC68/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:F4GOH_1W_LoRa_Tracker_LLCC68]
2 | extends = env:esp32
3 | board = esp32dev
4 | build_flags =
5 | ${common.build_flags}
6 | -D F4GOH_1W_LoRa_Tracker_LLCC68
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/OE5HWN_MeshCom/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1268
6 | #define HAS_1W_LORA
7 | #define RADIO_SCLK_PIN 18
8 | #define RADIO_MISO_PIN 19
9 | #define RADIO_MOSI_PIN 23
10 | #define RADIO_CS_PIN 5
11 | #define RADIO_RST_PIN 27
12 | #define RADIO_DIO1_PIN 33
13 | #define RADIO_BUSY_PIN 26
14 | #define RADIO_RXEN 14
15 | #define RADIO_TXEN 13
16 |
17 | // Display
18 | #undef OLED_SDA
19 | #undef OLED_SCL
20 | #undef OLED_RST
21 |
22 | #define OLED_SDA 21
23 | #define OLED_SCL 22
24 | #define OLED_RST -1
25 |
26 | // GPS
27 | #define GPS_RX 17
28 | #define GPS_TX 16
29 |
30 | // OTHER
31 | #define BUTTON_PIN 12
32 | #define BATTERY_PIN 35
33 |
34 | #define HAS_BT_CLASSIC
35 |
36 | #endif
--------------------------------------------------------------------------------
/variants/OE5HWN_MeshCom/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:OE5HWN_MeshCom]
2 | extends = env:esp32
3 | board = esp32dev
4 | build_flags =
5 | ${common.build_flags}
6 | -D OE5HWN_MeshCom
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/QRPLabs_LightTracker_Plus_1_0/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1268
6 | #define HAS_1W_LORA
7 | #define RADIO_VCC_PIN 21
8 | #define RADIO_SCLK_PIN 12
9 | #define RADIO_MISO_PIN 13
10 | #define RADIO_MOSI_PIN 11
11 | #define RADIO_CS_PIN 10
12 | #define RADIO_RST_PIN 9
13 | #define RADIO_DIO1_PIN 5
14 | #define RADIO_BUSY_PIN 6
15 | #define RADIO_RXEN 42
16 | #define RADIO_TXEN 14
17 |
18 | // Display
19 | #undef OLED_SDA
20 | #undef OLED_SCL
21 | #undef OLED_RST
22 |
23 | #define OLED_SDA 3
24 | #define OLED_SCL 4
25 | #define OLED_RST -1
26 |
27 | // GPS
28 | #define GPS_RX 17
29 | #define GPS_TX 18
30 | #define GPS_VCC 33 //#define LED_PIN 16
31 |
32 | // OTHER
33 | #define BUTTON_PIN 0
34 | #define BATTERY_PIN 1
35 |
36 | #endif
--------------------------------------------------------------------------------
/variants/QRPLabs_LightTracker_Plus_1_0/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:QRPLabs_LightTracker_Plus_1_0]
2 | extends = env:esp32
3 | board = esp32-s3-devkitc-1
4 | board_build.mcu = esp32s3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D LIGHTTRACKER_PLUS_1_0
9 | lib_deps =
10 | ${common.lib_deps}
11 | adafruit/Adafruit SHTC3 Library @ 1.0.1
--------------------------------------------------------------------------------
/variants/TROY_LoRa_APRS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST -1
21 |
22 | // GPS
23 | #define GPS_RX 12
24 | #define GPS_TX 34
25 |
26 | // OTHER
27 | #define BUTTON_PIN 4
28 |
29 | #define HAS_BT_CLASSIC
30 |
31 | #endif
--------------------------------------------------------------------------------
/variants/TROY_LoRa_APRS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:TROY_LoRa_APRS]
2 | extends = env:esp32
3 | board = esp32dev
4 | build_flags =
5 | ${common.build_flags}
6 | -D TROY_LoRa_APRS
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/Wemos_ESP32_Bat_LoRa_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 18
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 23
9 | #define RADIO_CS_PIN 5
10 | #define RADIO_RST_PIN 27
11 | #define RADIO_DIO1_PIN 12
12 | #define RADIO_BUSY_PIN 14
13 |
14 | // Display
15 | #undef OLED_SDA
16 | #undef OLED_SCL
17 | #undef OLED_RST
18 |
19 | #define OLED_SDA 21
20 | #define OLED_SCL 22
21 | #define OLED_RST -1
22 |
23 | // GPS
24 | #define GPS_RX 4
25 | #define GPS_TX 17
26 |
27 | // OTHER
28 | #define BUTTON_PIN 15
29 | #define BATTERY_PIN 35
30 |
31 | #define HAS_BT_CLASSIC
32 |
33 | #endif
--------------------------------------------------------------------------------
/variants/Wemos_ESP32_Bat_LoRa_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:Wemos_ESP32_Bat_LoRa_GPS]
2 | extends = env:esp32
3 | board = esp32dev
4 | build_flags =
5 | ${common.build_flags}
6 | -D WEMOS_ESP32_Bat_LoRa_GPS
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/esp32_c3_DIY_LoRa_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 4
7 | #define RADIO_MISO_PIN 5
8 | #define RADIO_MOSI_PIN 6
9 | #define RADIO_CS_PIN 7
10 | #define RADIO_RST_PIN 3
11 | #define RADIO_BUSY_PIN 2
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 8
19 | #define OLED_SCL 9
20 | #define OLED_RST 10
21 |
22 | // GPS
23 | #define GPS_RX 20
24 | #define GPS_TX 21
25 |
26 | // OTHER
27 | #define BATTERY_PIN 1
28 |
29 | #endif
--------------------------------------------------------------------------------
/variants/esp32_c3_DIY_LoRa_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:esp32_c3_DIY_LoRa_GPS]
2 | extends = env:esp32
3 | board = esp32-c3-devkitm-1
4 | board_build.mcu = esp32c3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D ESP32_C3_DIY_LoRa_GPS
9 | lib_deps =
10 | ${common.lib_deps}
11 | ${common.display_libs}
12 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/esp32_c3_DIY_LoRa_GPS_915/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1276
6 | #define RADIO_SCLK_PIN 4
7 | #define RADIO_MISO_PIN 5
8 | #define RADIO_MOSI_PIN 6
9 | #define RADIO_CS_PIN 7
10 | #define RADIO_RST_PIN 3
11 | #define RADIO_BUSY_PIN 2
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 8
19 | #define OLED_SCL 9
20 | #define OLED_RST 10
21 |
22 | // GPS
23 | #define GPS_RX 20
24 | #define GPS_TX 21
25 |
26 | // OTHER
27 | #define BATTERY_PIN 1
28 |
29 | #endif
--------------------------------------------------------------------------------
/variants/esp32_c3_DIY_LoRa_GPS_915/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:esp32_c3_DIY_LoRa_GPS_915]
2 | extends = env:esp32
3 | board = esp32-c3-devkitm-1
4 | board_build.mcu = esp32c3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D ESP32_C3_DIY_LoRa_GPS_915
9 | lib_deps =
10 | ${common.lib_deps}
11 | ${common.display_libs}
12 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/heltec-lora32-v2_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 14
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 4
19 | #define OLED_SCL 15
20 | #define OLED_RST 16
21 | #define OLED_DISPLAY_HAS_RST_PIN
22 |
23 | // GPS
24 | #define GPS_RX 12
25 | #define GPS_TX 34
26 |
27 | // OTHER
28 | #define BATTERY_PIN 37
29 | #define BUTTON_PIN 0
30 | #define ADC_CTRL 21
31 |
32 | #define HAS_BT_CLASSIC
33 |
34 | #endif
--------------------------------------------------------------------------------
/variants/heltec-lora32-v2_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:heltec-lora32-v2_GPS]
2 | extends = env:esp32
3 | board = heltec_wifi_lora_32_V2
4 | build_flags =
5 | ${common.build_flags}
6 | -D HELTEC_V2_GPS
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
--------------------------------------------------------------------------------
/variants/heltec-lora32-v2_GPS_915/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1276
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 14
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 4
19 | #define OLED_SCL 15
20 | #define OLED_RST 16
21 | #define OLED_DISPLAY_HAS_RST_PIN
22 |
23 | // GPS
24 | #define GPS_RX 12
25 | #define GPS_TX 34
26 |
27 | // OTHER
28 | #define BATTERY_PIN 37
29 | #define BUTTON_PIN 0
30 | #define ADC_CTRL 21
31 |
32 | #define HAS_BT_CLASSIC
33 |
34 | #endif
--------------------------------------------------------------------------------
/variants/heltec-lora32-v2_GPS_915/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:heltec-lora32-v2_GPS_915]
2 | extends = env:esp32
3 | board = heltec_wifi_lora_32_V2
4 | build_flags =
5 | ${common.build_flags}
6 | -D HELTEC_V2_GPS_915
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
--------------------------------------------------------------------------------
/variants/heltec-lora32-v2_TNC/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 14
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 4
19 | #define OLED_SCL 15
20 | #define OLED_RST 16
21 | #define OLED_DISPLAY_HAS_RST_PIN
22 |
23 | // GPS
24 | #define HAS_NO_GPS
25 | #define GPS_RX -1
26 | #define GPS_TX -1
27 |
28 | // OTHER
29 | #define BATTERY_PIN 37
30 | #define BUTTON_PIN 0
31 | #define ADC_CTRL 21
32 |
33 | #define HAS_BT_CLASSIC
34 |
35 | #endif
--------------------------------------------------------------------------------
/variants/heltec-lora32-v2_TNC/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:heltec-lora32-v2_TNC]
2 | extends = env:esp32
3 | board = heltec_wifi_lora_32_V2
4 | build_flags =
5 | ${common.build_flags}
6 | -D HELTEC_V2_TNC
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
--------------------------------------------------------------------------------
/variants/heltec_ht-ct62_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 10
7 | #define RADIO_MISO_PIN 6
8 | #define RADIO_MOSI_PIN 7
9 | #define RADIO_CS_PIN 8
10 | #define RADIO_RST_PIN 5
11 | #define RADIO_DIO1_PIN 3
12 | #define RADIO_BUSY_PIN 4
13 |
14 | // Display
15 | #undef OLED_SDA
16 | #undef OLED_SCL
17 | #undef OLED_RST
18 |
19 | #define OLED_SDA 18
20 | #define OLED_SCL 19
21 | #define OLED_RST -1
22 |
23 | // GPS
24 | #define GPS_RX 0
25 | #define GPS_TX 1
26 |
27 | #endif
--------------------------------------------------------------------------------
/variants/heltec_ht-ct62_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:heltec_ht-ct62_GPS]
2 | extends = env:esp32
3 | board = heltec_wireless_stick_lite
4 | board_build.mcu = esp32c3
5 | build_flags =
6 | ${common.build_flags}
7 | -D HELTEC_HTCT62_GPS
8 | lib_deps =
9 | ${common.lib_deps}
10 | ${common.display_libs}
--------------------------------------------------------------------------------
/variants/heltec_wifi_lora_32_v3_2_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 9
7 | #define RADIO_MISO_PIN 11
8 | #define RADIO_MOSI_PIN 10
9 | #define RADIO_CS_PIN 8
10 | #define RADIO_RST_PIN 12
11 | #define RADIO_DIO1_PIN 14
12 | #define RADIO_BUSY_PIN 13
13 |
14 | // Display
15 | #undef OLED_SDA
16 | #undef OLED_SCL
17 | #undef OLED_RST
18 |
19 | #define OLED_SDA 17
20 | #define OLED_SCL 18
21 | #define OLED_RST 21
22 |
23 | // GPS
24 | #define GPS_RX 47
25 | #define GPS_TX 48
26 |
27 | // OTHER
28 | #define BUTTON_PIN 0
29 | #define BATTERY_PIN 1
30 | #define VEXT_CTRL 36
31 | #define ADC_CTRL 37
32 |
33 | #define BOARD_I2C_SDA 41
34 | #define BOARD_I2C_SCL 42
35 |
36 | #endif
--------------------------------------------------------------------------------
/variants/heltec_wifi_lora_32_v3_2_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:heltec_wifi_lora_32_v3_2_GPS]
2 | extends = env:esp32
3 | board = heltec_wifi_lora_32_V3
4 | board_build.mcu = esp32s3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D HELTEC_V3_2_GPS
9 | lib_deps =
10 | ${common.lib_deps}
11 | ${common.display_libs}
--------------------------------------------------------------------------------
/variants/heltec_wifi_lora_32_v3_2_TNC/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 9
7 | #define RADIO_MISO_PIN 11
8 | #define RADIO_MOSI_PIN 10
9 | #define RADIO_CS_PIN 8
10 | #define RADIO_RST_PIN 12
11 | #define RADIO_DIO1_PIN 14
12 | #define RADIO_BUSY_PIN 13
13 |
14 | // Display
15 | #undef OLED_SDA
16 | #undef OLED_SCL
17 | #undef OLED_RST
18 |
19 | #define OLED_SDA 17
20 | #define OLED_SCL 18
21 | #define OLED_RST 21
22 |
23 | // GPS
24 | #define HAS_NO_GPS
25 | #define GPS_RX -1
26 | #define GPS_TX -1
27 |
28 | // OTHER
29 | #define BUTTON_PIN 0
30 | #define BATTERY_PIN 1
31 | #define VEXT_CTRL 36
32 | #define ADC_CTRL 37 // Heltec V3 needs ADC_CTRL = LOW powers the voltage divider to read BatteryPin
33 |
34 | #define BOARD_I2C_SDA 41
35 | #define BOARD_I2C_SCL 42
36 |
37 | #endif
--------------------------------------------------------------------------------
/variants/heltec_wifi_lora_32_v3_2_TNC/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:heltec_wifi_lora_32_v3_2_TNC]
2 | extends = env:esp32
3 | board = heltec_wifi_lora_32_V3
4 | board_build.mcu = esp32s3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D HELTEC_V3_2_TNC
9 | lib_deps =
10 | ${common.lib_deps}
11 | ${common.display_libs}
--------------------------------------------------------------------------------
/variants/heltec_wifi_lora_32_v3_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 9
7 | #define RADIO_MISO_PIN 11
8 | #define RADIO_MOSI_PIN 10
9 | #define RADIO_CS_PIN 8
10 | #define RADIO_RST_PIN 12
11 | #define RADIO_DIO1_PIN 14
12 | #define RADIO_BUSY_PIN 13
13 |
14 | // Display
15 | #undef OLED_SDA
16 | #undef OLED_SCL
17 | #undef OLED_RST
18 |
19 | #define OLED_SDA 17
20 | #define OLED_SCL 18
21 | #define OLED_RST 21
22 |
23 | // GPS
24 | #define GPS_RX 47
25 | #define GPS_TX 48
26 |
27 | // OTHER
28 | #define BUTTON_PIN 0
29 | #define BATTERY_PIN 1
30 | #define VEXT_CTRL 36
31 | #define ADC_CTRL 37
32 |
33 | #define BOARD_I2C_SDA 41
34 | #define BOARD_I2C_SCL 42
35 |
36 | #endif
--------------------------------------------------------------------------------
/variants/heltec_wifi_lora_32_v3_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:heltec_wifi_lora_32_v3_GPS]
2 | extends = env:esp32
3 | board = heltec_wifi_lora_32_V3
4 | board_build.mcu = esp32s3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D HELTEC_V3_GPS
9 | lib_deps =
10 | ${common.lib_deps}
11 | ${common.display_libs}
--------------------------------------------------------------------------------
/variants/heltec_wifi_lora_32_v3_TNC/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 9
7 | #define RADIO_MISO_PIN 11
8 | #define RADIO_MOSI_PIN 10
9 | #define RADIO_CS_PIN 8
10 | #define RADIO_RST_PIN 12
11 | #define RADIO_DIO1_PIN 14
12 | #define RADIO_BUSY_PIN 13
13 |
14 | // Display
15 | #undef OLED_SDA
16 | #undef OLED_SCL
17 | #undef OLED_RST
18 |
19 | #define OLED_SDA 17
20 | #define OLED_SCL 18
21 | #define OLED_RST 21
22 |
23 | // GPS
24 | #define HAS_NO_GPS
25 | #define GPS_RX -1
26 | #define GPS_TX -1
27 |
28 | // OTHER
29 | #define BUTTON_PIN 0
30 | #define BATTERY_PIN 1
31 | #define VEXT_CTRL 36
32 | #define ADC_CTRL 37 // Heltec V3 needs ADC_CTRL = LOW powers the voltage divider to read BatteryPin
33 |
34 | #define BOARD_I2C_SDA 41
35 | #define BOARD_I2C_SCL 42
36 |
37 | #endif
--------------------------------------------------------------------------------
/variants/heltec_wifi_lora_32_v3_TNC/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:heltec_wifi_lora_32_v3_TNC]
2 | extends = env:esp32
3 | board = heltec_wifi_lora_32_V3
4 | board_build.mcu = esp32s3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D HELTEC_V3_TNC
9 | lib_deps =
10 | ${common.lib_deps}
11 | ${common.display_libs}
--------------------------------------------------------------------------------
/variants/heltec_wireless_stick_lite_v3_GPS_display/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 9
7 | #define RADIO_MISO_PIN 11
8 | #define RADIO_MOSI_PIN 10
9 | #define RADIO_CS_PIN 8
10 | #define RADIO_RST_PIN 12
11 | #define RADIO_DIO1_PIN 14
12 | #define RADIO_BUSY_PIN 13
13 |
14 | // Display
15 | #undef OLED_SDA
16 | #undef OLED_SCL
17 | #undef OLED_RST
18 |
19 | #define OLED_SDA 17
20 | #define OLED_SCL 18
21 | #define OLED_RST -1
22 |
23 | // GPS
24 | #define GPS_RX 47
25 | #define GPS_TX 48
26 |
27 | // OTHER
28 | #define BUTTON_PIN 0
29 | #define BATTERY_PIN 1
30 | #define VEXT_CTRL 36
31 | #define ADC_CTRL 37 // Heltec V3 needs ADC_CTRL = LOW powers the voltage divider to read BatteryPin
32 |
33 | #define BOARD_I2C_SDA 41
34 | #define BOARD_I2C_SCL 42
35 |
36 | #endif
--------------------------------------------------------------------------------
/variants/heltec_wireless_stick_lite_v3_GPS_display/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:heltec_wireless_stick_lite_v3_GPS_display]
2 | extends = env:esp32
3 | board = esp32-s3-devkitc-1
4 | board_build.mcu = esp32s3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D HELTEC_WSL_V3_GPS_DISPLAY
9 | lib_deps =
10 | ${common.lib_deps}
--------------------------------------------------------------------------------
/variants/heltec_wireless_tracker/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 9
7 | #define RADIO_MISO_PIN 11
8 | #define RADIO_MOSI_PIN 10
9 | #define RADIO_CS_PIN 8
10 | #define RADIO_RST_PIN 12
11 | #define RADIO_DIO1_PIN 14
12 | #define RADIO_BUSY_PIN 13
13 | #define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
14 | #define WAKEUP_RADIO GPIO_SEL_14
15 |
16 | // Display
17 | #undef OLED_SDA
18 | #undef OLED_SCL
19 | #undef OLED_RST
20 |
21 | #define HAS_TFT
22 | #define BOARD_BL_PIN 21
23 |
24 | // GPS
25 | #define HAS_GPS_CTRL
26 | #define GPS_RX 34
27 | #define GPS_TX 33
28 | #define GPS_PPS 36
29 | #define GPS_RESET 35
30 | #define GPS_BAUDRATE 115200
31 |
32 | // OTHER
33 | #define BUTTON_PIN 0
34 | #define WAKEUP_BUTTON GPIO_NUM_0
35 | #define BATTERY_PIN 1
36 | #define ADC_CTRL 2 // HELTEC Wireless Tracker ADC_CTRL = HIGH powers the voltage divider to read BatteryPin. Only on V05 = V1.1
37 | #define VEXT_CTRL 3 // To turn on GPS and TFT
38 |
39 | #define BOARD_I2C_SDA 7
40 | #define BOARD_I2C_SCL 6
41 |
42 | #endif
--------------------------------------------------------------------------------
/variants/heltec_wireless_tracker/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:heltec_wireless_tracker]
2 | extends = env:esp32
3 | board = esp32-s3-devkitc-1
4 | board_build.mcu = esp32s3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D HELTEC_WIRELESS_TRACKER
9 | -D USER_SETUP_LOADED
10 | -D TFT_WIDTH=80
11 | -D TFT_HEIGHT=160
12 | -D ST7735_DRIVER
13 | -D ST7735_GREENTAB160x80
14 | -D TFT_RGB_ORDER=TFT_BGR
15 | -D TFT_MOSI=42
16 | -D TFT_SCLK=41
17 | -D TFT_CS=38
18 | -D TFT_DC=40
19 | -D TFT_RST=39
20 | -D TFT_BL=21
21 | -D TFT_BACKLIGHT_ON=1
22 | -D TOUCH_CS=-1
23 | -D LOAD_GLCD
24 | -D LOAD_FONT2
25 | -D LOAD_FONT4
26 | -D LOAD_FONT6
27 | -D LOAD_FONT7
28 | -D LOAD_FONT8
29 | -D SPI_FREQUENCY=27000000
30 | -D USE_HSPI_PORT
31 | lib_deps =
32 | ${common.lib_deps}
33 | bodmer/TFT_eSPI @ 2.5.43
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v0_7/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define GPS_RX 15
24 | #define GPS_TX 12
25 |
26 | // OTHER
27 | #define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
28 | #define BATTERY_PIN 35
29 |
30 | #define HAS_BT_CLASSIC
31 |
32 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v0_7/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-beam-v0_7]
2 | extends = env:esp32
3 | board = ttgo-t-beam
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_Beam_V0_7
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define HAS_GPS_CTRL
24 | #define GPS_RX 12
25 | #define GPS_TX 34
26 |
27 | // OTHER
28 | #define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
29 |
30 | #define HAS_AXP192
31 | #define HAS_BT_CLASSIC
32 |
33 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-beam-v1]
2 | extends = env:esp32
3 | board = ttgo-t-beam
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_Beam_V1_0
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | lewisxhe/XPowersLib @ 0.2.4
11 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1_2/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define HAS_GPS_CTRL
24 | #define GPS_RX 12
25 | #define GPS_TX 34
26 |
27 | // OTHER
28 | #define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
29 |
30 | #define HAS_AXP2101
31 | #define HAS_BT_CLASSIC
32 |
33 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1_2/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-beam-v1_2]
2 | extends = env:esp32
3 | board = ttgo-t-beam
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_Beam_V1_2
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | lewisxhe/XPowersLib @ 0.2.4
11 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1_2_915/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1276
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define HAS_GPS_CTRL
24 | #define GPS_RX 12
25 | #define GPS_TX 34
26 |
27 | // OTHER
28 | #define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
29 |
30 | #define HAS_AXP2101
31 | #define HAS_BT_CLASSIC
32 |
33 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1_2_915/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-beam-v1_2_915]
2 | extends = env:esp32
3 | board = ttgo-t-beam
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_Beam_V1_2_915
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | lewisxhe/XPowersLib @ 0.2.4
11 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1_2_SX1262/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_DIO0_PIN 26
11 | #define RADIO_RST_PIN 23
12 | #define RADIO_DIO1_PIN 33
13 | #define RADIO_BUSY_PIN 32
14 |
15 | // Display
16 | #undef OLED_SDA
17 | #undef OLED_SCL
18 | #undef OLED_RST
19 |
20 | #define OLED_SDA 21
21 | #define OLED_SCL 22
22 | #define OLED_RST 16
23 |
24 | // GPS
25 | #define HAS_GPS_CTRL
26 | #define GPS_RX 12
27 | #define GPS_TX 34
28 |
29 | // OTHER
30 | #define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
31 |
32 | #define HAS_AXP2101
33 | #define HAS_BT_CLASSIC
34 |
35 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1_2_SX1262/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-beam-v1_2_SX1262]
2 | extends = env:esp32
3 | board = ttgo-t-beam
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_Beam_V1_2_SX1262
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | lewisxhe/XPowersLib @ 0.2.4
11 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1_915/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1276
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define HAS_GPS_CTRL
24 | #define GPS_RX 12
25 | #define GPS_TX 34
26 |
27 | // OTHER
28 | #define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
29 |
30 | #define HAS_AXP192
31 | #define HAS_BT_CLASSIC
32 |
33 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1_915/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-beam-v1_915]
2 | extends = env:esp32
3 | board = ttgo-t-beam
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_Beam_V1_0_915
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | lewisxhe/XPowersLib @ 0.2.4
11 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1_SX1268/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1268
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_DIO0_PIN 26
11 | #define RADIO_RST_PIN 23
12 | #define RADIO_DIO1_PIN 33
13 | #define RADIO_BUSY_PIN 32
14 |
15 | // Display
16 | #undef OLED_SDA
17 | #undef OLED_SCL
18 | #undef OLED_RST
19 |
20 | #define OLED_SDA 21
21 | #define OLED_SCL 22
22 | #define OLED_RST 16
23 |
24 | // GPS
25 | #define HAS_GPS_CTRL
26 | #define GPS_RX 12
27 | #define GPS_TX 34
28 |
29 | // OTHER
30 | #define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
31 |
32 | #define HAS_AXP192
33 | #define HAS_BT_CLASSIC
34 |
35 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-beam-v1_SX1268/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-beam-v1_SX1268]
2 | extends = env:esp32
3 | board = ttgo-t-beam
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_Beam_V1_0_SX1268
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | lewisxhe/XPowersLib @ 0.2.4
11 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo-t-lora32-v2_1_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define GPS_RX 12
24 | #define GPS_TX 34
25 |
26 | // OTHER
27 | #define BUTTON_PIN 15
28 | #define BATTERY_PIN 35
29 |
30 | #define HAS_BT_CLASSIC
31 |
32 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-lora32-v2_1_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-lora32-v2_1_GPS]
2 | extends = env:esp32
3 | board = ttgo-lora32-v21
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_LORA32_V2_1_GPS
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo-t-lora32-v2_1_GPS_915/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1276
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define GPS_RX 12
24 | #define GPS_TX 34
25 |
26 | // OTHER
27 | #define BUTTON_PIN 15
28 | #define BATTERY_PIN 35
29 |
30 | #define HAS_BT_CLASSIC
31 |
32 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-lora32-v2_1_GPS_915/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-lora32-v2_1_GPS_915]
2 | extends = env:esp32
3 | board = ttgo-lora32-v21
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_LORA32_V2_1_GPS_915
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo-t-lora32-v2_1_TNC/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1278
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define HAS_NO_GPS
24 | #define GPS_RX -1
25 | #define GPS_TX -1
26 |
27 | // OTHER
28 | #define BUTTON_PIN 15
29 | #define BATTERY_PIN 35
30 |
31 | #define HAS_BT_CLASSIC
32 |
33 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-lora32-v2_1_TNC/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-lora32-v2_1_TNC]
2 | extends = env:esp32
3 | board = ttgo-lora32-v21
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_LORA32_V2_1_TNC_915
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo-t-lora32-v2_1_TNC_915/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1276
6 | #define RADIO_SCLK_PIN 5
7 | #define RADIO_MISO_PIN 19
8 | #define RADIO_MOSI_PIN 27
9 | #define RADIO_CS_PIN 18
10 | #define RADIO_RST_PIN 23
11 | #define RADIO_BUSY_PIN 26
12 |
13 | // Display
14 | #undef OLED_SDA
15 | #undef OLED_SCL
16 | #undef OLED_RST
17 |
18 | #define OLED_SDA 21
19 | #define OLED_SCL 22
20 | #define OLED_RST 16
21 |
22 | // GPS
23 | #define HAS_NO_GPS
24 | #define GPS_RX -1
25 | #define GPS_TX -1
26 |
27 | // OTHER
28 | #define BUTTON_PIN 15
29 | #define BATTERY_PIN 35
30 |
31 | #define HAS_BT_CLASSIC
32 |
33 | #endif
--------------------------------------------------------------------------------
/variants/ttgo-t-lora32-v2_1_TNC_915/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo-t-lora32-v2_1_TNC_915]
2 | extends = env:esp32
3 | board = ttgo-lora32-v21
4 | build_flags =
5 | ${common.build_flags}
6 | -D TTGO_T_LORA32_V2_1_TNC_915
7 | lib_deps =
8 | ${common.lib_deps}
9 | ${common.display_libs}
10 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo_t_beam_s3_SUPREME_v3/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 12
7 | #define RADIO_MISO_PIN 13
8 | #define RADIO_MOSI_PIN 11
9 | #define RADIO_CS_PIN 10
10 | #define RADIO_DIO0_PIN -1
11 | #define RADIO_RST_PIN 5
12 | #define RADIO_DIO1_PIN 1
13 | #define RADIO_BUSY_PIN 4
14 |
15 | // Display
16 | #undef OLED_SDA
17 | #undef OLED_SCL
18 | #undef OLED_RST
19 |
20 | #define OLED_SDA 17
21 | #define OLED_SCL 18
22 | #define OLED_RST 16
23 |
24 | // GPS
25 | #define HAS_GPS_CTRL
26 | #define GPS_RX 8
27 | #define GPS_TX 9
28 |
29 | // OTHER
30 | #define BUTTON_PIN 0
31 |
32 | #define HAS_AXP2101
33 | #define BOARD_HAS_PSRAM
34 |
35 | #endif
--------------------------------------------------------------------------------
/variants/ttgo_t_beam_s3_SUPREME_v3/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo_t_beam_s3_SUPREME_v3]
2 | extends = env:esp32
3 | board = esp32-s3-devkitc-1
4 | board_build.mcu = esp32s3
5 | build_flags =
6 | ${common.build_flags}
7 | ${common.usb_flags}
8 | -D TTGO_T_Beam_S3_SUPREME_V3
9 | lib_deps =
10 | ${common.lib_deps}
11 | ${common.display_libs}
12 | lewisxhe/XPowersLib @ 0.2.4
13 | adafruit/Adafruit SH110X @ 2.1.10
--------------------------------------------------------------------------------
/variants/ttgo_t_deck_GPS/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 40
7 | #define RADIO_MISO_PIN 38
8 | #define RADIO_MOSI_PIN 41
9 | #define RADIO_CS_PIN 9
10 | #define RADIO_RST_PIN 17
11 | #define RADIO_DIO1_PIN 45
12 | #define RADIO_BUSY_PIN 13
13 |
14 | // Display
15 | #undef OLED_SDA
16 | #undef OLED_SCL
17 | #undef OLED_RST
18 |
19 | #define HAS_TFT
20 |
21 | // GPS
22 | #define GPS_RX 43
23 | #define GPS_TX 44
24 |
25 | // OTHER
26 | #define BATTERY_PIN 4
27 |
28 | #define BOARD_POWERON 10
29 | #define BOARD_SDCARD_CS 39
30 | #define BOARD_BL_PIN 42
31 |
32 | #define BOARD_I2C_SDA 18
33 | #define BOARD_I2C_SCL 8
34 |
35 | // JOYSTICK
36 | #define HAS_JOYSTICK
37 | #define JOYSTICK_CENTER 0
38 | #define BUTTON_PIN JOYSTICK_CENTER
39 | #define JOYSTICK_UP 3 // G S1
40 | #define JOYSTICK_DOWN 15 // G S3
41 | #define JOYSTICK_LEFT 1 // G S4
42 | #define JOYSTICK_RIGHT 2 // G S2
43 |
44 | #define HAS_TOUCHSCREEN
45 | #define HAS_I2S
46 | #define DAC_I2S_WS 5
47 | #define DAC_I2S_DOUT 6
48 | #define DAC_I2S_BCK 7
49 | #define SPK_I2S_PORT I2S_NUM_0
50 | #define MIC_I2S_SAMPLE_RATE 16000
51 | #define MIC_I2S_PORT I2S_NUM_1
52 |
53 | #endif
--------------------------------------------------------------------------------
/variants/ttgo_t_deck_GPS/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo_t_deck_GPS]
2 | extends = env
3 | platform = espressif32 @ 6.3.1
4 | board_build.partitions = huge_app.csv
5 | monitor_filters = esp32_exception_decoder
6 | board = esp32-s3-devkitc-1
7 | board_build.mcu = esp32s3
8 | board_build.embed_files =
9 | data_embed/index.html.gz
10 | data_embed/style.css.gz
11 | data_embed/script.js.gz
12 | data_embed/bootstrap.css.gz
13 | data_embed/bootstrap.js.gz
14 | data_embed/favicon.png.gz
15 | extra_scripts =
16 | pre:tools/compress.py
17 | debug_tool = esp-prog
18 | build_flags =
19 | ${common.build_flags}
20 | ${common.usb_flags}
21 | -D TTGO_T_DECK_GPS
22 | -D BOARD_HAS_PSRAM
23 | -D USER_SETUP_LOADED
24 | -D ST7789_DRIVER
25 | -D TFT_WIDTH=240
26 | -D TFT_HEIGHT=320
27 | -D TFT_RGB_ORDER=TFT_BGR
28 | -D TFT_INVERSION_ON
29 | -D TFT_MISO=38
30 | -D TFT_MOSI=41
31 | -D TFT_SCLK=40
32 | -D TFT_CS=12
33 | -D TFT_DC=11
34 | -D TFT_RST=-1
35 | -D TFT_BUSY=-1
36 | -D TFT_BL=42
37 | -D TFT_BACKLIGHT_ON=1
38 | -D TOUCH_CS=-1
39 | -D LOAD_GLCD
40 | -D LOAD_FONT2
41 | -D LOAD_FONT4
42 | -D LOAD_FONT6
43 | -D LOAD_FONT7
44 | -D LOAD_FONT8
45 | -D SPI_FREQUENCY=40000000
46 | -D SPI_READ_FREQUENCY=16000000
47 | lib_deps =
48 | ${common.lib_deps}
49 | bodmer/TFT_eSPI @ 2.5.43
50 | https://github.com/mmMicky/TouchLib.git
--------------------------------------------------------------------------------
/variants/ttgo_t_deck_plus/board_pinout.h:
--------------------------------------------------------------------------------
1 | #ifndef BOARD_PINOUT_H_
2 | #define BOARD_PINOUT_H_
3 |
4 | // LoRa Radio
5 | #define HAS_SX1262
6 | #define RADIO_SCLK_PIN 40
7 | #define RADIO_MISO_PIN 38
8 | #define RADIO_MOSI_PIN 41
9 | #define RADIO_CS_PIN 9
10 | #define RADIO_RST_PIN 17
11 | #define RADIO_DIO1_PIN 45
12 | #define RADIO_BUSY_PIN 13
13 |
14 | // Display
15 | #undef OLED_SDA
16 | #undef OLED_SCL
17 | #undef OLED_RST
18 |
19 | #define HAS_TFT
20 |
21 | // GPS
22 | #define GPS_RX 43
23 | #define GPS_TX 44
24 | #define GPS_BAUDRATE 38400
25 |
26 | // OTHER
27 | #define BATTERY_PIN 4
28 |
29 | #define BOARD_POWERON 10
30 | #define BOARD_SDCARD_CS 39
31 | #define BOARD_BL_PIN 42
32 |
33 | #define BOARD_I2C_SDA 18
34 | #define BOARD_I2C_SCL 8
35 |
36 | // JOYSTICK
37 | #define HAS_JOYSTICK
38 | #define JOYSTICK_CENTER 0
39 | #define BUTTON_PIN JOYSTICK_CENTER
40 | #define JOYSTICK_UP 3 // G S1
41 | #define JOYSTICK_DOWN 15 // G S3
42 | #define JOYSTICK_LEFT 1 // G S4
43 | #define JOYSTICK_RIGHT 2 // G S2
44 |
45 | #define HAS_TOUCHSCREEN
46 | #define HAS_I2S
47 | #define DAC_I2S_WS 5
48 | #define DAC_I2S_DOUT 6
49 | #define DAC_I2S_BCK 7
50 | #define SPK_I2S_PORT I2S_NUM_0
51 | #define MIC_I2S_SAMPLE_RATE 16000
52 | #define MIC_I2S_PORT I2S_NUM_1
53 |
54 | #endif
--------------------------------------------------------------------------------
/variants/ttgo_t_deck_plus/platformio.ini:
--------------------------------------------------------------------------------
1 | [env:ttgo_t_deck_plus]
2 | extends = env
3 | platform = espressif32 @ 6.3.1
4 | board_build.partitions = huge_app.csv
5 | monitor_filters = esp32_exception_decoder
6 | board = esp32-s3-devkitc-1
7 | board_build.mcu = esp32s3
8 | board_build.embed_files =
9 | data_embed/index.html.gz
10 | data_embed/style.css.gz
11 | data_embed/script.js.gz
12 | data_embed/bootstrap.css.gz
13 | data_embed/bootstrap.js.gz
14 | data_embed/favicon.png.gz
15 | extra_scripts =
16 | pre:tools/compress.py
17 | debug_tool = esp-prog
18 | build_flags =
19 | ${common.build_flags}
20 | ${common.usb_flags}
21 | -D TTGO_T_DECK_PLUS
22 | -D BOARD_HAS_PSRAM
23 | -D USER_SETUP_LOADED
24 | -D ST7789_DRIVER
25 | -D TFT_WIDTH=240
26 | -D TFT_HEIGHT=320
27 | -D TFT_RGB_ORDER=TFT_BGR
28 | -D TFT_INVERSION_ON
29 | -D TFT_MISO=38
30 | -D TFT_MOSI=41
31 | -D TFT_SCLK=40
32 | -D TFT_CS=12
33 | -D TFT_DC=11
34 | -D TFT_RST=-1
35 | -D TFT_BUSY=-1
36 | -D TFT_BL=42
37 | -D TFT_BACKLIGHT_ON=1
38 | -D TOUCH_CS=-1
39 | -D LOAD_GLCD
40 | -D LOAD_FONT2
41 | -D LOAD_FONT4
42 | -D LOAD_FONT6
43 | -D LOAD_FONT7
44 | -D LOAD_FONT8
45 | -D SPI_FREQUENCY=40000000
46 | -D SPI_READ_FREQUENCY=16000000
47 | lib_deps =
48 | ${common.lib_deps}
49 | bodmer/TFT_eSPI @ 2.5.43
50 | https://github.com/mmMicky/TouchLib.git
--------------------------------------------------------------------------------