rmesh-reticulum/docs/GATEWAY_SETUP.md

12 KiB

rMesh Gateway Setup Guide

Dual-stack mesh networking: MeshCore for LoRa mesh, Reticulum for Internet backbone.

This guide covers:

  • Setting up a MeshCore Companion node as your primary LoRa gateway (Part 1-3)
  • Optionally adding an RNode for Reticulum Internet bridging (Part 4-5)
  • Radio parameters and network architecture (Part 6-7)

Architecture

[MeshCore Nodes] <--868MHz--> [Companion WiFi] <--TCP:5000--> [rmesh-reticulum] <--TCP:4242--> [Reticulum Internet backbone]

MeshCore handles the LoRa mesh (structured routing, 64 hops, efficient spectrum use). Reticulum bridges separate LoRa islands over the Internet.


Part 0: MeshCore Companion WiFi Setup (Primary Gateway)

This is the recommended primary gateway. A MeshCore Companion node with WiFi firmware creates a TCP server that rMesh connects to directly.

Flash MeshCore Companion WiFi firmware

  1. Open https://meshcore.io/flasher in Chrome.
  2. Connect a Heltec V3 or T-Beam via USB.
  3. Select your device, then Companion firmware.
  4. Enable WiFi in the configuration (set your SSID + password).
  5. Flash. The device creates a TCP server on port 5000.

Find the device IP

After flashing, the device connects to your WiFi. Find its IP via your router's DHCP client list, or use:

# If mDNS is available
ping meshcore.local

Enable in rMesh

Edit /opt/apps/rmesh-reticulum/.env:

MESHCORE_ENABLED=true
MESHCORE_HOST=192.168.1.xxx    # Your companion's IP
MESHCORE_PORT=5000

Restart:

cd /opt/apps/rmesh-reticulum
docker compose up -d

Check logs:

docker logs rmesh-reticulum --tail 20

You should see: MeshCore bridge ready — device: YourNodeName

Alternative: USB Serial

If the companion is plugged directly into the server:

MESHCORE_ENABLED=true
MESHCORE_SERIAL=/dev/ttyUSB0

And add to docker-compose.yml:

devices:
  - /dev/ttyUSB0:/dev/ttyUSB0

Part 0.5: MeshCore Repeaters and Room Servers

Flash a Repeater (autonomous relay)

  1. Same web flasher, select Repeater instead of Companion.
  2. Repeaters are autonomous — no phone or server connection needed.
  3. They learn routes and relay traffic between companions.
  4. Deploy on rooftops/high points with the solar kit from the BOM.

Flash a Room Server (BBS)

  1. Web flasher, select Room Server.
  2. Room Servers store posts/messages for the community.
  3. Users connect to Room Servers through the mesh via their Companion.

Part 1: RNode for Reticulum Internet Backbone (Optional)

If you want to bridge separate MeshCore mesh islands over the Internet, add an RNode running Reticulum as a second radio interface.

Note: RNode and MeshCore are different protocols on different radios. They don't interfere — use separate Heltec V3 boards for each.

Overview (RNode section)

[LoRa mesh nodes] <--868 MHz--> [RNode (Heltec V3)] <--USB--> [Server] <--Docker--> [rmesh-reticulum]

The RNode acts as a radio modem. It converts LoRa radio traffic into serial data that Reticulum can process. Reticulum running inside the rmesh-reticulum container bridges the radio network with the TCP/IP network.


Part 1: Flash RNode Firmware onto Heltec V3

Prerequisites

On any Linux/macOS machine with USB:

# Install Reticulum (includes rnodeconf tool)
pip install rns --upgrade

# Linux only: add your user to the serial port group
sudo usermod -a -G dialout $USER
# Log out and back in for this to take effect

The Heltec V3 uses a CH9102 USB chip. Modern Linux kernels include the driver (ch341 module). No extra drivers needed on Linux. On macOS/Windows, install the CH340/CH9102 driver from the manufacturer.

