Skip to content

Commit db2bafe

Browse files
authored
Merge pull request #12 from rightup/dev
Implement CAD check for LBT & Serial KISS TNC devices (MeshTNC).
2 parents 4027554 + 0d52cee commit db2bafe

18 files changed

+2114
-178
lines changed

.pre-commit-config.yaml

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,22 @@ repos:
3636
exclude: '^(src/pymc_core/hardware/lora/|examples/)'
3737

3838
# Run pytest to ensure all tests pass
39-
- repo: local
40-
hooks:
41-
- id: pytest
42-
name: pytest
43-
entry: pytest
44-
language: system
45-
pass_filenames: false
46-
# Only run if Python files in src/ or tests/ have changed
47-
files: ^(src/|tests/|pyproject\.toml|setup\.py).*$
48-
args: ["-v", "--tb=short"]
49-
- id: pytest-fast
50-
name: pytest-fast (quick smoke test)
51-
entry: pytest
52-
language: system
53-
pass_filenames: false
54-
# Run a quick subset of tests for faster feedback
55-
files: ^(src/|tests/).*\.py$
56-
args: ["-v", "--tb=short", "-x", "--maxfail=3", "tests/test_basic.py", "tests/test_crypto.py"]
57-
stages: [manual]
39+
# - repo: local
40+
# hooks:
41+
# - id: pytest
42+
# name: pytest
43+
# entry: pytest
44+
# language: system
45+
# pass_filenames: false
46+
# # Only run if Python files in src/ or tests/ have changed
47+
# files: ^(src/|tests/|pyproject\.toml|setup\.py).*$
48+
# args: ["-v", "--tb=short"]
49+
# - id: pytest-fast
50+
# name: pytest-fast (quick smoke test)
51+
# entry: pytest
52+
# language: system
53+
# pass_filenames: false
54+
# # Run a quick subset of tests for faster feedback
55+
# files: ^(src/|tests/).*\.py$
56+
# args: ["-v", "--tb=short", "-x", "--maxfail=3", "tests/test_basic.py", "tests/test_crypto.py"]
57+
# stages: [manual]

docs/docs/examples.md

Lines changed: 189 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,40 @@ This section contains practical examples of using pyMC_Core for mesh communicati
66

77
This directory contains examples for using PyMC Core functionality. More examples will be added over time.
88

9-
## Files
9+
## Available Examples
1010

11-
- `common.py`: Shared utilities and mock implementations used by all examples
12-
- `send_flood_advert.py`: Flood advertisement example
13-
- `send_direct_advert.py`: Direct advertisement example
14-
- `send_tracked_advert.py`: Tracked advertisement example
15-
- `ping_repeater_trace.py`: Trace ping example for repeater diagnostics
11+
All examples support multiple radio types via `--radio-type` argument:
12+
13+
- `send_tracked_advert.py`: Send location-tracked advertisements
14+
- `send_direct_advert.py`: Send direct advertisements without mesh routing
15+
- `send_flood_advert.py`: Send flood advertisements that propagate through mesh
16+
- `send_text_message.py`: Send text messages to mesh nodes
17+
- `send_channel_message.py`: Send messages to specific channels
18+
- `ping_repeater_trace.py`: Test mesh routing and trace packet paths
19+
- `common.py`: Shared utilities for radio setup and mesh node creation
20+
21+
## Radio Hardware Support
22+
23+
### SX1262 Direct Radio
24+
- **waveshare**: Waveshare SX1262 HAT for Raspberry Pi
25+
- **uconsole**: ClockworkPi uConsole LoRa module
26+
- **meshadv-mini**: MeshAdviser Mini board
27+
28+
### KISS TNC
29+
- **kiss-tnc**: Serial KISS TNC devices (MeshTNC)
1630

1731
## Shared Components (`common.py`)
1832

