Porównaj commity

...

13 Commity

Autor SHA1 Wiadomość Data
sh123 c09422dab9 Merge remote-tracking branch 'refs/remotes/origin/master' 2025-04-11 14:39:00 +03:00
sh123 f0d7caa6f2 Documentation, small refactoring 2025-04-11 14:38:34 +03:00
sh123 12c194b919
Update README.md 2024-12-27 21:50:26 +02:00
sh123 f48def5cab Add missing files 2024-11-03 18:53:17 +02:00
sh123 5ca3bf0e9e Updated schematics project 2024-10-30 14:32:46 +02:00
sh123 8a6427f088 Fix issue with RadioLib API changes 2023-12-01 16:37:01 +02:00
sh123 e78e0e8513 Serial tx delay update 2023-11-17 15:49:48 +02:00
sh123 cf99eb014d Avoid switching to rx on each packet 2023-11-17 14:25:06 +02:00
sh123 b89a13680e Handle control data escape 2023-11-17 14:25:06 +02:00
sh123 0a43429b1c Convert to khz 2023-11-17 14:25:06 +02:00
sh123 2083f946d9 Update SetHardware command 2023-11-17 14:25:06 +02:00
sh123 3e90abd47f
Update README.md 2023-11-16 17:17:21 +02:00
sh123 127ccbe072 Add support for FSK modulation 2023-11-16 17:15:52 +02:00
19 zmienionych plików z 22019 dodań i 4168 usunięć

1
.gitignore vendored
Wyświetl plik

@ -4,4 +4,3 @@
*.sch-bak *.sch-bak
*.kicad_pcb-bak *.kicad_pcb-bak
fp-info-cache fp-info-cache
*-cache.lib

Wyświetl plik

@ -1,7 +1,7 @@
# ESP32 LoRa APRS Modem # ESP32 LoRa APRS Modem
![Modes of operation](extras/images/diagram.png) ![Modes of operation](extras/images/diagram.png)
This project is amateur radio ESP32 based LoRa **KISS Bluetooth/BLE/USB/TCPIP** modem + LoRa **APRS-IS RX/TX iGate** server over WiFI + LoRa **APRS digipeater** + **Codec2 DV modem** (with Codec2 Talkie Android application). This project is amateur radio ESP32 based LoRa/FSK **KISS Bluetooth/BLE/USB/TCPIP** modem + LoRa **APRS-IS RX/TX iGate** server over WiFI + LoRa/FSK **APRS digipeater** + **Codec2 DV modem** (with Codec2 Talkie Android application).
⚠ **To configure sketch modify default parameters in config.h file.** ⚠ **To configure sketch modify default parameters in config.h file.**

Wyświetl plik

@ -4,7 +4,7 @@
- `antenna_base` - base for rubber duck antenna, to be printed with PETG filament. - `antenna_base` - base for rubber duck antenna, to be printed with PETG filament.
- `antenna_cover` - cover for rubber duck antenna, to printed with TPU filament. - `antenna_cover` - cover for rubber duck antenna, to printed with TPU filament.
👉 Rubber duck antenna spiral widing was done with 1.3mm copper wire on 8mm aluminium scaffolding tube. 👉 Rubber duck antenna spiral widing was done with 1.3mm copper wire on 8mm aluminium scaffolding tube, ~8 turns with 6mm step
**Tracker case**: **Tracker case**:
- `aprs_tracker_e22_base` - base for tracker case without battery compartment. - `aprs_tracker_e22_base` - base for tracker case without battery compartment.

Wyświetl plik

