Build a Round Touchscreen Smart Display with ESP32 and LVGL
Round touchscreen displays give a project a finished, product-like feel that a rectangular TFT can't match — think smartwatch faces, thermostat dials, or car infotainment dashboards. Pairing a round GC9A01 display with an ESP32 and the LVGL graphics library turns that look into something you can actually build: a wall-mounted smart display showing time, weather, and Home Assistant sensor data, with a proper touch-driven UI instead of a static readout. This project covers the hardware wiring, the LVGL project structure that makes a round-screen UI actually work well, and building out a working dashboard with multiple swipeable screens.
Why LVGL and Not a Simple Display Library
Basic Arduino display libraries like Adafruit_GFX are fine for drawing text and shapes, but they have no concept of a UI: no buttons, no touch handling, no screen transitions, no widget state. LVGL (Light and Versatile Graphics Library) is a full embedded GUI framework — it manages a widget tree, handles touch input events, does anti-aliased text rendering, and includes ready-made widgets (sliders, arcs, meters, tab views) that are exactly what a round display's circular real estate wants. The tradeoff is a steeper initial learning curve and a real RAM/flash budget to manage, which is where the ESP32's dual-core architecture and available PSRAM (on WROVER or S3 modules) matter — LVGL's frame buffer for a 240x240 round display easily eats into the ESP32's limited internal SRAM, so a module with PSRAM is worth the small price difference over a bare ESP32-WROOM for anything beyond a very simple UI.
Wiring the Display and Touch Controller
The GC9A01 round display uses SPI for its display data and typically shares the bus with a CST816 capacitive touch controller that talks I2C separately — so the wiring involves both an SPI bus (MOSI, SCLK, CS, DC, RST) for the screen and an I2C bus (SDA, SCL, plus interrupt and reset lines) for touch. Keep the SPI clock line short and, if possible, route it away from noisy digital lines on your protoboard — a round GC9A01 module run at the higher end of its SPI clock range (40MHz+) can show visible tearing or glitching artifacts if the wiring is long or poorly routed, which is easy to mistake for a software bug when it's actually signal integrity.
SignalDisplay (GC9A01)Touch (CST816) Power3.3V, GND3.3V, GND Data busSPI: MOSI, SCLK, CS, DCI2C: SDA, SCL ControlRST (reset)RST, INT (touch interrupt) BacklightPWM-capable GPIO (optional dimming)—Setting Up LVGL on the ESP32
Install LVGL through PlatformIO or the Arduino Library Manager, along with a display driver library (TFT_eSPI configured for GC9A01, or the newer LovyanGFX which has cleaner round-display support) to bridge LVGL's rendering calls to the actual SPI hardware. LVGL's configuration header (lv_conf.h) is where most first-time setup problems live — set the display resolution to match your panel exactly, enable the CST816 touch driver if you're not writing your own, and size the draw buffer deliberately: a full-frame buffer at 240x240x16-bit color is 115KB, which fits comfortably with PSRAM enabled but will not fit in a bare ESP32's internal SRAM alongside your WiFi stack and application code, forcing you to use a partial buffer (LVGL redraws in bands) if you're on a PSRAM-less module.
Designing a Round-Friendly UI
The biggest mistake in a first LVGL round-display project is designing a UI as if the screen were rectangular — text and controls placed near the corners of a bounding box get clipped by the physical circle, so lay out content within a safe circular inset, and lean on LVGL's arc and meter widgets, which are specifically designed to read naturally on a round face (a circular gauge or a radial progress arc looks native on this hardware in a way a rectangular progress bar never will). LVGL's tab view or a swipeable screen-stack pattern works well for a multi-function dashboard: a time/date face as the default screen, swipe left for weather, swipe right for Home Assistant sensor tiles, using LVGL's built-in gesture detection on the touch controller rather than building custom swipe logic from raw touch coordinates.
Pulling in Live Data
Connect the ESP32 to WiFi and pull weather from a REST API (or better, subscribe to Home Assistant's data over MQTT if you're already running Home Assistant, which keeps the display in sync with your existing smart home sensors without a separate cloud dependency) and update LVGL widget values from your data-fetch callback rather than redrawing the whole screen — LVGL's widget model means changing a label's text or a meter's needle value only repaints that widget, which keeps the UI responsive even while a network request is in flight in the background on the ESP32's second core.
Safety
This is a low-voltage build with no significant electrical hazard, but if you're mounting the finished display in a 3D printed or laser-cut wall enclosure, make sure the ESP32's USB power adapter and any exposed wiring are fully enclosed and strain-relieved — a wall-mounted device that gets bumped or bears weight on a dangling cable is a common failure point that has nothing to do with the electronics themselves.
Once the display side is working, this project scales naturally: add more Home Assistant entities as swipeable tiles, wire a rotary encoder for a physical volume-style control alongside the touchscreen, or drop the whole assembly into a 3D printed bezel that turns it into a genuinely finished smart home fixture rather than a bare dev board on a desk.
Related Guides
- Build a Wall-Mounted Dashboard with the ESP32 Cheap Yellow Display (CYD)
- Build a Wall-Mounted Maker Dashboard: Aggregating Your Print Farm, Security, and Home Server on One CYD Panel
- DIY Home Security System: Combining Raspberry Pi, ESP32 Sensors, and Flipper Zero
- ESPHome and Home Assistant Beginner Guide: Build Your First WiFi Sensor
- Build a Home Energy Monitor with ESP32 and CT Clamps: Whole-House Power Tracking in Home Assistant
- M5Stack Core2
- How to Program Addressable LED Strips: WS2812B Patterns, Effects, and Power Design
- I2C vs SPI vs UART: How to Choose and Use Serial Communication Protocols