173 lines
7.7 KiB
Markdown
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).
|