@ -0,0 +1,352 @@
EESchema-LIBRARY Version 2.4
#encoding utf-8
#
# Connector_Conn_01x03_Female
#
DEF Connector_Conn_01x03_Female J 0 40 Y N 1 F N
F0 "J" 0 200 50 H V C CNN
F1 "Connector_Conn_01x03_Female" 0 -200 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Connector*:*_1x??_*
$ENDFPLIST
DRAW
A 0 -100 20 901 -901 1 1 6 N 0 -80 0 -120
A 0 0 20 901 -901 1 1 6 N 0 20 0 -20
A 0 100 20 901 -901 1 1 6 N 0 120 0 80
P 2 1 1 6 -50 -100 -20 -100 N
P 2 1 1 6 -50 0 -20 0 N
P 2 1 1 6 -50 100 -20 100 N
X Pin_1 1 -200 100 150 R 50 50 1 1 P
X Pin_2 2 -200 0 150 R 50 50 1 1 P
X Pin_3 3 -200 -100 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Connector_Conn_01x10_Female
#
DEF Connector_Conn_01x10_Female J 0 40 Y N 1 F N
F0 "J" 0 500 50 H V C CNN
F1 "Connector_Conn_01x10_Female" 0 -600 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Connector*:*_1x??_*
$ENDFPLIST
DRAW
A 0 -500 20 901 -901 1 1 6 N 0 -480 0 -520
A 0 -400 20 901 -901 1 1 6 N 0 -380 0 -420
A 0 -300 20 901 -901 1 1 6 N 0 -280 0 -320
A 0 -200 20 901 -901 1 1 6 N 0 -180 0 -220
A 0 -100 20 901 -901 1 1 6 N 0 -80 0 -120
A 0 0 20 901 -901 1 1 6 N 0 20 0 -20
A 0 100 20 901 -901 1 1 6 N 0 120 0 80
A 0 200 20 901 -901 1 1 6 N 0 220 0 180
A 0 300 20 901 -901 1 1 6 N 0 320 0 280
A 0 400 20 901 -901 1 1 6 N 0 420 0 380
P 2 1 1 6 -50 -500 -20 -500 N
P 2 1 1 6 -50 -400 -20 -400 N
P 2 1 1 6 -50 -300 -20 -300 N
P 2 1 1 6 -50 -200 -20 -200 N
P 2 1 1 6 -50 -100 -20 -100 N
P 2 1 1 6 -50 0 -20 0 N
P 2 1 1 6 -50 100 -20 100 N
P 2 1 1 6 -50 200 -20 200 N
P 2 1 1 6 -50 300 -20 300 N
P 2 1 1 6 -50 400 -20 400 N
X Pin_1 1 -200 400 150 R 50 50 1 1 P
X Pin_10 10 -200 -500 150 R 50 50 1 1 P
X Pin_2 2 -200 300 150 R 50 50 1 1 P
X Pin_3 3 -200 200 150 R 50 50 1 1 P
X Pin_4 4 -200 100 150 R 50 50 1 1 P
X Pin_5 5 -200 0 150 R 50 50 1 1 P
X Pin_6 6 -200 -100 150 R 50 50 1 1 P
X Pin_7 7 -200 -200 150 R 50 50 1 1 P
X Pin_8 8 -200 -300 150 R 50 50 1 1 P
X Pin_9 9 -200 -400 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Connector_Conn_01x12_Female
#
DEF Connector_Conn_01x12_Female J 0 40 Y N 1 F N
F0 "J" 0 600 50 H V C CNN
F1 "Connector_Conn_01x12_Female" 0 -700 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Connector*:*_1x??_*
$ENDFPLIST
DRAW
A 0 -600 20 901 -901 1 1 6 N 0 -580 0 -620
A 0 -500 20 901 -901 1 1 6 N 0 -480 0 -520
A 0 -400 20 901 -901 1 1 6 N 0 -380 0 -420
A 0 -300 20 901 -901 1 1 6 N 0 -280 0 -320
A 0 -200 20 901 -901 1 1 6 N 0 -180 0 -220
A 0 -100 20 901 -901 1 1 6 N 0 -80 0 -120
A 0 0 20 901 -901 1 1 6 N 0 20 0 -20
A 0 100 20 901 -901 1 1 6 N 0 120 0 80
A 0 200 20 901 -901 1 1 6 N 0 220 0 180
A 0 300 20 901 -901 1 1 6 N 0 320 0 280
A 0 400 20 901 -901 1 1 6 N 0 420 0 380
A 0 500 20 901 -901 1 1 6 N 0 520 0 480
P 2 1 1 6 -50 -600 -20 -600 N
P 2 1 1 6 -50 -500 -20 -500 N
P 2 1 1 6 -50 -400 -20 -400 N
P 2 1 1 6 -50 -300 -20 -300 N
P 2 1 1 6 -50 -200 -20 -200 N
P 2 1 1 6 -50 -100 -20 -100 N
P 2 1 1 6 -50 0 -20 0 N
P 2 1 1 6 -50 100 -20 100 N
P 2 1 1 6 -50 200 -20 200 N
P 2 1 1 6 -50 300 -20 300 N
P 2 1 1 6 -50 400 -20 400 N
P 2 1 1 6 -50 500 -20 500 N
X Pin_1 1 -200 500 150 R 50 50 1 1 P
X Pin_10 10 -200 -400 150 R 50 50 1 1 P
X Pin_11 11 -200 -500 150 R 50 50 1 1 P
X Pin_12 12 -200 -600 150 R 50 50 1 1 P
X Pin_2 2 -200 400 150 R 50 50 1 1 P
X Pin_3 3 -200 300 150 R 50 50 1 1 P
X Pin_4 4 -200 200 150 R 50 50 1 1 P
X Pin_5 5 -200 100 150 R 50 50 1 1 P
X Pin_6 6 -200 0 150 R 50 50 1 1 P
X Pin_7 7 -200 -100 150 R 50 50 1 1 P
X Pin_8 8 -200 -200 150 R 50 50 1 1 P
X Pin_9 9 -200 -300 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Connector_Conn_Coaxial
#
DEF Connector_Conn_Coaxial J 0 40 Y N 1 F N
F0 "J" 10 120 50 H V C CNN
F1 "Connector_Conn_Coaxial" 115 0 50 V V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
*BNC*
*SMA*
*SMB*
*SMC*
*Cinch*
$ENDFPLIST
DRAW
A -2 0 71 1636 0 0 1 10 N -70 20 70 0
A -1 0 71 0 -1638 0 1 10 N 70 0 -70 -20
C 0 0 20 0 1 8 N
P 2 0 1 0 -100 0 -20 0 N
P 2 0 1 0 0 -100 0 -70 N
X In 1 -200 0 100 R 50 50 1 1 P
X Ext 2 0 -200 100 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Device_C
#
DEF Device_C C 0 10 N Y 1 F N
F0 "C" 25 100 50 H V L CNN
F1 "Device_C" 25 -100 50 H V L CNN
F2 "" 38 -150 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
C_*
$ENDFPLIST
DRAW
P 2 0 1 20 -80 -30 80 -30 N
P 2 0 1 20 -80 30 80 30 N
X ~ 1 0 150 110 D 50 50 1 1 P
X ~ 2 0 -150 110 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Device_CP1
#
DEF Device_CP1 C 0 10 N N 1 F N
F0 "C" 25 100 50 H V L CNN
F1 "Device_CP1" 25 -100 50 H V L CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
CP_*
$ENDFPLIST
DRAW
A 0 -150 128 1287 513 0 1 20 N -80 -50 80 -50
P 2 0 1 20 -80 30 80 30 N
P 2 0 1 0 -70 90 -30 90 N
P 2 0 1 0 -50 70 -50 110 N
X ~ 1 0 150 110 D 50 50 1 1 P
X ~ 2 0 -150 130 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Jumper_SolderJumper_2_Open
#
DEF Jumper_SolderJumper_2_Open JP 0 0 Y N 1 F N
F0 "JP" 0 80 50 H V C CNN
F1 "Jumper_SolderJumper_2_Open" 0 -100 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
SolderJumper*Open*
$ENDFPLIST
DRAW
A -10 0 40 901 -901 0 1 0 N -10 40 -10 -40
A -10 0 40 901 -901 0 1 0 F -10 40 -10 -40
A 10 0 40 -899 899 0 1 0 N 10 -40 10 40
A 10 0 40 -899 899 0 1 0 F 10 -40 10 40
P 2 0 1 0 -10 40 -10 -40 N
P 2 0 1 0 10 40 10 -40 N
X A 1 -150 0 100 R 50 50 1 1 P
X B 2 150 0 100 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Jumper_SolderJumper_3_Open
#
DEF Jumper_SolderJumper_3_Open JP 0 0 Y N 1 F N
F0 "JP" -100 -100 50 H V C CNN
F1 "Jumper_SolderJumper_3_Open" 0 110 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
SolderJumper*Open*
$ENDFPLIST
DRAW
A -40 0 40 901 -901 0 1 0 N -40 40 -40 -40
A -40 0 40 901 -901 0 1 0 F -40 40 -40 -40
A 40 0 40 -899 899 0 1 0 N 40 -40 40 40
A 40 0 40 -899 899 0 1 0 F 40 -40 40 40
S -20 40 20 -40 0 1 0 F
P 2 0 1 0 -100 0 -80 0 N
P 2 0 1 0 -40 40 -40 -40 N
P 2 0 1 0 0 -50 0 -40 N
P 2 0 1 0 40 40 40 -40 N
P 2 0 1 0 100 0 80 0 N
X A 1 -200 0 100 R 50 50 1 1 P
X C 2 0 -150 100 U 50 50 1 1 I
X B 3 200 0 100 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
# RF_Module_Ai-Thinker-Ra-01
#
DEF RF_Module_Ai-Thinker-Ra-01 U 0 40 Y Y 1 F N
F0 "U" 100 700 50 H V C CNN
F1 "RF_Module_Ai-Thinker-Ra-01" 400 -550 50 H V C CNN
F2 "RF_Module:Ai-Thinker-Ra-01-LoRa" 1000 -400 50 H I C CNN
F3 "" 100 700 50 H I C CNN
$FPLIST
Ai?Thinker?Ra?01*
$ENDFPLIST
DRAW
S -300 600 300 -500 0 1 10 f
X Ant 1 -500 500 200 R 50 50 1 1 I
X DIO4 10 500 0 200 L 50 50 1 1 B
X DIO5 11 500 -100 200 L 50 50 1 1 B
X SCK 12 -500 0 200 R 50 50 1 1 B
X MISO 13 -500 -100 200 R 50 50 1 1 O
X MOSI 14 -500 -200 200 R 50 50 1 1 I
X ~SS 15 -500 100 200 R 50 50 1 1 I
X Gnd 16 0 -700 200 U 50 50 1 1 P N
X Gnd 2 0 -700 200 U 50 50 1 1 W
X 3v3 3 0 800 200 D 50 50 1 1 W
X ~Reset 4 -500 300 200 R 50 50 1 1 I
X DIO0 5 500 400 200 L 50 50 1 1 B
X DIO1 6 500 300 200 L 50 50 1 1 B
X DIO2 7 500 200 200 L 50 50 1 1 B
X DIO3 8 500 100 200 L 50 50 1 1 B
X Gnd 9 0 -700 200 U 50 50 1 1 P N
ENDDRAW
ENDDEF
#
# lora_tracker_E22-400M30S
#
DEF lora_tracker_E22-400M30S U 0 40 Y Y 1 L N
F0 "U" -800 1300 85 H V L BNN
F1 "lora_tracker_E22-400M30S" 0 0 50 H I C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
T 0 0 500 85 0 1 0 E22-400M30S Normal 0 C C
P 2 1 0 0 -800 -1200 800 -1200 N
P 2 1 0 0 -800 1200 -800 -1200 N
P 2 1 0 0 800 -1200 800 1200 N
P 2 1 0 0 800 1200 -800 1200 N
X GND@1 1 -1000 1100 200 R 0 50 1 0 B
X VCC@2 10 -1000 -900 200 R 0 50 1 0 B
X GND@6 11 -1000 -1100 200 R 0 50 1 0 B
X GND@7 12 1000 -1100 200 L 0 50 1 0 B
X DIO1 13 1000 -900 200 L 0 50 1 0 B
X BUSY 14 1000 -700 200 L 0 50 1 0 B
X NRST 15 1000 -500 200 L 0 50 1 0 B
X MISO 16 1000 -300 200 L 0 50 1 0 B
X MOSI 17 1000 -100 200 L 0 50 1 0 B
X SCK 18 1000 100 200 L 0 50 1 0 B
X NSS 19 1000 300 200 L 0 50 1 0 B
X GND@2 2 -1000 900 200 R 0 50 1 0 B
X GND@8 20 1000 700 200 L 0 50 1 0 B
X ANT 21 1000 900 200 L 0 50 1 0 B
X GND@9 22 1000 1100 200 L 0 50 1 0 B
X GND@3 3 -1000 700 200 R 0 50 1 0 B
X GND@4 4 -1000 300 200 R 0 50 1 0 B
X GND@5 5 -1000 100 200 R 0 50 1 0 B
X RXEN 6 -1000 -100 200 R 0 50 1 0 B
X TXEN 7 -1000 -300 200 R 0 50 1 0 B
X DIO2 8 -1000 -500 200 R 0 50 1 0 B
X VCC@1 9 -1000 -700 200 R 0 50 1 0 B
ENDDRAW
ENDDEF
#
# lora_tracker_ESP32
#
DEF lora_tracker_ESP32 U 0 40 Y Y 1 F N
F0 "U" 50 150 50 H V C CNN
F1 "lora_tracker_ESP32" 50 50 50 H V C CNN
F2 "" 50 150 50 H I C CNN
F3 "" 50 150 50 H I C CNN
DRAW
S -300 0 450 -2000 0 1 0 N
X +3V3 1 -400 -100 100 R 50 50 1 1 I
X GPIO26 10 -400 -1000 100 R 50 50 1 1 I
X GPIO27 11 -400 -1100 100 R 50 50 1 1 I
X GPIO14 12 -400 -1200 100 R 50 50 1 1 I
X GPIO12 13 -400 -1300 100 R 50 50 1 1 I
X GND 14 -400 -1400 100 R 50 50 1 1 I
X GPIO13 15 -400 -1500 100 R 50 50 1 1 I
X GPIO9 16 -400 -1600 100 R 50 50 1 1 I
X GPIO10 17 -400 -1700 100 R 50 50 1 1 I
X GPIO11 18 -400 -1800 100 R 50 50 1 1 I
X VIN 19 -400 -1900 100 R 50 50 1 1 I
X EN 2 -400 -200 100 R 50 50 1 1 I
X GPIO6 20 550 -1900 100 L 50 50 1 1 I
X GPIO7 21 550 -1800 100 L 50 50 1 1 I
X GPIO8 22 550 -1700 100 L 50 50 1 1 I
X GPIO15 23 550 -1600 100 L 50 50 1 1 I
X GPIO2 24 550 -1500 100 L 50 50 1 1 I
X GPIO0 25 550 -1400 100 L 50 50 1 1 I
X GPIO4 26 550 -1300 100 L 50 50 1 1 I
X GPIO16 27 550 -1200 100 L 50 50 1 1 I
X GPIO17 28 550 -1100 100 L 50 50 1 1 I
X GPIO5 29 550 -1000 100 L 50 50 1 1 I
X GPIO36 3 -400 -300 100 R 50 50 1 1 I
X GPIO18 30 550 -900 100 L 50 50 1 1 I
X GPIO19 31 550 -800 100 L 50 50 1 1 I
X GND 32 550 -700 100 L 50 50 1 1 I
X GPIO21 33 550 -600 100 L 50 50 1 1 I
X GPIO3 34 550 -500 100 L 50 50 1 1 I
X GPIO1 35 550 -400 100 L 50 50 1 1 I
X GPIO22 36 550 -300 100 L 50 50 1 1 I
X GPIO23 37 550 -200 100 L 50 50 1 1 I
X GND 38 550 -100 100 L 50 50 1 1 I
X GPIO39 4 -400 -400 100 R 50 50 1 1 I
X GPIO34 5 -400 -500 100 R 50 50 1 1 I
X GPIO35 6 -400 -600 100 R 50 50 1 1 I
X GPIO32 7 -400 -700 100 R 50 50 1 1 I
X GPIO33 8 -400 -800 100 R 50 50 1 1 I
X GPIO25 9 -400 -900 100 R 50 50 1 1 I
ENDDRAW
ENDDEF
#
#End Library