19-
### `MockLoRaRadio`
20-
Mock radio implementation for testing and demonstration:
21-
- Simulates LoRa hardware without requiring actual hardware
22-
- Logs transmission operations
23-
- Returns realistic RSSI/SNR values
24-
- Implements the `LoRaRadio` interface
33+
### `create_radio(radio_type, serial_port)`
34+
Creates radio instances for different hardware types:
35+
- **SX1262 Radios**: Direct hardware control via SPI/GPIO
36+
- **KISS TNC**: Serial protocol wrapper for TNC devices
37+
- Supports waveshare, uconsole, meshadv-mini, and kiss-tnc types
2538

26-
### `create_mesh_node(node_name)`
39+
### `create_mesh_node(name, radio_type, serial_port)`
2740
Helper function that creates a mesh node setup:
2841
- Generates a new `LocalIdentity` with cryptographic keypair
29-
- Creates and initializes a `MockLoRaRadio`
42+
- Creates and configures the specified radio type
3043
- Returns configured `MeshNode` and `LocalIdentity`
3144

3245
### `print_packet_info(packet, description)`
@@ -60,62 +73,63 @@ Example showing how to ping a repeater using trace packets for network diagnosti
6073

6174
## Running the Examples
6275

63-
All examples use SX1262 LoRa radio hardware with support for multiple radio types.
76+
All examples support multiple radio hardware types via unified command-line arguments.
6477

65-
### Direct Execution (Recommended)
78+
### Command Line Interface
6679

67-
Run the example scripts directly with optional radio type selection:
80+
Each example uses argparse with consistent options:
6881

6982
```bash
70-
# Run examples with default Waveshare radio
71-
python examples/send_flood_advert.py
72-
python examples/send_direct_advert.py
73-
python examples/send_text_message.py
74-
python examples/send_channel_message.py
75-
python examples/ping_repeater_trace.py
76-
python examples/send_tracked_advert.py
77-
78-
# Run examples with uConsole radio
79-
python examples/send_flood_advert.py uconsole
80-
python examples/send_direct_advert.py uconsole
81-
python examples/send_text_message.py uconsole
83+
# Show help for any example
84+
python examples/send_tracked_advert.py --help
8285
```
8386

84-
Each example script accepts an optional radio type parameter:
85-
- `waveshare` (default) - Waveshare SX1262 HAT
86-
- `uconsole` - HackerGadgets uConsole
87-
- `meshadv-mini` - FrequencyLabs meshadv-mini
87+
**Arguments:**
88+
- `--radio-type`: Choose hardware type (waveshare, uconsole, meshadv-mini, kiss-tnc)
89+
- `--serial-port`: Serial port for KISS TNC (default: /dev/ttyUSB0)
8890

89-
You can also run examples directly with command-line arguments:
91+
### SX1262 Direct Radio Examples
9092

9193
```bash
92-
# Default Waveshare HAT configuration
93-
python examples/send_flood_advert.py
94+
# Send tracked advert with Waveshare HAT (default)
95+
python examples/send_tracked_advert.py
9496

95-
# uConsole configuration
96-
python examples/send_flood_advert.py uconsole
97-
```
97+
# Send text message with uConsole
98+
python examples/send_text_message.py --radio-type uconsole
9899

99-
### Command Line Options
100+
# Send direct advert with MeshAdv Mini
101+
python examples/send_direct_advert.py --radio-type meshadv-mini
100102

