Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions docs/docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ All examples support multiple radio types via `--radio-type` argument:
### SX1262 Direct Radio
- **waveshare**: Waveshare SX1262 HAT for Raspberry Pi
- **uconsole**: ClockworkPi uConsole LoRa module
- **meshadv-mini**: MeshAdviser Mini board
- **meshav**: MeshAdviser Raspberry Pi HAT
- **meshadv-mini**: MeshAdviser Mini Raspberry Pi HAT

### KISS TNC
- **kiss-tnc**: Serial KISS TNC devices (MeshTNC)
Expand All @@ -34,7 +35,7 @@ All examples support multiple radio types via `--radio-type` argument:
Creates radio instances for different hardware types:
- **SX1262 Radios**: Direct hardware control via SPI/GPIO
- **KISS TNC**: Serial protocol wrapper for TNC devices
- Supports waveshare, uconsole, meshadv-mini, and kiss-tnc types
- Supports waveshare, uconsole, meshadv, meshadv-mini, and kiss-tnc types

### `create_mesh_node(name, radio_type, serial_port)`
Helper function that creates a mesh node setup:
Expand Down Expand Up @@ -85,7 +86,7 @@ python examples/send_tracked_advert.py --help
```

**Arguments:**
- `--radio-type`: Choose hardware type (waveshare, uconsole, meshadv-mini, kiss-tnc)
- `--radio-type`: Choose hardware type (waveshare, uconsole, meshadv, meshadv-mini, kiss-tnc)
- `--serial-port`: Serial port for KISS TNC (default: /dev/ttyUSB0)

### SX1262 Direct Radio Examples
Expand Down Expand Up @@ -148,6 +149,14 @@ pyMC_Core supports both direct SX1262 radio control and KISS TNC devices:
- **GPIO Pins**: CS=-1, Reset=25, Busy=24, IRQ=26
- **Additional Setup**: Requires SPI1 overlay and GPS/RTC configuration (see uConsole setup guide)

#### Frequency Labs meshadv
- **Hardware**: FrequencyLabs meshadv Hat
- **Platform**: Raspberry Pi (or compatible single-board computer)
- **Frequency**: 868MHz (EU) or 915MHz (US)
- **TX Power**: Up to 27dBm (Note: Actual tx power is [10dB higher than configured value](https://github.com/chrismyers2000/MeshAdv-Pi-Hat/issues/18))
- **SPI Bus**: SPI0
- **GPIO Pins**: CS=21, Reset=18, Busy=20, IRQ=16

#### Frequency Labs meshadv-mini
- **Hardware**: FrequencyLabs meshadv-mini Hat
- **Platform**: Raspberry Pi (or compatible single-board computer)
Expand Down Expand Up @@ -178,6 +187,16 @@ pyMC_Core supports both direct SX1262 radio control and KISS TNC devices:
- TX Enable: Not used (-1)
- RX Enable: Not used (-1)

#### meshadv (Frequency Labs)
- SPI Bus: 0
- CS ID: 0
- CS Pin: GPIO 21
- Busy Pin: GPIO 20
- Reset Pin: GPIO 18
- IRQ Pin: GPIO 16
- TX Enable: GPIO 13
- RX Enable: GPIO 12

#### meshadv-mini (Frequency Labs)
- SPI Bus: 0
- CS ID: 0
Expand Down Expand Up @@ -320,6 +339,22 @@ All examples use the SX1262 LoRa radio with the following default settings:
- **TX Enable**: Not used (-1)
- **RX Enable**: Not used (-1)

#### meshadv (Frequency Labs)
- **Radio Type**: SX1262 direct hardware control
- **Frequency**: 869.525MHz (European standard)
- **TX Power**: 22dBm (Note: Actual tx power is [10dB higher than configured value](https://github.com/chrismyers2000/MeshAdv-Pi-Hat/issues/18))
- **Spreading Factor**: 11
- **Bandwidth**: 250kHz
- **Coding Rate**: 4/5
- **Preamble Length**: 17 symbols
- **SPI Bus**: 0
- **CS Pin**: GPIO 21
- **Reset Pin**: GPIO 18
- **Busy Pin**: GPIO 20
- **IRQ Pin**: GPIO 16
- **TX Enable**: GPIO 13
- **RX Enable**: GPIO 12

#### meshadv-mini (Frequency Labs)
- **Radio Type**: SX1262 direct hardware control
- **Frequency**: 869.525MHz (European standard)
Expand Down
34 changes: 17 additions & 17 deletions docs/docs/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ The meshadv and meshadv-mini are available from FrequencyLabs, and are open sour
2. Ensure SPI interface is enabled in Raspberry Pi configuration
3. Install required GPIO library: `sudo apt install python3-rpi.lgpio`

**Pin Configuration (Raspberry Pi):**
** meshadv-mini Pin Configuration (Raspberry Pi):**
- SPI Bus: SPI0 (MOSI, MISO, SCLK pins)
- CS: GPIO 21
- Reset: GPIO 18
Expand Down Expand Up @@ -204,22 +204,22 @@ radio.begin()

### Radio Configuration Parameters

| Parameter | Description | Waveshare HAT | meshadv-mini | uConsole |
|--------------------|----------------------------------|----------------|----------------|----------------|
| `bus_id` | SPI bus ID | 0 | 0 | 1 |
| `cs_id` | SPI chip select ID | 0 | 0 | 0 |
| `cs_pin` | Chip select GPIO pin | 21 | 8 | -1 |
| `reset_pin` | Reset GPIO pin | 18 | 24 | 25 |
| `busy_pin` | Busy GPIO pin | 20 | 20 | 24 |
| `irq_pin` | Interrupt GPIO pin | 16 | 16 | 26 |
| `txen_pin` | TX enable GPIO pin | 6 | -1 | -1 |
| `rxen_pin` | RX enable GPIO pin | -1 | 12 | -1 |
| `frequency` | Operating frequency in Hz | 869525000 (EU) | 910525000 (US) | 869525000 (EU) |
| `tx_power` | Transmit power in dBm | 22 | 22 | 22 |
| `spreading_factor` | LoRa spreading factor (7-12) | 11 | 7 | 11 |
| `bandwidth` | Bandwidth in Hz | 250000 | 62500 | 250000 |
| `coding_rate` | Coding rate (5=4/5, 6=4/6, etc.) | 5 | 5 | 5 |
| `preamble_length` | Preamble length | 17 | 17 | 17 |
| Parameter | Description | Waveshare HAT | meshadv | meshadv-mini | uConsole |
|--------------------|----------------------------------|----------------|----------------|----------------|----------------|
| `bus_id` | SPI bus ID | 0 | 0 | 0 | 1 |
| `cs_id` | SPI chip select ID | 0 | 0 | 0 | 0 |
| `cs_pin` | Chip select GPIO pin | 21 | 21 | 8 | -1 |
| `reset_pin` | Reset GPIO pin | 18 | 18 | 24 | 25 |
| `busy_pin` | Busy GPIO pin | 20 | 20 | 20 | 24 |
| `irq_pin` | Interrupt GPIO pin | 16 | 16 | 16 | 26 |
| `txen_pin` | TX enable GPIO pin | 6 | 13 | -1 | -1 |
| `rxen_pin` | RX enable GPIO pin | -1 | 12 | 12 | -1 |
| `frequency` | Operating frequency in Hz | 869525000 (EU) | 910525000 (US) | 910525000 (US) | 869525000 (EU) |
| `tx_power` | Transmit power in dBm | 22 | 22 | 22 | 22 |
| `spreading_factor` | LoRa spreading factor (7-12) | 11 | 7 | 7 | 11 |
| `bandwidth` | Bandwidth in Hz | 250000 | 62500 | 62500 | 250000 |
| `coding_rate` | Coding rate (5=4/5, 6=4/6, etc.) | 5 | 5 | 5 | 5 |
| `preamble_length` | Preamble length | 17 | 17 | 17 | 17 |

**Note:** Adjust the `frequency` parameter based on your regional LoRa regulations (868MHz for EU, 915MHz for US, 433MHz for Asia).

Expand Down
135 changes: 77 additions & 58 deletions examples/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,80 @@
from pymc_core.hardware.base import LoRaRadio
from pymc_core.node.node import MeshNode

# Radio configurations for different hardware
RADIOS = {
"waveshare": {
"bus_id": 0,
"cs_id": 0,
"cs_pin": 21, # Waveshare HAT CS pin
"reset_pin": 18,
"busy_pin": 20,
"irq_pin": 16,
"txen_pin": 13, # GPIO 13 for TX enable
"rxen_pin": 12,
"frequency": int(869.618 * 1000000), # EU: 869.618 MHz
"tx_power": 22,
"spreading_factor": 8,
"bandwidth": int(62.5 * 1000),
"coding_rate": 8,
"preamble_length": 17,
"is_waveshare": True,
},
"uconsole": {
"bus_id": 1, # SPI1
"cs_id": 0,
"cs_pin": -1, # Use hardware CS
"reset_pin": 25,
"busy_pin": 24,
"irq_pin": 26,
"txen_pin": -1,
"rxen_pin": -1,
"frequency": int(869.525 * 1000000), # EU: 869.525 MHz
"tx_power": 22,
"spreading_factor": 11,
"bandwidth": int(250 * 1000),
"coding_rate": 5,
"preamble_length": 17,
},
"meshadv": {
"bus_id": 0,
"cs_id": 0,
"cs_pin": 21,
"reset_pin": 18,
"busy_pin": 20,
"irq_pin": 16,
"txen_pin": 13,
"rxen_pin": 12,
"use_dio3_tcxo": True,
"frequency": int(910.525 * 1000000), # US: 910.525 MHz
"tx_power": 12, # real meshadv power is 10dB higher, see https://github.com/chrismyers2000/MeshAdv-Pi-Hat/issues/18
"spreading_factor": 7,
"bandwidth": int(62.5 * 1000),
"coding_rate": 5,
"preamble_length": 17,
},
"meshadv-mini": {
"bus_id": 0,
"cs_id": 0,
"cs_pin": 8,
"reset_pin": 24,
"busy_pin": 20,
"irq_pin": 16,
"txen_pin": -1,
"rxen_pin": 12,
"frequency": int(910.525 * 1000000), # US: 910.525 MHz
"tx_power": 22,
"spreading_factor": 7,
"bandwidth": int(62.5 * 1000),
"coding_rate": 5,
"preamble_length": 17,
},
}


def get_supported_radios():
return list(RADIOS.keys()) + ["kiss-tnc"]


def create_radio(radio_type: str = "waveshare", serial_port: str = "/dev/ttyUSB0") -> LoRaRadio:
"""Create a radio instance with configuration for specified hardware.
Expand Down Expand Up @@ -70,63 +144,8 @@ def create_radio(radio_type: str = "waveshare", serial_port: str = "/dev/ttyUSB0

logger.debug("Imported SX1262Radio successfully")

# Radio configurations for different hardware
configs = {
"waveshare": {
"bus_id": 0,
"cs_id": 0,
"cs_pin": 21, # Waveshare HAT CS pin
"reset_pin": 18,
"busy_pin": 20,
"irq_pin": 16,
"txen_pin": 13, # GPIO 13 for TX enable
"rxen_pin": 12,
"frequency": int(869.618 * 1000000), # EU: 869.618 MHz
"tx_power": 22,
"spreading_factor": 8,
"bandwidth": int(62.5 * 1000),
"coding_rate": 8,
"preamble_length": 17,
"is_waveshare": True,
},
"uconsole": {
"bus_id": 1, # SPI1
"cs_id": 0,
"cs_pin": -1, # Use hardware CS
"reset_pin": 25,
"busy_pin": 24,
"irq_pin": 26,
"txen_pin": -1,
"rxen_pin": -1,
"frequency": int(869.525 * 1000000), # EU: 869.525 MHz
"tx_power": 22,
"spreading_factor": 11,
"bandwidth": int(250 * 1000),
"coding_rate": 5,
"preamble_length": 17,
},
"meshadv-mini": {
"bus_id": 0,
"cs_id": 0,
"cs_pin": 8,
"reset_pin": 24,
"busy_pin": 20,
"irq_pin": 16,
"txen_pin": -1,
"rxen_pin": 12,
"frequency": int(910.525 * 1000000), # US: 910.525 MHz
"tx_power": 22,
"spreading_factor": 7,
"bandwidth": int(62.5 * 1000),
"coding_rate": 5,
"preamble_length": 17,
},
}

if radio_type not in configs:
raise ValueError(
f"Unknown radio type: {radio_type}. Use 'waveshare', 'meshadv-mini', 'uconsole', or 'kiss-tnc'"
)
if radio_type not in RADIOS:
raise ValueError(f"Unknown radio type: {radio_type}. Use f{get_supported_radios()}")

radio_kwargs = configs[radio_type]
logger.debug(f"Radio configuration for {radio_type}: {radio_kwargs}")
Expand All @@ -153,7 +172,7 @@ def create_mesh_node(

Args:
node_name: Name for the mesh node
radio_type: Type of radio hardware ("waveshare", "uconsole", "meshadv-mini", or "kiss-tnc")
radio_type: Type of radio hardware ("waveshare", "uconsole", "meshadv", "meshadv-mini", or "kiss-tnc")
serial_port: Serial port for KISS TNC (only used with "kiss-tnc" type)

Returns:
Expand Down
8 changes: 3 additions & 5 deletions examples/discover_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import random
import time

from common import create_mesh_node
from common import create_mesh_node, get_supported_radios

from pymc_core.protocol.packet_builder import PacketBuilder

Expand Down Expand Up @@ -149,7 +149,7 @@ def main():
parser = argparse.ArgumentParser(description="Discover nearby mesh nodes")
parser.add_argument(
"--radio-type",
choices=["waveshare", "uconsole", "meshadv-mini", "kiss-tnc"],
choices=get_supported_radios(),
default="waveshare",
help="Radio hardware type (default: waveshare)",
)
Expand Down Expand Up @@ -177,9 +177,7 @@ def main():
if args.radio_type == "kiss-tnc":
print(f"Serial port: {args.serial_port}")

asyncio.run(
discover_nodes(args.radio_type, args.serial_port, args.timeout, args.filter)
)
asyncio.run(discover_nodes(args.radio_type, args.serial_port, args.timeout, args.filter))


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions examples/login_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import time
from typing import Dict, Optional

from common import create_mesh_node
from common import create_mesh_node, get_supported_radios

from pymc_core.node.handlers.login_server import LoginServerHandler
from pymc_core.protocol import Identity, LocalIdentity
Expand Down Expand Up @@ -381,7 +381,7 @@ def main():
)
parser.add_argument(
"--radio-type",
choices=["waveshare", "uconsole", "meshadv-mini", "kiss-tnc"],
choices=get_supported_radios(),
default="waveshare",
help="Radio hardware type (default: waveshare)",
)
Expand Down
4 changes: 2 additions & 2 deletions examples/ping_repeater_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import asyncio
import random

from common import create_mesh_node, print_packet_info
from common import create_mesh_node, get_supported_radios, print_packet_info

from pymc_core.protocol.constants import PAYLOAD_TYPE_TRACE
from pymc_core.protocol.packet_builder import PacketBuilder
Expand Down Expand Up @@ -86,7 +86,7 @@ def main():
parser = argparse.ArgumentParser(description="Ping a repeater using trace packets")
parser.add_argument(
"--radio-type",
choices=["waveshare", "uconsole", "meshadv-mini", "kiss-tnc"],
choices=get_supported_radios(),
default="waveshare",
help="Radio hardware type (default: waveshare)",
)
Expand Down
4 changes: 2 additions & 2 deletions examples/respond_to_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import asyncio

from common import create_mesh_node
from common import create_mesh_node, get_supported_radios

from pymc_core.protocol.packet_builder import PacketBuilder

Expand Down Expand Up @@ -121,7 +121,7 @@ def main():
parser = argparse.ArgumentParser(description="Respond to mesh node discovery requests")
parser.add_argument(
"--radio-type",
choices=["waveshare", "uconsole", "meshadv-mini", "kiss-tnc"],
choices=get_supported_radios(),
default="waveshare",
help="Radio hardware type (default: waveshare)",
)
Expand Down
4 changes: 2 additions & 2 deletions examples/send_channel_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import asyncio

from common import create_mesh_node, print_packet_info
from common import create_mesh_node, get_supported_radios, print_packet_info

from pymc_core.protocol import Packet
from pymc_core.protocol.packet_builder import PacketBuilder
Expand Down Expand Up @@ -71,7 +71,7 @@ def main():
parser = argparse.ArgumentParser(description="Send a channel message to the Public channel")
parser.add_argument(
"--radio-type",
choices=["waveshare", "uconsole", "meshadv-mini", "kiss-tnc"],
choices=get_supported_radios(),
default="waveshare",
help="Radio hardware type (default: waveshare)",
)
Expand Down
Loading