Flash the firmware

  1. Connect the Heltec V3 via USB-C (use a data cable, not charge-only).

  2. Run the autoinstaller:

    rnodeconf --autoinstall
    
  3. When prompted:

    • Device type: Heltec LoRa32 v3
    • Frequency band: 868/915/923 MHz (the SX1262 variant)
  4. The tool downloads and flashes the firmware. Takes about 1-2 minutes.

Alternative: Browser-based flasher

Open https://liamcottle.github.io/rnode-flasher/ in Chrome/Edge. Select Heltec LoRa32 V3, 868 MHz. Click flash. Uses WebSerial API.

Verify the flash

rnodeconf -i /dev/ttyUSB0

You should see: firmware version, device signature, hardware platform, and frequency range. The status LED will flash every ~2 seconds when idle.

Tip: Find the stable device path for later use:

ls -la /dev/serial/by-id/

Use this path instead of /dev/ttyUSB0 to avoid port renumbering.


Part 2: Connect RNode to the Server

Option A: Direct USB to server (simplest)

If the Heltec V3 is plugged directly into the Netcup server (or a USB-over-IP adapter), the device appears as /dev/ttyUSB0 or /dev/ttyACM0 on the host.

Option B: Via Raspberry Pi bridge (remote location)

If the RNode is at a different location from the server:

  1. Plug RNode into a Raspberry Pi via USB.
  2. Install Reticulum on the Pi: pip install rns
  3. Configure the Pi's Reticulum with:
    • An RNodeInterface for the radio
    • A TCPClientInterface pointing to your server's IP on port 4242
  4. The Pi bridges radio traffic to the server over the internet.

Pi config (~/.reticulum/config):

[reticulum]
  enable_transport = True

[interfaces]
  [[RNode LoRa]]
    type = RNodeInterface
    enabled = yes
    port = /dev/ttyUSB0
    frequency = 867200000
    bandwidth = 125000
    txpower = 7
    spreadingfactor = 8
    codingrate = 5

  [[TCP to Server]]
    type = TCPClientInterface
    enabled = yes
    target_host = YOUR_SERVER_IP
    target_port = 4242

Option C: RNode over WiFi/Bluetooth

RNode supports network connections. After flashing, configure the RNode's WiFi:

rnodeconf /dev/ttyUSB0 --wifi-ssid "YourNetwork" --wifi-pass "YourPassword"

Then in Reticulum config, use TCP instead of serial:

[[RNode LoRa]]
  type = RNodeInterface
  enabled = yes
  port = tcp://rnode-ip-address:0

Part 3: Enable RNode in rmesh-reticulum Container

Step 1: Pass the USB device into Docker

Edit /opt/apps/rmesh-reticulum/docker-compose.yml:

services:
  rmesh-reticulum:
    # ... existing config ...
    devices:
      - /dev/ttyUSB0:/dev/ttyUSB0
    # You may also need:
    # privileged: true
    # Or more targeted:
    # cap_add:
    #   - SYS_RAWIO

Use the stable path from /dev/serial/by-id/ instead of /dev/ttyUSB0 to avoid issues if multiple USB devices are connected.

Step 2: Update the Reticulum config

Edit /opt/apps/rmesh-reticulum/config/reticulum.conf — uncomment and configure the RNode interface:

[interfaces]
  [[Default Interface]]
    type = TCPServerInterface
    interface_enabled = True
    listen_ip = 0.0.0.0
    listen_port = 4242

  [[RNode LoRa]]
    type = RNodeInterface
    interface_enabled = True
    port = /dev/ttyUSB0
    frequency = 867200000
    bandwidth = 125000
    txpower = 7
    spreadingfactor = 8
    codingrate = 5

Step 3: Rebuild and restart

cd /opt/apps/rmesh-reticulum

# If this is first time changing the config after initial deploy,
# clear the persisted config so entrypoint.sh copies the new one:
docker compose down
docker volume rm rmesh-reticulum_reticulum_data  # WARNING: resets identity
# Or exec into container and update config in-place:
docker exec rmesh-reticulum cp /app/config/reticulum.conf /data/reticulum/config

