Files
MeshCore/docs/espnow_bridge_setup.md
T

173 lines
7.7 KiB
Markdown

# ESP-NOW bridge: simple setup
Use two ESP32 LoRa boards to join two MeshCore networks with different radio
settings. Each board repeats on its own LoRa network, and the boards exchange
packets directly over 2.4 GHz ESP-NOW. No router, internet connection, or manual
peer pairing is needed.
```text
LoRa network A <--> Repeater A <-- ESP-NOW --> Repeater B <--> LoRa network B
```
## 1. Choose the firmware
Install the exact board's **Full repeater** image on each board. ESP-NOW is
included as a runtime transport on supported ESP32 Full repeaters. Newly
combined ordinary repeaters leave it off until explicitly enabled; that
choice is saved across reboot. Boards with measured capacity exceptions keep
separate `_repeater_bridge_espnow` images. Historical dedicated target names
remain available for direct builds with their original bridge-on defaults.
Full Companion is a different role. See the [firmware picker guide](firmware_picker.md).
Open each board's [USB console](https://flasher.meshcore.io/console) at
115200 baud and run:
```text
get bridge.type
```
The answer can be `espnow`, `mqtt+espnow`, `rs232+espnow`, or
`mqtt+rs232+espnow`, depending on the image. Confirm the
independent ESP-NOW control is present with `get espnow.enabled` and
`get espnow.running`. The `espnow` commands select this transport without
changing another bridge in a combined image.
## 2. Set each board's LoRa network
Configure one board at a time over USB. Replace the placeholders below with
the radio settings used by the network on that board's side. Use `Bridge-A`
for the first board and `Bridge-B` for the second, or choose your own names.
```text
set espnow.enabled off
set name Bridge-A
set radio <freq>,<bw>,<sf>,<cr>
reboot
```
Do not type the angle-bracket placeholders literally.
| Radio option | Meaning |
| --- | --- |
| `freq` | LoRa frequency in MHz. Match the local network on this side. |
| `bw` | LoRa bandwidth in kHz. Match that network's bandwidth. |
| `sf` | Spreading factor, 5-12. Match that network's setting. |
| `cr` | Coding-rate value, 5-8. Match that network's setting. |
| `name` | A label to tell the two repeaters apart. It does not pair them. |
**`set radio` requires a reboot to apply.** After reconnecting, `get radio`
shows the saved settings. Use permanent radio settings for this setup;
`tempradio` sessions expire.
## 3. Configure the ESP-NOW link on both boards
Run this block on **both** boards. Replace `YourSharedKey` with the same
case-sensitive secret on each board, using 1-15 characters. Channel `6` is
an example; both boards must use the same channel.
```text
set espnow.enabled off
set bridge.channel 6
set bridge.format wrapped
set bridge.secret YourSharedKey
set bridge.source tx
set bridge.delay 500
set repeat on
set espnow.enabled on
```
These settings are saved across reboot. Bridge changes apply immediately;
changing an enabled bridge's channel, format, or secret restarts the bridge.
Stopping it first lets you finish configuring both sides before connecting them.
## What each bridge option does
| Option | Choices and purpose |
| --- | --- |
| `espnow.enabled` | `on` starts ESP-NOW; `off` stops it and keeps its saved settings. Independent of MQTT or RS-232. |
| `rs232.enabled` | On combined UART images, starts or stops RS-232 independently of MQTT and ESP-NOW. Use `get rs232.running` to check the live UART. |
| `bridge.channel` | The 2.4 GHz channel, 1-13. Match it on both boards. This is separate from the LoRa frequency in `set radio`. |
| `bridge.format` | `wrapped` is the default for this two-repeater setup and uses the shared secret. `raw` connects to primary-ESP-NOW nodes such as `Generic_ESPNOW` or `SenseCapIndicator-ESPNow`; it ignores the secret. Both peers must use compatible formats. |
| `bridge.secret` | A matching, case-sensitive value of 1-15 characters for `wrapped` mode. It separates bridge groups; it is not strong encryption. MeshCore's own message encryption remains in place. |
| `bridge.source` | `tx` crosses packets this repeater transmits on LoRa, after its forwarding decisions; use this for the setup above. `rx` crosses received packets before those decisions and can pass traffic the local repeater would not forward. |
| `bridge.delay` | Wait before processing a packet received from the other bridge, in milliseconds. Range: 0-10000. Start with the default `500`. |
| `repeat` | `on` enables normal LoRa forwarding; `off` disables forwarding. Keep it `on` on both bridge repeaters. Normal routing, scope, and packet-filter rules still apply. |
| `bridge.type` | Read-only firmware capability, including combined transports. |
| `espnow.running` | Read-only ESP-NOW runtime state. `on` means the local bridge started; it does not prove the other board is reachable. |
This fork uses **`set bridge.source tx`** or **`rx`**. Some upstream guides
use `logTx` and `logRx`; those are not the command values used here.
For a LoRa gateway connected to primary-ESP-NOW Companions instead of another
LoRa repeater, see [raw ESP-NOW compatibility](WiFi.md#wifi-companion-setup).
## 4. Check the link
Run on both boards:
```text
get espnow.enabled
get espnow.running
get bridge.channel
get bridge.format
get bridge.secret
get bridge.source
get bridge.delay
get repeat
get radio
```
Expected: enabled and running `on`, matching channel/format/secret, source
`tx`, delay `500`, repeat `on`, and the intended LoRa settings on each side.
Send a message from a Companion on network A to one on network B, then reply
from B to A. Check both directions; configuration readback alone does not test
delivery.
If it does not work:
- **Commands are unavailable:** check `get bridge.type` and the firmware choice.
- **Enabled is on but running is off:** initialization failed. Reboot and
check again; ensure another WiFi service is not occupying the radio.
- **Both are running but traffic does not cross:** compare channel, format,
and secret; confirm each board's LoRa settings were applied with a reboot,
and check the networks' forwarding and scope rules.
A running bridge keeps the device awake, even with device power saving enabled.
ESP-NOW shares the WiFi radio: use the connected WiFi network's channel when
WiFi is active. Browser OTA pauses ESP-NOW on ordinary non-MQTT repeaters,
reports that pause, and resumes saved-enabled ESP-NOW when OTA is stopped.
A failed OTA start restores the bridge. The RS-232 transport remains available
on combined boards while ESP-NOW is paused.
For every command's full details, see the [bridge CLI reference](cli_commands.md#bridge-when-bridge-support-is-compiled-in).
For a broader comparison with a Linux-based bridge, see the
[MeshCore Nexus bridging guide](https://meshcore.nexus/guides/lora-bridging#method-2-meshcore-esp-now-bridge).
## Keep wardriving traffic off the bridge
New generalized repeater filter tables include a third built-in rule that
blocks authenticated `#wardriving` text and data in both bridge directions,
at every hop count. The same row blocks crossover between radio profiles:
```text
get flood.rule.3
set flood.rule type=any channel=#wardriving hops=all mode=bridge,cross drop
```
The same rule can be added with the shorter command:
```text
set fr any c=#wardriving m=bc d
```
Both forms use the same table. `m=b` means bridge only, `m=c` means crossover
only, and `get fr.N` returns a short command for copying a numbered rule.
The unnumbered command adds the rule safely on existing devices whose saved
tables predate this default. It works with either bridge packet source and
both ESP-NOW formats. Nearby same-profile LoRa forwarding retains the separate
four-hop default. Use `mode=bridge` for a bridge-only block, or `mode=cross` for
a crossover-only block. See the [mode matrix and examples](flood_filtering.md#filter-bridge-and-radio-crossover-traffic).