Wyświetl plik

@ -0,0 +1,75 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "All Layers",
"auto_track_width": true,
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"ratsnest_display_mode": 0,
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": true,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36
],
"visible_layers": "fffffff_ffffffff",
"zone_display_mode": 0
},
"meta": {
"filename": "lora_tracker.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

Wyświetl plik

@ -0,0 +1,419 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.15,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.09999999999999999,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.15,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15,
"silk_text_upright": false,
"zones": {
"45_degree_only": false,
"min_clearance": 0.508
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"filename": "board_design_settings.json",
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"copper_edge_clearance": "error",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint_type_mismatch": "error",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zone_has_empty_net": "error",
"zones_intersect": "error"
},
"rules": {
"allow_blind_buried_vias": false,
"allow_microvias": false,
"max_error": 0.005,
"min_clearance": 0.0,
"min_copper_edge_clearance": 0.09999999999999999,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_silk_clearance": 0.0,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.19999999999999998,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"use_height_for_length_calcs": true
},
"track_widths": [],
"via_dimensions": [],
"zones_allow_external_fillets": false,
"zones_use_no_outline": true
},
"layer_presets": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "lora_tracker.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.25,
"pin_symbol_size": 0.0,
"text_offset_ratio": 0.08
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "Pcbnew",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"2d4f79a6-5cd6-46ec-8c40-a841159b019b",
""
]
],
"text_variables": {}
}