docker compose up -d

Step 4: Verify

docker logs rmesh-reticulum --tail 20

You should see the RNode interface initializing alongside the TCP interface. Check the bridge API:

curl -H "X-Bridge-API-Key: YOUR_KEY" http://localhost:8000/api/status

The path_count should increase as radio nodes announce themselves.


Part 4: Radio Parameters

Parameter Value Notes
frequency 867200000 867.2 MHz (EU general)
bandwidth 125000 125 kHz — good range/speed balance
txpower 7 7 dBm (~5 mW). Safe for EU with any antenna
spreadingfactor 8 SF8 — balanced range and throughput
codingrate 5 4/5 — lowest overhead, fine for low-noise

Tuning for range vs speed

Goal SF BW Bitrate Range
Maximum speed 7 250000 ~11 kbps Shorter
Balanced 8 125000 ~3.1 kbps Medium
Maximum range 12 125000 ~0.29 kbps Longest

All nodes on the same network must use identical radio parameters. Different SF/BW/frequency = invisible to each other.

EU duty cycle

The 868 MHz band has a 1% duty cycle limit on most sub-bands (ETSI EN 300.220). Reticulum handles this automatically. With SF8/125kHz, a typical message takes ~100ms on air, allowing ~36 messages per hour within duty cycle.

The sub-band 869.4-869.65 MHz allows 10% duty cycle and 500 mW ERP — useful for higher-traffic gateways. Set frequency = 869525000 to use it.


Part 5: Flash MeshCore on a Second Device

For a companion device that pairs with your phone:

Web flasher (easiest)

  1. Open https://meshcore.io/flasher in Chrome.
  2. Connect a second Heltec V3 via USB.
  3. Select: Heltec V3Companion.
  4. Click flash. Done in under a minute.

Companion apps

After flashing MeshCore Companion firmware, pair with:

MeshCore Repeater

To flash a dedicated relay node (e.g., the T-Beam for outdoor solar deployment):

  1. Same web flasher, select Repeater instead of Companion.
  2. Repeaters are autonomous — no phone pairing needed.
  3. They learn routes and relay traffic between companions.

Part 6: Network Architecture

Once you have hardware deployed:

                                    Internet
                                       |
                              [Netcup Server]
                              rmesh-reticulum
                              TCP:4242 + API:8000
                                   |    |
                    +--------------+    +----------------+
                    |                                    |
            [RNode Gateway]                    [Remote Reticulum
             Heltec V3 USB                      nodes via TCP]
             868 MHz LoRa
                    |
         +----------+-----------+
         |                      |
  [MeshCore Companion]   [MeshCore Repeater]
   Heltec V3 + Phone     T-Beam + Solar
                                |
                         [More nodes...]

The RNode gateway bridges LoRa and TCP/IP. MeshCore nodes on the same frequency are heard by the RNode. Reticulum handles the routing and encryption.

Important: MeshCore and Reticulum use different protocols at the LoRa level. An RNode running Reticulum firmware talks to other Reticulum/RNode devices. MeshCore devices talk to other MeshCore devices. To bridge between them, you'd need both firmwares running on separate radios, or use the experimental Reticulum-over-MeshCore bridge (see GitHub discussions).

For a simple start: use RNode firmware on everything, and run Sideband on phones instead of the MeshCore app. This keeps the whole network on one protocol.


Troubleshooting

Problem Solution
Permission denied: /dev/ttyUSB0 sudo usermod -a -G dialout $USER then re-login
Device not detected Try a different USB cable (must be data-capable)
rnodeconf can't find device Check ls /dev/tty* — may be ttyACM0 instead of ttyUSB0
RNode flashing fails Hold BOOT button while plugging in USB, then retry
Container can't see device Add devices: ["/dev/ttyUSB0:/dev/ttyUSB0"] to docker-compose.yml
No radio peers discovered Verify all nodes use same frequency/bandwidth/SF
Docker volume has old config docker exec rmesh-reticulum cp /app/config/reticulum.conf /data/reticulum/config then restart