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
- RadioLib receives LoRa packet
- microReticulum decodes the Reticulum transport layer
- LXMF delivery handler fires the
onIncomingLXMFMessagecallback - UIManager receives
(sender_hash, messageText)and pushes to TabMessages - 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)