Wyświetl plik

@ -0,0 +1,75 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "All Layers",
"auto_track_width": true,
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"ratsnest_display_mode": 0,
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": true,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36
],
"visible_layers": "fffffff_ffffffff",
"zone_display_mode": 0
},
"meta": {
"filename": "lora_tracker_wide.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

Wyświetl plik

@ -0,0 +1,182 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.15,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.09999999999999999,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.15,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15,
"silk_text_upright": false,
"zones": {
"45_degree_only": false,
"min_clearance": 0.508
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"filename": "board_design_settings.json",
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"copper_edge_clearance": "error",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint_type_mismatch": "error",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zone_has_empty_net": "error",
"zones_intersect": "error"
},
"rule_severitieslegacy_courtyards_overlap": true,
"rule_severitieslegacy_no_courtyard_defined": false,
"rules": {
"allow_blind_buried_vias": false,
"allow_microvias": false,
"max_error": 0.005,
"min_clearance": 0.0,
"min_copper_edge_clearance": 0.09999999999999999,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_silk_clearance": 0.0,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.19999999999999998,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"use_height_for_length_calcs": true
},
"track_widths": [],
"via_dimensions": [],
"zones_allow_external_fillets": false,
"zones_use_no_outline": true
},
"layer_presets": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "lora_tracker_wide.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "lora_tracker_wide.net",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"drawing": {
"label_size_ratio": 0.25,
"pin_symbol_size": 0,
"text_offset_ratio": 0.08
},
"legacy_lib_dir": "",
"legacy_lib_list": []
},
"sheets": [],
"text_variables": {}
}

Wyświetl plik

@ -1,3 +1,4 @@
(sym_lib_table (sym_lib_table
(lib (name lora_tracker)(type Legacy)(uri ${KIPRJMOD}/lora_tracker.lib)(options "")(descr "")) (lib (name "lora_tracker")(type "Legacy")(uri "${KIPRJMOD}/lora_tracker.lib")(options "")(descr ""))
(lib (name "lora_tracker-rescue")(type "Legacy")(uri "${KIPRJMOD}/lora_tracker-rescue.lib")(options "")(descr ""))
) )

Wyświetl plik

@ -59,18 +59,30 @@
#define CFG_LORA_USE_CAD true // set to true to utilize carrier detection #define CFG_LORA_USE_CAD true // set to true to utilize carrier detection
#endif #endif
// LoRa protocol default parameters (they need to match between devices!!!) // modulation
#define CFG_MOD_TYPE_LORA 0
#define CFG_MOD_TYPE_FSK 1
#define CFG_MOD_TYPE CFG_MOD_TYPE_LORA
// general radio parameters
#define CFG_LORA_FREQ_RX 433.775e6 // RX frequency in MHz #define CFG_LORA_FREQ_RX 433.775e6 // RX frequency in MHz
#define CFG_LORA_FREQ_TX 433.775e6 // TX frequency in MHz #define CFG_LORA_FREQ_TX 433.775e6 // TX frequency in MHz
#define CFG_LORA_PWR 20 // output power in dBm
// LoRa protocol default parameters (they need to match between devices!!!)
#define CFG_LORA_BW 125e3 // bandwidth (from 7.8 kHz up to 500 kHz) #define CFG_LORA_BW 125e3 // bandwidth (from 7.8 kHz up to 500 kHz)
#define CFG_LORA_SF 12 // spreading factor (6 - 12), 6 requires implicit header mode #define CFG_LORA_SF 12 // spreading factor (6 - 12), 6 requires implicit header mode
#define CFG_LORA_CR 7 // coding rate (5 - 8) #define CFG_LORA_CR 7 // coding rate (5 - 8)
#define CFG_LORA_CRC 1 // 0 - disabled, 1 - 1 byte, 2 - 2 bytes #define CFG_LORA_CRC 1 // 0 - disabled, 1 - 1 byte, 2 - 2 bytes
#define CFG_LORA_EXPLICIT true // header mode, true - explicit, false - implicit #define CFG_LORA_EXPLICIT true // header mode, true - explicit, false - implicit
#define CFG_LORA_SYNC 0x12 // sync word (0x12 - private used by other trackers, 0x34 - public used by LoRaWAN) #define CFG_LORA_SYNC 0x12 // sync word (0x12 - private used by other trackers, 0x34 - public used by LoRaWAN)
#define CFG_LORA_PWR 20 // output power in dBm
#define CFG_LORA_PREAMBLE 8 // preamble length from 6 to 65535 #define CFG_LORA_PREAMBLE 8 // preamble length from 6 to 65535
// fsk modem default parameters (they need to match between devices!!!)
#define CFG_FSK_BIT_RATE 4.8 // bit rate in Kbps from 0.6 to 300.0
#define CFG_FSK_FREQ_DEV 1.2 // frequency deviation in kHz from 0.6 to 200.0
#define CFG_FSK_RX_BW 9.7 // rx bandwidth in kHz !!discrete!! from 4.8 to 467.0
// WiFi client and AP options // WiFi client and AP options
#define CFG_WIFI_ENABLE_AP false // run as wifi access point (for CFG_KISS_TCP_IP mode) #define CFG_WIFI_ENABLE_AP false // run as wifi access point (for CFG_KISS_TCP_IP mode)
#define CFG_WIFI_SSID "<ssid>" // connect to SSID or run as this SSID in AP mode #define CFG_WIFI_SSID "<ssid>" // connect to SSID or run as this SSID in AP mode

Wyświetl plik