101-
Each example accepts an optional radio type parameter:
103+
# Ping test with Waveshare
104+
python examples/ping_repeater_trace.py --radio-type waveshare
105+
```
102106

103-
- `waveshare` (default): Waveshare LoRaWAN/GNSS HAT configuration
104-
- `uconsole`: HackerGadgets uConsole configuration
105-
- `meshadv-mini`: Frequency Labs Mesh Adv
107+
### KISS TNC Examples
106108

107109
```bash
108-
# Examples with explicit radio type
109-
python examples/send_flood_advert.py waveshare
110-
python examples/send_flood_advert.py uconsole
111-
python examples/send_flood_advert.py meshadv-mini
110+
# Send tracked advert via KISS TNC
111+
python examples/send_tracked_advert.py --radio-type kiss-tnc --serial-port /dev/cu.usbserial-0001
112+
113+
# Send text message via KISS TNC
114+
python examples/send_text_message.py --radio-type kiss-tnc --serial-port /dev/ttyUSB0
115+
116+
# Send flood advert via KISS TNC
117+
python examples/send_flood_advert.py --radio-type kiss-tnc --serial-port /dev/cu.usbserial-0001
118+
119+
# Send channel message via KISS TNC
120+
python examples/send_channel_message.py --radio-type kiss-tnc --serial-port /dev/ttyUSB0
121+
122+
# Ping test via KISS TNC
123+
python examples/ping_repeater_trace.py --radio-type kiss-tnc --serial-port /dev/cu.usbserial-0001
112124
```
113125

114126
## Hardware Requirements
115127

116-
### Supported SX1262 Radio Hardware
128+
### Supported Radio Hardware
129+
130+
pyMC_Core supports both direct SX1262 radio control and KISS TNC devices:
117131

118-
pyMC_Core supports multiple SX1262-based LoRa radio modules:
132+
### SX1262 Direct Radio Hardware
119133

120134
#### Waveshare LoRaWAN/GNSS HAT
121135
- **Hardware**: Waveshare SX1262 LoRa HAT
@@ -174,6 +188,23 @@ pyMC_Core supports multiple SX1262-based LoRa radio modules:
174188
- TX Enable: Not used (-1)
175189
- RX Enable: GPIO 12
176190

191+
### KISS TNC Hardware
192+
193+
#### KISS TNC Devices
194+
- **Hardware**: Any KISS-compatible TNC device (MeshTNC, etc.)
195+
- **Interface**: Serial/USB connection
196+
- **Protocol**: KISS Serial Protocol
197+
- **Configuration**: Radio settings handled by TNC firmware
198+
- **Connection**: USB, RS-232, or TTL serial
199+
- **Baud Rate**: 115200 (default, configurable)
200+
- **Advantages**: No GPIO/SPI setup required, plug-and-play operation
201+
202+
**Supported TNC Devices:**
203+
- MeshTNC boards
204+
- OpenTracker+ with KISS firmware
205+
- Mobilinkd TNC devices
206+
- Custom Arduino/ESP32 KISS TNCs
207+
177208
## Dependencies
178209

179210
> **Important**: On modern Python installations (Ubuntu 22.04+, Debian 12+), you may encounter `externally-managed-environment` errors when installing packages system-wide. Create a virtual environment first:
@@ -194,23 +225,40 @@ pyMC_Core supports multiple SX1262-based LoRa radio modules:
194225
pip install pymc_core
195226
```
196227
197-
### Hardware Dependencies (for SX1262 radio)
228+
### Hardware Dependencies
229+
230+
**For SX1262 Direct Radio:**
198231
```bash
199232
pip install pymc_core[hardware]
200233
# or manually:
201234
pip install gpiozero lgpio
202235
```
203236

237+
**For KISS TNC:**
238+
```bash
239+
pip install pyserial
240+
```
241+
204242
### All Dependencies
205243
```bash
206244
pip install pymc_core[all]
207245
```
208246

209247
## Hardware Setup
210248

249+
### SX1262 Direct Radio Setup
250+
211251
1. Connect SX1262 module to Raspberry Pi GPIO pins according to the pin configuration
212-
2. Install required Python packages
213-
3. Run any example to test the setup
252+
2. Enable SPI interface: `sudo raspi-config` → Interface Options → SPI
253+
3. Install required Python packages
254+
4. Run any example to test the setup
255+
256+
### KISS TNC Setup
257+
258+
1. Connect KISS TNC device via USB or serial
259+
2. Install pyserial: `pip install pyserial`
260+
3. Identify serial port: `ls /dev/tty*` or `ls /dev/cu.*` (macOS)
261+
4. Run examples with `--radio-type kiss-tnc --serial-port /dev/ttyUSB0`
214262

