LilyGO T3-S3 v1.2 / v1.3
t3s3- MCU
- ESP32-S3FH4R2 — 4 MB flash, 2 MB PSRAM
- Radio
- SX1276/78 or SX1262 — detected at boot
- Panel
- 0.96″ SSD1306 (I²C)
- Extras
- microSD, battery ADC, native USB
RetiMesh Node turns a $30 ESP32 + LoRa board into a standalone Reticulum transport node. It routes for every peer around it over LoRa while your phone talks to it over ordinary Wi‑Fi — no host computer, no internet, no accounts, nothing to type.
rnsd does with
enable_transport = yes.
Reticulum is a cryptography-first networking stack that runs over anything — LoRa, packet radio, TCP, a serial cable. RetiMesh Node is that stack, embedded in firmware, on a board you can hang off a battery and forget about.
The firmware embeds microReticulum, a C++ port of RNS, with transport enabled: a live path table, announce propagation with hop counts, path requests answered from its own table, packets forwarded hop by hop. No companion computer anywhere in the picture.
Packets cross between Wi‑Fi and LoRa unmodified in both directions. The node holds no keys belonging to anyone else and reads nothing it carries — end-to-end encryption stays strictly between the Reticulum peers, with their own identities.
The LoRa wire format — one header byte, ≤255-byte frames, two-fragment packets up to the 500-byte RNS MTU — is byte-identical to RNode_Firmware. Real RNodes on the same channel parameters simply work with it. Nothing proprietary goes on the air.
rnsd’s vocabulary and their own
admin API; off-grid and emergency users who need local messaging with no infrastructure; and
tinkerers who want a documented codebase, a board registry and a web flasher for their own hardware.
Radio timing is never blocked by web or Wi‑Fi work. The two halves of the node talk through FreeRTOS ring buffers that drop on overflow rather than block — because a stalled radio task is worse than a lost packet, and Reticulum links tolerate loss.
Task layout
| Core | Runs | Why there |
|---|---|---|
| Core 0 | Wi‑Fi / LwIP stack, the single AsyncTCP event task (sockets for ports 80 and 4242), captive-portal DNS poller | Networking is bursty and interrupt-heavy; it gets its own core |
| Core 1 | radioTask (transceiver IRQ service, CSMA, RNode framing) and bridgeTask (LoRa → TCP fan-out) |
LoRa timing is hard real time; nothing web-facing may pre-empt it |
| Between | Two ring buffers (RINGBUF_TYPE_NOSPLIT) — one item is one RNS packet |
Lock-free hand-off; both directions drop rather than stall |
Ways a host reaches the node
| Port | Protocol | Purpose |
|---|---|---|
| — | Wi‑Fi SoftAP retimesh-XXXXXX, 10.42.0.1/24 | Open network with captive-portal DNS; or join an existing LAN in station mode |
| 80 | HTTP | Status page, neighbour list, message log, public bulletin board, admin settings, retimesh.local |
| 4242 | Raw TCP, RNS HDLC framing | Reticulum transport — connect any stock RNS client |
| — | RNS AutoInterface (IPv6 link-local) | Zero-config discovery — Sideband’s Local/LAN finds the node by itself |
| 115200 | USB serial | The log, and a maintenance console (VERSION, STATUS, LINKS, MESSAGES…) |
| 4243 | TCP | The same console over the network |
| 10.64.n.1 | USB CDC-NCM (native-USB boards) | The node is an Ethernet link with DHCP — the whole web app and API over the cable, no Wi‑Fi |
| 10.65.n.1 | PPP over the serial bridge | Same again through pppd on CP2102 / CH9102 boards |
Client side — the whole configuration
# ~/.reticulum/config — or, in Sideband, just add a TCP Client Interface.
# With Local/LAN discovery on (the default) even this is unnecessary.
[[RetiMesh Gateway]]
type = TCPClientInterface
enabled = yes
target_host = 10.42.0.1
target_port = 4242
Each connected client gets its own RNS interface on the node, with its own mode.
Radio parameters must match every node on the channel — frequency, bandwidth,
spreading factor, coding rate and sync word — and are changed live on the settings page,
which prints the matching RNodeInterface block for you.
The whole product is on the board. There is no companion app, no service to sign up to and nothing that stops working when the internet does.
An RNS AutoInterface does IPv6 link-local discovery on the Wi‑Fi. Sideband’s Local/LAN connectivity finds the node within seconds of joining — no host, no port, nothing typed.
Radio model and channel, RSSI/SNR, transport interfaces, the live path table, neighbours, and QR codes for Wi‑Fi join, portal URL and node address. Your OS pops it up on join.
Announces heard from either side are parsed and signature-verified, then listed with aspect, hop count, display name and signal. LXMF peers get a Message in Sideband hand-off and an address copy button.
full, gateway, access_point, roaming,
boundary — set separately for the LoRa channel, the TCP clients and the
discovered peers, because those are three different policies.
The last 50 LXMF messages the node itself was sent, newest first: whether the sender could be verified, how it arrived and what it said. “Did that get through?” has an answer on the node, not just in the sender’s client.
Deliberately plaintext and local to the node — anyone on its Wi‑Fi can post and read, no identity needed. 50 posts, rotated oldest-first.
Radio channel applied without a reboot, Wi‑Fi security and SSID, transport modes, announce interval, admin password, factory reset. Everything in NVS, behind a password you are told to change on first use.
Point the node at your existing Wi‑Fi and it becomes a LoRa uplink for the whole LAN — every Reticulum client on the network reaches it by address or by discovery.
On native-USB boards the node is a composite device: a console and a CDC-NCM Ethernet link
with DHCP. On bridge boards, pppd gives you the same over the serial cable. The full
web app and API, no Wi‑Fi involved.
VERSION, STATUS, LINKS, MESSAGES,
WIFI ON, RESET CONFIRM, BOOTLOADER CONFIRM — over
USB serial or TCP 4243. The node can even hand its own bootloader over, so reflashing needs no
BOOT button.
/api/status, /api/board, /api/settings/*,
/api/system/* — identity and destination hashes, radio stats, neighbours,
paths. Fleet provisioning and monitoring are a curl away.
X25519 + Ed25519 keys in NVS, kept across a factory reset — the node keeps its address. The path table and announce cache live in a microStore on the SD card when one is present, internal flash otherwise.
Optional RM1 probes broadcast to the PLAIN destination retimesh.beacon
— valid RNS packets other clients silently drop, and any Python RNS script can listen to.
RNode station callsigns show up as neighbours too.
SSD1306 OLED status pages with neighbour counts and QR codes; a driven 2.13″ e-ink panel on the Wireless Paper; front LEDs on the headless Wireless Bridge. Absent panels compile out entirely.
RetiMesh Node is not competing with the Reticulum ecosystem — it fills the one gap in it: a node that is both the radio and the router, with nothing plugged into it.
| RNode firmware | Meshtastic | MeshChat | RetiMesh Node | |
|---|---|---|---|---|
| Role | Radio modem for a host RNS | Own protocol, own apps | Web client for RNS | Standalone RNS transport node + gateway |
| Needs a host computer | yes | no | yes | no |
| Reticulum-native | yes — via a host | no | yes | yes — embedded RNS |
| Phone onboarding | rnsd + Sideband config | vendor app | browser | join the Wi‑Fi, done |
| RF interop with RNode | — | no | — | yes — byte-compatible |
Interoperability is the point, not a feature: put an RNode and a RetiMesh Node on the same frequency, bandwidth, spreading factor, coding rate and sync word, and they are on the same mesh.
One boards.json registry drives the builds, the release packaging, the flasher and the
CLI — so every board here is built by CI on every commit. Where the transceiver can be told
apart at runtime it is detected at boot, and a single image covers both variants.
PIN_LORA_* build flags to match your wiring[env:…] in platformio.ini, a pin map in
src/boards/<name>.h, and an entry in boards.json — CI, the release
packaging, this flasher and the CLI all pick it up from there. Ports in progress include the T-Beam S3
Supreme, RAK WisBlock 4631, Xiao ESP32S3 + Wio-SX1262 and LR1121 variants.
Firmware comes straight from the latest GitHub release. Chrome or Edge on a desktop, a USB cable, about ninety seconds. No toolchain, no account, nothing to install.
▲ Could not reach the firmware index. Use the hosted flasher or the CLI below.
Tick Erase device on a first install so the filesystem and settings start clean. Everything is fetched over HTTPS and verified against the release’s published SHA-256 sums.
Then
admin / retimesh.Terminal — Linux, macOS, Windows
pipx run --spec "git+https://github.com/dobrevit/RetiMesh_Node#subdirectory=tools/retimesh-flash" retimesh-flash install
Lists boards, auto-detects the port, verifies checksums and flashes with esptool.
--mode app keeps your settings; --mode fs updates only the web app.
Manual — esptool
pip install esptool esptool.py --chip esp32s3 --baud 921600 \ write_flash --erase-all 0x0 retimesh-node-<version>-<board>-merged.bin
Every release ships a merged image per board plus a zip of the individual partitions;
offsets and SHA-256 hashes are in that release’s release.json.
RetiMesh Node is free software, released in full under the GNU General Public License v3 or later. Every line that runs on the board is published, and if you distribute or modify it you must pass those freedoms on: provide the corresponding source, keep the copyright and licence notices, and tell your users what rights they have.
Copyright © 2026 Dobrev IT Ltd. Third-party components keep their own licences — microReticulum and microStore (Apache-2.0/MIT), RadioLib, ArduinoJson, MsgPack (MIT), Adafruit GFX/SSD1306/BusIO (BSD/MIT), ESPAsyncWebServer and AsyncTCP (LGPL-3.0). The LoRa wire format is implemented for interoperability with RNode_Firmware; no RNode source is included.
This is a pre-1.0 project on 0.0.x releases, shipping fast and changing in the open. Things move: settings gain fields, APIs gain endpoints, boards get added, and a board marked builds only here has genuinely never been powered on. The status of every board is stated plainly rather than rounded up.
The published roadmap is equally blunt about targets and non-goals: 0.1 transport you can trust and soak-test, 0.2 zero-config, 0.3 real battery numbers, 0.4 more boards, 0.5 mesh services. No cloud accounts, no telemetry and no always-online dependency are on the list — ever.
Bug reports, board ports and interop results are all welcome, and CI builds every board on every commit so a pull request tells you immediately whether it fits.