@ -4,6 +4,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <DebugLog.h> #include <DebugLog.h>
#include <memory> #include <memory>
#include <vector>
#define CIRCULAR_BUFFER_INT_SAFE #define CIRCULAR_BUFFER_INT_SAFE
#include <CircularBuffer.h> #include <CircularBuffer.h>
@ -13,6 +14,7 @@ namespace Kiss {
class Processor { class Processor {
protected: protected:
// Enum to represent special KISS markers
enum Marker { enum Marker {
Fend = 0xc0, Fend = 0xc0,
Fesc = 0xdb, Fesc = 0xdb,
@ -20,6 +22,7 @@ protected:
Tfesc = 0xdd Tfesc = 0xdd
}; };
// Enum to represent the state of the processor
enum State { enum State {
GetStart = 0, GetStart = 0,
GetEnd, GetEnd,
@ -30,6 +33,7 @@ protected:
Escape Escape
}; };
// Enum to represent KISS commands
enum Cmd { enum Cmd {
Data = 0x00, Data = 0x00,
TxDelay = 0x01, TxDelay = 0x01,
@ -43,6 +47,7 @@ protected:
NoCmd = 0x80 NoCmd = 0x80
}; };
// Enum to represent the type of data being processed
enum DataType { enum DataType {
Raw = 0, Raw = 0,
Control, Control,
@ -50,56 +55,69 @@ protected:
None = 0x80 None = 0x80
}; };
static const int CfgSerialToRigQueueSize = 4096; // Compile-time constants for configuration
static const int CfgRigToSerialQueueSize = 4096; static constexpr int CfgToSerialDelayMs = 10;
static constexpr int CfgSerialToRigQueueSize = 4096;
static constexpr int CfgRigToSerialQueueSize = 4096;
public: public:
Processor(); Processor();
virtual ~Processor() = default; // Add virtual destructor
// Sends data from rig to serial with a specific command
void sendRigToSerial(Cmd cmd, const byte *packet, int packetLength); void sendRigToSerial(Cmd cmd, const byte *packet, int packetLength);
// Queues data for transmission from rig to serial
void queueRigToSerial(Cmd cmd, const byte *packet, int packetLength); void queueRigToSerial(Cmd cmd, const byte *packet, int packetLength);
// Queues data for transmission from serial to rig
void queueSerialToRig(Cmd cmd, const byte *packet, int packetLength); void queueSerialToRig(Cmd cmd, const byte *packet, int packetLength);
// Processes queued data for transmission from rig to serial
bool processRigToSerial(); bool processRigToSerial();
// Processes queued data for transmission from serial to rig
bool processSerialToRig(); bool processSerialToRig();
protected: protected:
// Virtual methods to be implemented by derived classes
virtual bool onRigTxBegin() = 0; virtual bool onRigTxBegin() = 0;
virtual void onRigTx(byte b) = 0; virtual void onRigTx(byte b) = 0;
virtual void onRigTxEnd() = 0; virtual void onRigTxEnd() = 0;
virtual void onRigPacket(void *packet, int packetLength) = 0; virtual void onRigPacket(void *packet, int packetLength) = 0;
virtual void onSerialTx(byte b) = 0; virtual void onSerialTx(byte b) = 0;
virtual bool onSerialRxHasData() = 0; virtual bool onSerialRxHasData() = 0;
virtual bool onSerialRx(byte *b) = 0; virtual bool onSerialRx(byte *b) = 0;
virtual void onControlCommand(Cmd cmd, byte value) = 0; virtual void onControlCommand(Cmd cmd, byte value) = 0;
virtual void onRadioControlCommand(const std::vector<byte> &command) = 0; virtual void onRadioControlCommand(const std::vector<byte> &command) = 0;
virtual void onRebootCommand() = 0; virtual void onRebootCommand() = 0;
private: private:
// Processes a received byte
bool receiveByte(byte rxByte); bool receiveByte(byte rxByte);
bool receiveByteRaw(byte rxByte); bool receiveByteRaw(byte rxByte);
bool receiveByteKiss(byte rxByte); bool receiveByteKiss(byte rxByte);
// Processes data and commands
void processData(byte rxByte); void processData(byte rxByte);
bool processCommand(byte rxByte); bool processCommand(byte rxByte);
protected: protected:
bool disableKiss_; bool disableKiss_; // Flag to disable KISS mode
bool usePrefix3_; bool usePrefix3_; // Flag to use a 3-byte prefix
private: private:
bool isRawIdle_; bool isRawIdle_; // Indicates if raw mode is idle
State state_; State state_; // Current state of the processor
DataType dataType_; DataType dataType_;// Current data type being processed
std::vector<byte> cmdBuffer_; std::vector<byte> cmdBuffer_; // Buffer for commands
// Circular buffers for data queues
CircularBuffer<uint8_t, CfgSerialToRigQueueSize> serialToRigQueue_; CircularBuffer<uint8_t, CfgSerialToRigQueueSize> serialToRigQueue_;
CircularBuffer<uint8_t, CfgRigToSerialQueueSize> rigToSerialQueue_; CircularBuffer<uint8_t, CfgRigToSerialQueueSize> rigToSerialQueue_;
CircularBuffer<uint8_t, CfgRigToSerialQueueSize> rigToSerialQueueIndex_; CircularBuffer<uint8_t, CfgRigToSerialQueueSize> rigToSerialQueueIndex_;
}; };
} // Kiss } // Kiss
#endif // KISS_PROCESSOR_H #endif // KISS_PROCESSOR_H

Wyświetl plik

@ -11,18 +11,28 @@ struct Config
DebugLogLevel LogLevel; // log level DebugLogLevel LogLevel; // log level
bool IsClientMode; // false - server mode, true - client mode (disables wifi and aprsis) bool IsClientMode; // false - server mode, true - client mode (disables wifi and aprsis)
// lora protocol parameters // modulation type
int ModType; // 0 - lora, 1 - fsk
// general radio parameters
long LoraFreqRx; // lora RX frequency, e.g. 433.775e6 long LoraFreqRx; // lora RX frequency, e.g. 433.775e6
long LoraFreqTx; // lora TX frequency, e.g. 433.775e6 long LoraFreqTx; // lora TX frequency, e.g. 433.775e6
int LoraPower; // lora power level in dbm, 20
// lora protocol parameters
long LoraBw; // lora bandwidth, e.g. 125e3 long LoraBw; // lora bandwidth, e.g. 125e3
int LoraSf; // lora spreading factor, e.g. 12 int LoraSf; // lora spreading factor, e.g. 12
int LoraCodingRate; // lora coding rate, e.g. 7 int LoraCodingRate; // lora coding rate, e.g. 7
int LoraPower; // lora power level in dbm, 20
int LoraSync; // lora sync word/packet id, 0x34 int LoraSync; // lora sync word/packet id, 0x34
int LoraCrc; // lora crc mode, 0 - disabled, 1 - 1 byte, 2 - 2 bytes int LoraCrc; // lora crc mode, 0 - disabled, 1 - 1 byte, 2 - 2 bytes
bool LoraExplicit; // lora header mode, true - explicit, false - implicit bool LoraExplicit; // lora header mode, true - explicit, false - implicit
int LoraPreamble; // lora preamble length from 6 to 65535 int LoraPreamble; // lora preamble length from 6 to 65535
// fsk modulation parameters
float FskBitRate; // fsk bit rate, 0.6 - 300.0 Kbps
float FskFreqDev; // fsk frequency deviation 0.6 - 200 kHz
float FskRxBw; // fsk rx bandwidth, discrete from 4.8 to 467 kHz
// lora hardware pinouts and isr // lora hardware pinouts and isr
byte LoraPinSs; // lora ss pin byte LoraPinSs; // lora ss pin
byte LoraPinRst; // lora rst pin byte LoraPinRst; // lora rst pin