215263
The examples will automatically initialize the radio with the default configuration and send packets.
216264

@@ -288,7 +336,23 @@ All examples use the SX1262 LoRa radio with the following default settings:
288336
- **TX Enable**: Not used (-1)
289337
- **RX Enable**: GPIO 12
290338

291-
The radio configuration is hardcoded in `common.py` for simplicity and reliability.
339+
### KISS TNC Configuration
340+
- **Radio Type**: KISS Serial Protocol over TNC device
341+
- **Frequency**: 869.525MHz (EU standard, configurable)
342+
- **TX Power**: 22dBm (configurable)
343+
- **Spreading Factor**: 11 (configurable)
344+
- **Bandwidth**: 250kHz (configurable)
345+
- **Coding Rate**: 4/5 (configurable)
346+
- **Serial Port**: /dev/ttyUSB0 (Linux), /dev/cu.usbserial-* (macOS)
347+
- **Baud Rate**: 115200 (default)
348+
- **Protocol**: KISS frames with radio configuration commands
349+
- **Auto Configure**: Automatically configures TNC and enters KISS mode
350+
351+
All radio configurations use Hz-based frequency and bandwidth values for consistency:
352+
- **Frequency**: `int(869.525 * 1000000)` (869.525 MHz in Hz)
353+
- **Bandwidth**: `int(250 * 1000)` (250 kHz in Hz)
354+
355+
The radio configurations are defined in `common.py` for each hardware type.
292356

293357
## Hardware Setup
294358

@@ -431,3 +495,74 @@ custom_packet = Packet(
431495

432496
await node.send_packet(custom_packet)
433497
```
498+
499+
## Troubleshooting
500+
501+
### SX1262 Radio Issues
502+
503+
**SPI Communication Problems:**
504+
```bash
505+
# Enable SPI interface
506+
sudo raspi-config # → Interface Options → SPI
507+
508+
# Check SPI devices
509+
ls /dev/spi*
510+
511+
# Verify GPIO permissions
512+
sudo usermod -a -G gpio $USER
513+
```
514+
515+
**GPIO Access Errors:**
516+
```bash
517+
# Install modern GPIO library
518+
sudo apt install python3-rpi.lgpio
519+
520+
# Remove old GPIO library if present
521+
sudo apt remove python3-rpi.gpio
522+
```
523+
524+
### KISS TNC Issues
525+
526+
**Serial Port Problems:**
527+
```bash
528+
# Find available serial ports
529+
ls /dev/tty* # Linux
530+
ls /dev/cu.* # macOS
531+
532+
# Check port permissions
533+
sudo chmod 666 /dev/ttyUSB0
534+
535+
# Test serial connection
536+
screen /dev/ttyUSB0 115200
537+
```
538+
539+
**KISS Protocol Issues:**
540+
- Verify TNC supports KISS mode
541+
- Check baud rate (default: 115200)
542+
- Ensure no other programs using port
543+
- Try different serial port if multiple devices
544+
545+
**Configuration Problems:**
546+
- All examples use Hz-based frequency values
547+
- KISS TNC automatically configures radio
548+
- Check TNC firmware supports configuration commands
549+
550+
### Import Errors
551+
552+
**Module Not Found:**
553+
```bash
554+
# Install in development mode
555+
cd pyMC_core
556+
pip install -e .
557+
558+
# Or install from PyPI
559+
pip install pymc_core
560+
```
561+
562+
**Virtual Environment Issues:**
563+
```bash
564+
# Create fresh virtual environment
565+
python3 -m venv pymc_env
566+
source pymc_env/bin/activate # Linux/Mac
567+
pip install pymc_core
568+
```

0 commit comments

Comments
 (0)