Embedded Systems / Off-Grid Communications / LoRa Mesh Networking

Haywards Hub

Haywards Hub is a sophisticated off-grid, long-range communications device built on the LilyGO T-Deck Plus — a compact all-in-one device featuring ...

Haywards Hub

Category: Embedded Systems / Off-Grid Communications / LoRa Mesh Networking
Platform: LilyGO T-Deck Plus (ESP32-S3FN16R8 — 16MB Flash, 8MB OPI PSRAM)
Framework: Arduino via PlatformIO | C++
Region: AU915 (Australian 915 MHz LoRa band)
Status: Active Development — v1.0.0 (Build 2026-07)


Project Overview

Haywards Hub is a sophisticated off-grid, long-range communications device built on the LilyGO T-Deck Plus — a compact all-in-one device featuring a physical QWERTY keyboard, colour TFT touchscreen, LoRa radio module, GPS receiver, and battery management.

The firmware implements a complete Reticulum Network Stack (RNS) node using the microReticulum library, enabling encrypted, infrastructure-independent mesh communications over LoRa radio waves. The system implements the LXMF (Lightweight Extensible Message Format) protocol for message addressing and delivery, making it interoperable with the broader Reticulum ecosystem including the Nomad Network and Sideband applications.

Haywards Hub is designed for scenarios where conventional internet infrastructure is unavailable or undesirable: remote areas, off-grid homesteads, emergency communications, privacy-conscious deployments, or simply for decentralised mesh networking enthusiasts.


Core Systems

Hardware Abstraction Layer (HardwareManager)

Manages and initialises all physical peripherals on the T-Deck Plus:

Peripheral Interface Notes
LoRa Radio SPI (HSPI / SPI3) RadioLib-managed SX127x/SX126x module
GPS Receiver UART TinyGPS+ parser for position/time
Battery ADC GPIO LiPo voltage sensing and percentage
Physical Keyboard I2C T-Deck Plus built-in QWERTY keypad
Display SPI (FSPI / SPI2) LovyanGFX-driven 320x240 TFT
Touchscreen I2C CST816 capacitive touch controller

Critical: GPIO10 (BOARD_POWERON) must be pulled HIGH before any SPI/I2C initialisation — this pin controls the power latch for ALL peripherals simultaneously.

Network Layer (NetworkManager)

Built on microReticulum and implementing the full Reticulum Network Stack:

  • Transport: LoRa radio via RadioLib (AU915 regional configuration)
  • Addressing: Reticulum cryptographic addresses (truncated SHA-256 of public key)
  • Protocol: LXMF (Lightweight Extensible Message Format) for message framing
  • Persistence: LittleFS via RNSFileSystem adapter — stores node identity, routing tables, and message history across reboots
  • Callback Architecture: Incoming LXMF messages trigger onIncomingLXMFMessage() in main, which routes to the UIManager for live display updates

UI Layer (UIManager — LovyanGFX + LVGL 8.3.x)

A fully featured, tabbed graphical interface rendered via LVGL:

Tab Purpose
Home (TabHome) Node status, signal strength, GPS position, battery level
Messages (TabMessages) Inbox, compose, and send LXMF messages
Contacts (TabContacts) Address book with Reticulum hash management
Network (TabNetwork) Discovered peers, routing table, link quality indicators
Settings (TabSettings) Radio config, display brightness, power management

Additional UI components:

  • StatusBar — persistent top bar showing time, battery, GPS fix status, LoRa signal
  • InputDriver — keyboard and touch event dispatcher
  • NVSStore — non-volatile settings persistence (NVS partition)
  • Theme — custom LVGL dark theme with colour palette and font definitions

Architecture Highlights

Layered Initialisation Sequence

1. GPIO10 HIGH           → Power all peripherals
2. Serial (USB-CDC)      → Diagnostics and debug output
3. HardwareManager::init → LoRa SPI + GPS UART + keyboard I2C + battery ADC
4. NetworkManager::init  → Mount LittleFS + start Reticulum + LXMF announce
5. UIManager::init       → LovyanGFX display + LVGL + tab widgets
6. Main loop             → hw.update + net.update + ui.update @ ~200Hz

Non-Fatal Hardware Failures

  • HardwareManager gracefully reports partial failures (e.g., keyboard not detected) but does not halt boot
  • Only display init failure is treated as fatal (device halts cleanly into deep sleep rather than entering a watchdog reset loop)

LXMF Message Routing

  1. RadioLib receives LoRa packet
  2. microReticulum decodes the Reticulum transport layer
  3. LXMF delivery handler fires the onIncomingLXMFMessage callback
  4. UIManager receives (sender_hash, messageText) and pushes to TabMessages
  5. LVGL re-renders the messages tab with the new entry

Technical Stack

Component Library / Version
Reticulum Network Stack attermann/microReticulum v0.4.0
LoRa Radio Driver jgromes/RadioLib v6.6.0
Display Graphics lovyan03/LovyanGFX v1.1.12
UI Framework lvgl/lvgl v8.3.11
GPS Parsing mikalhart/TinyGPSPlus v1.0.3
JSON bblanchon/ArduinoJson v7.0.4
Cryptography rweather/Crypto v0.4.0
QR Code Generation ricmoo/QRCode v0.0.1
Time paulstoffregen/Time v1.6.1
Build System PlatformIO (espressif32 platform)

Key Design Decisions

LoRa Region — AU915

  • Configured for the Australian 915 MHz ISM band (AU915 in LoRaWAN terminology)
  • Uses the RadioLib AU915 channel plan
  • Compliant with Australian Communications and Media Authority (ACMA) regulations for 915 MHz ISM band usage

PSRAM Stack Expansion

  • Default Arduino loop task stack (8KB) is insufficient for LVGL's deep call chain
  • Stack overflow caused _DoubleExceptionVector → TG1WDT reset (black screen boot loop)
  • Resolution: ARDUINO_LOOP_STACK_SIZE=32768 (32KB stack via build flag)

Dual SPI Bus Management

  • LoRa radio uses HSPI (SPI3) — claimed by HardwareManager first
  • Display uses FSPI (SPI2) — claimed by UIManager second
  • Initialisation order is critical to prevent bus contention

LittleFS Double-Mount Prevention

  • LittleFS is mounted exclusively inside NetworkManager via the RNSFileSystem adapter
  • Main setup() explicitly does NOT call LittleFS.begin() — double-mount causes a boot panic

Hardware Specifications (T-Deck Plus)

Spec Detail
MCU ESP32-S3FN16R8
Flash 16MB (QIO)
PSRAM 8MB OPI
Display 320x240 colour TFT
Input Physical QWERTY keyboard + capacitive touchscreen
Radio LoRa module (SX-series)
GPS UART GPS module
Battery LiPo with onboard charging
Connectivity WiFi, Bluetooth, LoRa
Build PlatformIO esp32-s3-devkitc-1 board profile

Use Cases

  • Off-grid text messaging in remote areas (bushfire response, hiking, rural properties)
  • Decentralised, censorship-resistant private communications
  • Emergency mesh network node
  • Reticulum network infrastructure — relay/transport node for the broader mesh
  • Privacy-focused communications where no internet infrastructure is desired
  • Amateur radio digital messaging (LoRa mesh)
Return to Projects