Wyświetl plik

@ -39,9 +39,11 @@ private:
void setupWifi(const String &wifiName, const String &wifiKey); void setupWifi(const String &wifiName, const String &wifiKey);
void setupRig(long freq, long bw, int sf, int cr, int pwr, int sync, int crcBytes, bool isExplicit); void setupRig(long freq, long bw, int sf, int cr, int pwr, int sync, int crcBytes, bool isExplicit);
void setFreq(long freq) const; void setupRigFsk(long freq, float bitRate, float freqDev, float rxBw, int pwr);
void setupBt(const String &btName); void setupBt(const String &btName);
void setFreq(long freq) const;
void reconnectWifi() const; void reconnectWifi() const;
bool reconnectAprsis(); bool reconnectAprsis();
void attachKissNetworkClient(); void attachKissNetworkClient();
@ -50,9 +52,14 @@ private:
void onRigTaskRxPacket(); void onRigTaskRxPacket();
void onRigTaskTxPacket(); void onRigTaskTxPacket();
void onRigTaskStartRx();
void onRigTaskStartTx();
static void rigTask(void *self); static void rigTask(void *self);
static ICACHE_RAM_ATTR void onRigIsrRxPacket(); static ICACHE_RAM_ATTR void onRigIsrRxPacket();
void startRx();
static bool startRxTimer(void *param);
void onAprsisDataAvailable(); void onAprsisDataAvailable();
void sendSignalReportEvent(int rssi, float snr); void sendSignalReportEvent(int rssi, float snr);
@ -104,13 +111,18 @@ protected:
private: private:
struct SetHardware { struct SetHardware {
uint32_t freq; uint32_t freqRx;
uint32_t freqTx;
uint8_t modType;
int16_t pwr;
uint32_t bw; uint32_t bw;
uint16_t sf; uint16_t sf;
uint16_t cr; uint16_t cr;
uint16_t pwr;
uint16_t sync; uint16_t sync;
uint8_t crc; uint8_t crc;
uint32_t fskBitRate;
uint32_t fskFreqDev;
uint32_t fskRxBw;
} __attribute__((packed)); } __attribute__((packed));
struct SignalReport { struct SignalReport {
@ -123,7 +135,7 @@ private:
} __attribute__((packed)); } __attribute__((packed));
private: private:
const String CfgLoraprsVersion = "LoRAPRS 1.0.13"; const String CfgLoraprsVersion = "LoRAPRS 1.0.16";
// processor config // processor config
const int CfgConnRetryMs = 500; // connection retry delay, e.g. wifi const int CfgConnRetryMs = 500; // connection retry delay, e.g. wifi
@ -143,7 +155,9 @@ private:
// radio task commands // radio task commands
enum RadioTaskBits { enum RadioTaskBits {
Receive = 0x01, Receive = 0x01,
Transmit = 0x02 Transmit = 0x02,
StartReceive = 0x04,
StartTransmit = 0x10
}; };
private: private:
@ -162,6 +176,7 @@ private:
// peripherals, radio // peripherals, radio
static TaskHandle_t rigTaskHandle_; static TaskHandle_t rigTaskHandle_;
Timer<1> startRxTimer_;
static volatile bool rigIsRxActive_; static volatile bool rigIsRxActive_;
static volatile bool rigIsRxIsrEnabled_; static volatile bool rigIsRxIsrEnabled_;
bool rigIsImplicitMode_; bool rigIsImplicitMode_;

Wyświetl plik

