ESP32 E-Paper Meshtastic Dashboard (LilyGo T5 4.7”)
For this project, I designed and built a roomy, glanceable dashboard for the LilyGo T5 4.7″ E-Paper board (ESP32 + EPD47). The goal was to create a low-power, always-available status display that pulls live telemetry from a MeshStatic device, persists historical data across reboots, and renders it in a clean and minimal interface.
Motivation
Mesh networks are powerful, but they’re often difficult to monitor at a glance. I wanted a solution that could run passively, without needing a laptop or phone app, while still being readable in bright light and power efficient enough for long-term deployment.
The LilyGo T5 4.7″ board was a perfect fit:
- Large 960×540 grayscale E-Ink panel
- On-board ESP32 with PSRAM
- Good community support and an open driver library
Features
- Realtime telemetry via HTTP JSON
Polls a configurable endpoint (default:http://192.168.0.160/json/report
) to display system, radio, memory, and power stats. - Historical data persistence
Uses SPIFFS as a ring buffer to log ~4 days of samples at 30-minute intervals. Data survives reboots and is displayed as mini-graphs. - Two historical graphs
- Channel Utilization % (0–100)
- Wi-Fi RSSI (auto-scaling)
- Optimized for E-Paper
Careful use of margins and header fills avoids the common “black line” artifacts at the top row of the EPD47. Layout emphasizes clarity and spacing for at-a-glance reading.
Technical Implementation
- Board: LilyGo T5 4.7” E-Paper (ESP32, PSRAM, grayscale 4-bpp)
- Core stack: ESP32 Arduino Core (2.0.15+)
- Libraries:
- LilyGo-EPD47 driver (
epd_driver.h
) - ArduinoJson v7+
- WiFi / HTTPClient / FS / SPIFFS (ESP32 core)
- LilyGo-EPD47 driver (
- File handling:
On first boot, SPIFFS is formatted automatically and a fixed-size history file (/hist.dat
) is created. Samples are appended as a circular buffer for durability. - Update interval:
Default is every 30 minutes, adjustable with:static const uint32_t REFRESH_MS = 30UL * 60UL * 1000UL;
- History capacity:
static const uint16_t HIST_CAP = 192; // ≈ 4 days @ 30 min
Screens & Layout
The dashboard is structured with:
- Top Header Bar (system info, reboot counter)
- System & Memory Panels
- Radio / Power / Wi-Fi Panels
- Graphs (Channel Utilization, Wi-Fi RSSI)
The design makes generous use of whitespace, gutters, and section spacing for readability. Fonts are OpenSans bold variants (8–24pt), included as headers for consistency across toolchains.
Challenges Solved
- E-Paper quirks: Mitigated the infamous top scanline rendering bug by offsetting header rendering away from row 0.
- Efficient persistence: Implemented a fixed-size ring buffer in SPIFFS to avoid wear and corruption, ensuring smooth historical graphing.
- Auto-scaling metrics: Wi-Fi RSSI values are dynamically scaled, keeping the graph informative regardless of signal range.
Roadmap
Future improvements I’d like to explore:
- Optional battery % graph alongside utilization and RSSI
- On-device settings menu for changing refresh intervals or toggling graphs
- Support for partial refreshes to reduce redraw time and ghosting
- Exporting historical data as CSV or PNG over Wi-Fi for deeper analysis
Outcome
This project demonstrates my ability to:
- Work directly with embedded hardware (ESP32 + E-Ink)
- Integrate network APIs (JSON over HTTP)
- Implement data persistence on constrained systems (SPIFFS ring buffer)
- Design user-centric UIs optimized for clarity on a unique medium
You can explore the source code and documentation on GitHub:
👉 ESP32 E-Paper MeshStatic Dashboard