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)
  • 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

Leave a Reply

Your email address will not be published. Required fields are marked *.

*
*

About This Site

This site double as a portfolio and a place to help people.

Mostly just helping people with articles and services