@ -134,7 +134,7 @@ bool Processor::processRigToSerial()
onRigPacket(&buf, rxPacketSize); onRigPacket(&buf, rxPacketSize);
isProcessed = true; isProcessed = true;
yield(); if (!rigToSerialQueueIndex_.isEmpty()) delay(CfgToSerialDelayMs);
} }
return isProcessed; return isProcessed;
} }
@ -280,11 +280,19 @@ bool Processor::receiveByteKiss(byte rxByte)
break; break;
case State::Escape: case State::Escape:
if (rxByte == Marker::Tfend) { if (rxByte == Marker::Tfend) {
onRigTx((byte)Marker::Fend); if (dataType_ == DataType::Raw) {
onRigTx((byte)Marker::Fend);
} else if (dataType_ == DataType::Control) {
cmdBuffer_.push_back((byte)Marker::Fend);
}
state_ = State::GetData; state_ = State::GetData;
} }
else if (rxByte == Marker::Tfesc) { else if (rxByte == Marker::Tfesc) {
onRigTx((byte)Marker::Fesc); if (dataType_ == DataType::Raw) {
onRigTx((byte)Marker::Fesc);
} else if (dataType_ == DataType::Control) {
cmdBuffer_.push_back((byte)Marker::Fesc);
}
state_ = State::GetData; state_ = State::GetData;
} }
else if (rxByte != Marker::Fend) { else if (rxByte != Marker::Fend) {

Wyświetl plik

@ -61,9 +61,14 @@ void Service::setup(const Config &conf)
} }
aprsLoginCommand_ += String("\n"); aprsLoginCommand_ += String("\n");
// peripherals, LoRa // radio module, FSK/LoRa
setupRig(config_.LoraFreqRx, config_.LoraBw, config_.LoraSf, if (config_.ModType == CFG_MOD_TYPE_FSK) {
config_.LoraCodingRate, config_.LoraPower, config_.LoraSync, config_.LoraCrc, config_.LoraExplicit); setupRigFsk(config_.LoraFreqRx, config_.FskBitRate, config_.FskFreqDev, config_.FskRxBw, config_.LoraPower);
}
else {
setupRig(config_.LoraFreqRx, config_.LoraBw, config_.LoraSf,
config_.LoraCodingRate, config_.LoraPower, config_.LoraSync, config_.LoraCrc, config_.LoraExplicit);
}
// start radio task // start radio task
xTaskCreate(rigTask, "rigTask", 4096, this, 5, &rigTaskHandle_); xTaskCreate(rigTask, "rigTask", 4096, this, 5, &rigTaskHandle_);
@ -251,7 +256,7 @@ void Service::setupRig(long loraFreq, long bw, int sf, int cr, int pwr, int sync
#pragma message("Using SX127X") #pragma message("Using SX127X")
LOG_INFO("Using SX127X module"); LOG_INFO("Using SX127X module");
if (isIsrInstalled_) rig_->clearDio0Action(); if (isIsrInstalled_) rig_->clearDio0Action();
rig_->setDio0Action(onRigIsrRxPacket); rig_->setDio0Action(onRigIsrRxPacket, RISING);
isIsrInstalled_ = true; isIsrInstalled_ = true;
#endif #endif
@ -269,6 +274,43 @@ void Service::setupRig(long loraFreq, long bw, int sf, int cr, int pwr, int sync
LOG_INFO("LoRa initialized"); LOG_INFO("LoRa initialized");
} }
void Service::setupRigFsk(long freq, float bitRate, float freqDev, float rxBw, int pwr)
{
LOG_INFO("Initializing FSK");
LOG_INFO("Frequency:", freq, "Hz");
LOG_INFO("Bit rate:", bitRate, "kbps");
LOG_INFO("Deviation:", freqDev, "kHz");
LOG_INFO("Bandwidth:", rxBw, "kHz");
LOG_INFO("Power:", pwr, "dBm");
rig_ = std::make_shared<MODULE_NAME>(new Module(config_.LoraPinSs, config_.LoraPinA, config_.LoraPinRst, config_.LoraPinB));
int state = rig_->beginFSK((float)freq / 1e6, bitRate, freqDev, rxBw, pwr);
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("Radio start error:", state);
}
rig_->disableAddressFiltering();
#ifdef USE_SX126X
#pragma message("Using SX126X")
LOG_INFO("Using SX126X module");
rig_->setRfSwitchPins(config_.LoraPinSwitchRx, config_.LoraPinSwitchTx);
if (isIsrInstalled_) rig_->clearDio1Action();
rig_->setDio1Action(onRigIsrRxPacket);
isIsrInstalled_ = true;
#else
#pragma message("Using SX127X")
LOG_INFO("Using SX127X module");
if (isIsrInstalled_) rig_->clearDio0Action();
rig_->setDio0Action(onRigIsrRxPacket, RISING);
isIsrInstalled_ = true;
#endif
state = rig_->startReceive();
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("Receive start error:", state);
}
LOG_INFO("FSK initialized");
}
void Service::setupBt(const String &btName) void Service::setupBt(const String &btName)
{ {
String btType = config_.BtEnableBle ? "BLE" : "BT"; String btType = config_.BtEnableBle ? "BLE" : "BT";
@ -325,6 +367,7 @@ void Service::loop()
if (config_.TlmEnable) { if (config_.TlmEnable) {
telemetryTimer_.tick(); telemetryTimer_.tick();
} }
startRxTimer_.tick();
} }
ICACHE_RAM_ATTR void Service::onRigIsrRxPacket() { ICACHE_RAM_ATTR void Service::onRigIsrRxPacket() {
@ -346,9 +389,30 @@ void Service::rigTask(void *self) {
else if (commandBits & RadioTaskBits::Transmit) { else if (commandBits & RadioTaskBits::Transmit) {
static_cast<Service*>(self)->onRigTaskTxPacket(); static_cast<Service*>(self)->onRigTaskTxPacket();
} }
if (commandBits & RadioTaskBits::StartReceive) {
static_cast<Service*>(self)->onRigTaskStartRx();
}
else if (commandBits & RadioTaskBits::StartTransmit) {
static_cast<Service*>(self)->onRigTaskStartTx();
}
} }
} }
void Service::onRigTaskStartRx() {
LOG_TRACE("onRigTaskStartRx");
if (config_.PttEnable) {
digitalWrite(config_.PttPin, LOW);
}
if (isHalfDuplex()) {
setFreq(config_.LoraFreqRx);
}
int state = rig_->startReceive();
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("Start receive error: ", state);
}
rigIsRxIsrEnabled_ = true;
}
void Service::onRigTaskRxPacket() { void Service::onRigTaskRxPacket() {
int packetSize = rig_->getPacketLength(); int packetSize = rig_->getPacketLength();
LOG_TRACE("onRigTaskRxPacket", packetSize); LOG_TRACE("onRigTaskRxPacket", packetSize);
@ -369,15 +433,21 @@ void Service::onRigTaskRxPacket() {
rigIsRxActive_ = false; rigIsRxActive_ = false;
} }
void Service::onRigTaskTxPacket() { void Service::onRigTaskStartTx() {
rigIsRxIsrEnabled_ = false; LOG_TRACE("onRigTaskStartTx");
if (isHalfDuplex()) { if (rigIsRxIsrEnabled_) {
setFreq(config_.LoraFreqTx); rigIsRxIsrEnabled_ = false;
} if (isHalfDuplex()) {
if (config_.PttEnable) { setFreq(config_.LoraFreqTx);
digitalWrite(config_.PttPin, HIGH); }
if (config_.PttEnable) {
digitalWrite(config_.PttPin, HIGH);
}
delay(config_.PttTxDelayMs); delay(config_.PttTxDelayMs);
} }
}
void Service::onRigTaskTxPacket() {
while (rigTxQueueIndex_.size() > 0) { while (rigTxQueueIndex_.size() > 0) {
int txPacketSize = rigTxQueueIndex_.shift(); int txPacketSize = rigTxQueueIndex_.shift();
LOG_TRACE("onRigTaskTxPacket", txPacketSize); LOG_TRACE("onRigTaskTxPacket", txPacketSize);
@ -393,18 +463,7 @@ void Service::onRigTaskTxPacket() {
} }
vTaskDelay(1); vTaskDelay(1);
} }
if (config_.PttEnable) { startRxTimer_.in(config_.PttTxTailMs, &startRxTimer);
delay(config_.PttTxTailMs);
digitalWrite(config_.PttPin, LOW);
}
if (isHalfDuplex()) {
setFreq(config_.LoraFreqRx);
}
int state = rig_->startReceive();
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("Start receive error: ", state);
}
rigIsRxIsrEnabled_ = true;
} }
void Service::sendPeriodicBeacon() void Service::sendPeriodicBeacon()
@ -486,6 +545,16 @@ bool Service::sendModemTelemetryTimer(void *param)
return true; return true;
} }
bool Service::startRxTimer(void *param)
{
static_cast<Service*>(param)->startRx();
return true;
}
void Service::startRx() {
xTaskNotify(rigTaskHandle_, RadioTaskBits::StartReceive, eSetBits);
}
void Service::sendModemTelemetry() void Service::sendModemTelemetry()
{ {
float batVoltage = 2 * analogRead(config_.TlmBatMonPin) * (3.3 / 4096.0) + config_.TlmBatMonCal; float batVoltage = 2 * analogRead(config_.TlmBatMonPin) * (3.3 / 4096.0) + config_.TlmBatMonCal;
@ -549,10 +618,6 @@ void Service::performFrequencyCorrection() {
void Service::setFreq(long loraFreq) const { void Service::setFreq(long loraFreq) const {
rig_->setFrequency((float)loraFreq / 1e6); rig_->setFrequency((float)loraFreq / 1e6);
int state = rig_->startReceive();
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("Start receive error:", state);
}
} }
void Service::processIncomingRawPacketAsServer(const byte *packet, int packetLength) { void Service::processIncomingRawPacketAsServer(const byte *packet, int packetLength) {
@ -608,6 +673,8 @@ void Service::processIncomingRawPacketAsServer(const byte *packet, int packetLen
bool Service::onRigTxBegin() bool Service::onRigTxBegin()
{ {
LOG_TRACE("onRigTxBegin"); LOG_TRACE("onRigTxBegin");
startRxTimer_.cancel();
xTaskNotify(rigTaskHandle_, RadioTaskBits::StartTransmit, eSetBits);
rigCurrentTxPacketSize_ = 0; rigCurrentTxPacketSize_ = 0;
return true; return true;
} }
@ -739,21 +806,29 @@ void Service::onRadioControlCommand(const std::vector<byte> &rawCommand) {
if (config_.KissEnableExtensions && rawCommand.size() == sizeof(SetHardware)) { if (config_.KissEnableExtensions && rawCommand.size() == sizeof(SetHardware)) {
LOG_INFO("Setting new radio parameters"); LOG_INFO("Setting new radio parameters");
const struct SetHardware * setHardware = reinterpret_cast<const struct SetHardware*>(rawCommand.data()); const struct SetHardware * setHardware = reinterpret_cast<const struct SetHardware*>(rawCommand.data());
// TODO, add support for split set hardware config_.LoraFreqRx = be32toh(setHardware->freqRx);
config_.LoraFreqRx = be32toh(setHardware->freq); config_.LoraFreqTx = be32toh(setHardware->freqTx);
config_.LoraFreqTx = be32toh(setHardware->freq); config_.ModType = setHardware->modType;
config_.LoraBw = be32toh(setHardware->bw); config_.LoraBw = be32toh(setHardware->bw);
config_.LoraSf = be16toh(setHardware->sf); config_.LoraSf = be16toh(setHardware->sf);
config_.LoraCodingRate = be16toh(setHardware->cr); config_.LoraCodingRate = be16toh(setHardware->cr);
config_.LoraPower = be16toh(setHardware->pwr); config_.LoraPower = (int16_t)be16toh(setHardware->pwr);
config_.LoraSync = be16toh(setHardware->sync); config_.LoraSync = be16toh(setHardware->sync);
config_.FskBitRate = (float)be32toh(setHardware->fskBitRate) / 1e3;
config_.FskFreqDev = (float)be32toh(setHardware->fskFreqDev) / 1e3;
config_.FskRxBw = (float)be32toh(setHardware->fskRxBw) / 1e3;
int crcType = setHardware->crc ? config_.LoraCrc : 0; int crcType = setHardware->crc ? config_.LoraCrc : 0;
setupRig(config_.LoraFreqRx, config_.LoraBw, config_.LoraSf, if (config_.ModType == CFG_MOD_TYPE_FSK) {
config_.LoraCodingRate, config_.LoraPower, config_.LoraSync, crcType, config_.LoraExplicit); setupRigFsk(config_.LoraFreqRx, config_.FskBitRate, config_.FskFreqDev, config_.FskRxBw, config_.LoraPower);
}
else {
setupRig(config_.LoraFreqRx, config_.LoraBw, config_.LoraSf,
config_.LoraCodingRate, config_.LoraPower, config_.LoraSync, crcType, config_.LoraExplicit);
}
} else { } else {
LOG_ERROR("Radio control command of wrong size"); LOG_ERROR("Radio control command of wrong size", rawCommand.size());
} }
} }

Wyświetl plik

@ -17,7 +17,7 @@
#include "loraprs_service.h" #include "loraprs_service.h"
const int CfgPollDelayMs = 20; // main loop delay const int CfgPollDelayMs = 10; // main loop delay
/* /*
* Initialize config from config.h options. * Initialize config from config.h options.
@ -31,18 +31,28 @@ void initializeConfig(LoraPrs::Config &cfg) {
// client/server mode switch // client/server mode switch
cfg.IsClientMode = CFG_IS_CLIENT_MODE; cfg.IsClientMode = CFG_IS_CLIENT_MODE;
// lora parameters, must match on devices // modulation
cfg.ModType = CFG_MOD_TYPE;
// generic module parameters
cfg.LoraFreqRx = CFG_LORA_FREQ_RX; cfg.LoraFreqRx = CFG_LORA_FREQ_RX;
cfg.LoraFreqTx = CFG_LORA_FREQ_TX; cfg.LoraFreqTx = CFG_LORA_FREQ_TX;
cfg.LoraPower = CFG_LORA_PWR;
// lora parameters, must match on devices
cfg.LoraBw = CFG_LORA_BW; cfg.LoraBw = CFG_LORA_BW;
cfg.LoraSf = CFG_LORA_SF; cfg.LoraSf = CFG_LORA_SF;
cfg.LoraCodingRate = CFG_LORA_CR; cfg.LoraCodingRate = CFG_LORA_CR;
cfg.LoraSync = CFG_LORA_SYNC; cfg.LoraSync = CFG_LORA_SYNC;
cfg.LoraCrc = CFG_LORA_CRC; // set to 0 to disable cfg.LoraCrc = CFG_LORA_CRC; // set to 0 to disable
cfg.LoraExplicit = CFG_LORA_EXPLICIT; cfg.LoraExplicit = CFG_LORA_EXPLICIT;
cfg.LoraPower = CFG_LORA_PWR;
cfg.LoraPreamble = CFG_LORA_PREAMBLE; cfg.LoraPreamble = CFG_LORA_PREAMBLE;
// fsk parameters
cfg.FskBitRate = CFG_FSK_BIT_RATE;
cfg.FskFreqDev = CFG_FSK_FREQ_DEV;
cfg.FskRxBw = CFG_FSK_RX_BW;
// lora pinouts // lora pinouts
cfg.LoraPinSs = CFG_LORA_PIN_SS; cfg.LoraPinSs = CFG_LORA_PIN_SS;
cfg.LoraPinRst = CFG_LORA_PIN_RST; cfg.LoraPinRst = CFG_LORA_PIN_RST;