Adding a radio on the SPI bus has a walkthrough of its own
configuration.md now takes a non-AIO board from its meshtasticd config to a working profile: the key-by-key mapping, a whole example, how to check it, and what the profile deliberately doesn't hold (radio settings, the preamble, identity). It warns that a key left out keeps the AIO's value, unlike meshtasticd where it means off. --spi joins the option lists in cli.md, the README, and the cookbook, radio/ joins the state-files table, and config.example.toml carries a full wiring example. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
dee4674942
commit
2d5e8bb67d
6 files changed
+118
-5
No files matched your search
@@ -216,6 +216,9 @@ meshterm --ble AA:BB:CC:DD:EE:FF info
|
||||
# Connect over the network to a TCP companion (host[:port], port defaults to 5000)
|
||||
meshterm --tcp 192.168.1.50 info
|
||||
|
||||
# Drive a LoRa radio on this machine's own SPI bus (the uConsole AIO; Linux only)
|
||||
meshterm --spi info
|
||||
|
||||
# No radio attached? Use the built-in simulator for development.
|
||||
meshterm --mock
|
||||
|
||||
@@ -253,7 +256,7 @@ does, and its scripted equivalent where one exists.
|
||||
## Scripting it
|
||||
|
||||
Nearly every command speaks `--json`, and the global options — `--profile/-p`, `--port`,
|
||||
`--ble`, `--ble-pin`, `--tcp`, `--mock`, `--db`, `--json`, `--absolute`, `--quiet/-q`,
|
||||
`--ble`, `--ble-pin`, `--tcp`, `--spi`, `--mock`, `--db`, `--json`, `--absolute`, `--quiet/-q`,
|
||||
`--platform` — may be typed before or after the subcommand.
|
||||
|
||||
```bash
|
||||
|
||||
+18
-2
@@ -59,9 +59,25 @@ host = "192.168.1.50"
|
||||
# transport = "tcp"
|
||||
description = "Basestation over WiFi"
|
||||
|
||||
# A radio on this machine's own SPI bus (the uConsole AIO): MeshTerm runs its node.
|
||||
# The pins default to the AIO v1's; a `spi` table states only what differs.
|
||||
# A radio on this machine's own SPI bus: MeshTerm runs its node while it is connected.
|
||||
# The pins default to the uConsole AIO v1's, which needs nothing more than this (and is
|
||||
# listed on the device screen anyway, whenever /dev/spidev1.0 exists).
|
||||
[profiles.aio]
|
||||
transport = "spi"
|
||||
# [profiles.aio.spi]
|
||||
# en_pins = [27] # the AIO v2 powers its radio from pin 27
|
||||
|
||||
# Any other board states its whole wiring — every pin and both switches, because a key
|
||||
# left out keeps the AIO's value. Read them off the board's meshtasticd config; the
|
||||
# values here are an illustration only. docs/configuration.md has the key-by-key mapping.
|
||||
# [profiles.hat.spi]
|
||||
# bus_id = 0 # /dev/spidev0.0
|
||||
# cs_id = 0
|
||||
# reset_pin = 18
|
||||
# busy_pin = 20
|
||||
# irq_pin = 16
|
||||
# txen_pin = 6
|
||||
# rxen_pin = -1
|
||||
# use_dio2_rf = false
|
||||
# use_dio3_tcxo = false
|
||||
# python = "/opt/radio/bin/python" # only to pick the Python that has openhop-core
|
||||
@@ -55,6 +55,7 @@ With no command, MeshTerm launches the interactive menu instead.
|
||||
| `--ble ADDRESS` | Bluetooth address of a companion; selects the BLE transport. |
|
||||
| `--ble-pin PIN` | Pairing PIN, if the Bluetooth companion asks for one. |
|
||||
| `--tcp HOST[:PORT]` | Network address of a TCP companion; selects the TCP transport. Default port 5000. |
|
||||
| `--spi` | The LoRa radio on this machine's own SPI bus; selects the SPI transport. MeshTerm runs the node for the length of the command. Uses the first SPI profile's wiring, else the uConsole AIO's — see [Adding a radio on the SPI bus](configuration.md#adding-a-radio-on-the-spi-bus). Linux only. |
|
||||
| `--mock` | Use the built-in simulator instead of real hardware. Nothing transmits, and the run records to `meshterm-mock.db` rather than your real history. |
|
||||
| `--db PATH` | Use this SQLite database instead of `~/.meshterm/meshterm.db` (or `meshterm-mock.db`, under `--mock`). **It moves the database and nothing else** — see [Where MeshTerm keeps its state](#where-meshterm-keeps-its-state). |
|
||||
| `--json` | Print the answer as JSON instead of aligned text. |
|
||||
@@ -104,6 +105,7 @@ of two directories from the same shell.
|
||||
| `contacts.json`, `channels.json`, `settings.json` | Per-device caches of what the radio last told us, so a screen opens without a round-trip. |
|
||||
| `adverts.json` | The weekly flood advert's clock: when it was switched on, and when each device's week began. |
|
||||
| `mutes.json`, `watchtower.json`, `remote.json` | Muted channels; watched nodes and their alerts; per-node remote-admin cache and CLI history. |
|
||||
| `radio/<spidev>/` | An SPI radio's node, one folder per device node (`radio/spidev1.0/`): its identity key, settings, channels, and contacts, and its log, `node.log`. What firmware would keep in flash. |
|
||||
| `tilecache/` | Downloaded basemap tiles. |
|
||||
| `meshterm.log` | The log file. |
|
||||
| `.lock` | The single-instance lock. |
|
||||
|
||||
@@ -70,3 +70,92 @@ Timestamps are stored as UTC and rendered in your local time. Heard packets olde
|
||||
`history_days` preference are deleted when monitoring starts: once in each menu session,
|
||||
and at the start of each `meshterm monitor` run. Nothing else is pruned.
|
||||
|
||||
## Adding a radio on the SPI bus
|
||||
|
||||
Some boards put the LoRa chip straight on the computer's SPI bus, with no firmware in front
|
||||
of it: the uConsole's AIO board, and LoRa HATs for the Raspberry Pi. MeshTerm drives these
|
||||
itself — it runs the node while it is connected and lets go of the radio when it quits.
|
||||
It needs Linux and the radio library; [the uConsole manual](uconsole.md#step-2--install-the-radio-library)
|
||||
shows how to install that.
|
||||
|
||||
**An AIO v1 needs no configuration.** Its wiring is MeshTerm's default, so whenever
|
||||
`/dev/spidev1.0` exists the device screen lists it as **SPI radio**, and `meshterm --spi`
|
||||
reaches it. Any other board is added with a profile that states how it is wired.
|
||||
|
||||
### 1. Find your board's wiring
|
||||
|
||||
The easiest place to find it is the board's `meshtasticd` configuration, which most vendors
|
||||
publish (usually a `config.yaml` or a `config.d/` fragment with a `Lora:` section). Its keys
|
||||
map one to one:
|
||||
|
||||
| `meshtasticd` (`Lora:`) | MeshTerm (`[profiles.<name>.spi]`) |
|
||||
| --- | --- |
|
||||
| `spidev: spidev0.0` | `bus_id = 0` and `cs_id = 0` — the two numbers of `spidevB.C` |
|
||||
| `CS: 21` | `cs_pin = 21` (only when the board drives chip select from a GPIO) |
|
||||
| `Reset`, `Busy`, `IRQ` | `reset_pin`, `busy_pin`, `irq_pin` |
|
||||
| `TXen`, `RXen` | `txen_pin`, `rxen_pin` |
|
||||
| `DIO2_AS_RF_SWITCH: true` | `use_dio2_rf = true` |
|
||||
| `DIO3_TCXO_VOLTAGE: true` | `use_dio3_tcxo = true` (1.8 V) |
|
||||
| `gpiochip: 4` | `gpio_chip = 4` |
|
||||
|
||||
`Module` must be `sx1262`; that is the chip MeshTerm's node drives. `gpio_chip` is `0` on
|
||||
a Compute Module 4 but differs on a Raspberry Pi 5 and a CM5 — `gpiodetect`, or
|
||||
`ls /dev/gpiochip*`, shows which chip carries the 40-pin header.
|
||||
|
||||
**State every pin and both switches.** Where a `meshtasticd` file leaves a key out, it means
|
||||
"none" or "off". Where the `spi` table leaves a key out, it means *the AIO's value* — IRQ on
|
||||
26, DIO2 and DIO3 on — which is wrong for almost any other board, and a radio wired wrong
|
||||
comes up deaf rather than failing.
|
||||
|
||||
### 2. Write the profile
|
||||
|
||||
In `~/.meshterm/config.toml`, give the radio a name and its wiring. The values below are an
|
||||
illustration, not any particular board's — take yours from step 1:
|
||||
|
||||
```toml
|
||||
[profiles.hat]
|
||||
description = "SX1262 HAT on the Pi header"
|
||||
|
||||
[profiles.hat.spi]
|
||||
bus_id = 0 # /dev/spidev0.0
|
||||
cs_id = 0
|
||||
reset_pin = 18
|
||||
busy_pin = 20
|
||||
irq_pin = 16
|
||||
txen_pin = 6 # this HAT switches its antenna from a GPIO…
|
||||
rxen_pin = -1
|
||||
use_dio2_rf = false # …so DIO2 doesn't
|
||||
use_dio3_tcxo = false # no TCXO on this board
|
||||
```
|
||||
|
||||
A `spi` table is enough to make it an SPI profile; `transport = "spi"` says so outright and
|
||||
is what an AIO profile with no table uses. Every key, with the AIO defaults, is in
|
||||
[the uConsole manual's wiring table](uconsole.md#board-wiring). A key MeshTerm doesn't know,
|
||||
or a value of the wrong type, stops it at startup with the profile named — a misspelt pin
|
||||
is never quietly ignored.
|
||||
|
||||
### 3. Check it
|
||||
|
||||
```bash
|
||||
meshterm -p hat info
|
||||
```
|
||||
|
||||
The first run starts the node, which mints the radio's identity. If something is wrong, the
|
||||
error says what to fix — a missing `/dev/spidev*` (enable SPI and reboot), a permission
|
||||
problem (join the `spi` and `gpio` groups), a missing radio library, or another program
|
||||
already holding the radio. A node that starts but never answers leaves its log in
|
||||
`~/.meshterm/radio/spidev0.0/node.log`. Once it answers, the device screen lists the radio
|
||||
under the profile's name.
|
||||
|
||||
### What the profile doesn't hold
|
||||
|
||||
- **Radio settings.** Frequency, bandwidth, spreading factor, coding rate, and TX power are
|
||||
the node's own settings, saved by the node and changed on **Device config** like any
|
||||
companion's. A new node starts on MeshCore's **US/Canada preset** (910.525 MHz, 62.5 kHz,
|
||||
SF7, CR 4/5, 22 dBm): anywhere else, change it on Device config before you send anything.
|
||||
- **The preamble.** The node follows MeshCore's own rule — 32 symbols up to SF8, 16 above —
|
||||
and a receiver that expects anything else misses most of the mesh. `preamble_length` was
|
||||
once a wiring key and is refused now; delete the line if an old profile has it.
|
||||
- **Identity.** The node's key, contacts, and channels live in
|
||||
`~/.meshterm/radio/<spidev>/`, filed by the device node rather than the profile, so
|
||||
renaming a profile, or reaching the same radio from the device screen, keeps the same node.
|
||||
+1
-1
@@ -53,7 +53,7 @@ meshterm preferences set weekly_flood_advert on # flood an advert once a week,
|
||||
meshterm monitor --seconds 60
|
||||
```
|
||||
|
||||
Global options — `--profile/-p`, `--port`, `--ble`, `--ble-pin`, `--tcp`, `--mock`,
|
||||
Global options — `--profile/-p`, `--port`, `--ble`, `--ble-pin`, `--tcp`, `--spi`, `--mock`,
|
||||
`--db`, `--json`, `--absolute`, `--quiet/-q`, `--platform` — may be typed **before or
|
||||
after** the subcommand: `meshterm contacts --json` and `meshterm --json contacts` are the
|
||||
same run.
|
||||
|
||||
+4
-1
@@ -253,7 +253,10 @@ same two commands.
|
||||
## Board wiring
|
||||
|
||||
The defaults match the hackergadgets uConsole AIO **v1**, which needs no `spi` table at
|
||||
all. State only what differs, under `[profiles.<name>.spi]`:
|
||||
all. State only what differs, under `[profiles.<name>.spi]`. For a board that isn't an
|
||||
AIO — a LoRa HAT on a Raspberry Pi, say — [Adding a radio on the SPI
|
||||
bus](configuration.md#adding-a-radio-on-the-spi-bus) walks through a whole profile, including
|
||||
how to read the pins off the board's `meshtasticd` configuration:
|
||||
|
||||
```toml
|
||||
[profiles.aio2]
|
||||
|
||||
Reference in new issue
Block a user