Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home IoT & Smart Home

ESP32 LVGL Display: Build a Rich UI on Cheap TFT Screen

ESP32 LVGL Display: Build a Rich UI on Cheap TFT Screen

March 11, 2026 /Posted byJayesh Jain / 0

Forget bland serial monitor outputs and simple seven-segment displays. With ESP32 LVGL display UI development, you can build professional-looking touchscreen interfaces that rival smartphone apps — all running on a microcontroller that costs less than ₹400. LVGL (Light and Versatile Graphics Library) is the most popular open-source embedded GUI library in the world, and pairing it with an ESP32 and a cheap TFT screen opens up incredible possibilities for IoT dashboards, smart appliance controls, and industrial HMI panels.

Table of Contents

  1. What Is LVGL and Why Use It on ESP32?
  2. Choosing Your Display Hardware
  3. Setting Up LVGL with Arduino and PlatformIO
  4. Building Your First LVGL UI
  5. Working with LVGL Widgets and Themes
  6. Performance Optimization for Smooth Rendering
  7. Frequently Asked Questions

What Is LVGL and Why Use It on ESP32?

LVGL (formerly known as LittlevGL) is a free and open-source graphics library written in C, specifically designed for embedded systems with limited resources. Unlike desktop GUI frameworks that require gigabytes of RAM and powerful CPUs, LVGL is engineered to run on microcontrollers with as little as 64KB RAM and an 8MHz clock.

Key advantages of LVGL for ESP32 projects:

  • Rich widget library: Buttons, sliders, charts, tabviews, keyboards, gauges, lists, and over 30 other widget types
  • Smooth animations: Built-in animation engine with easing functions for professional-looking transitions
  • Touch support: Built-in resistive and capacitive touch handling with gesture recognition
  • Themes: Pre-built Material and LVGL default themes with customizable colors and fonts
  • Multilingual: Full Unicode support with custom fonts — crucial for Indian languages
  • Active community: Huge global community, excellent documentation at docs.lvgl.io

For Indian makers and startups building IoT products, LVGL enables you to create polished displays for smart meters, medical monitoring devices, agricultural automation panels, and home automation controllers — without hiring a software UI developer.

Choosing Your Display Hardware

LVGL requires a display controller that supports reading/writing pixels. The most common options for ESP32 projects in the Indian market are:

SPI TFT Displays (Budget Option)

ILI9341 (240×320) and ST7789 (240×240, 240×320) based displays connected via SPI are the most affordable entry point. A 2.4 inch ILI9341 with resistive touch costs around ₹250-400 in India. SPI is slower than parallel interfaces (max ~40MHz on ESP32 = ~15-20 fps for full-screen redraws), but perfectly adequate for most UI projects with LVGL’s partial update system.

ESP32-S3 with Built-in Display (Recommended)

Several ESP32-S3 development boards now come with displays built in. These are the best option for new projects as they eliminate wiring complexity and often use faster QSPI or parallel RGB interfaces.

Waveshare ESP32-S3 1.43inch AMOLED Display

Waveshare ESP32-S3 1.43inch AMOLED Display Board, 466×466, QSPI Interface

A premium ESP32-S3 board with a stunning 466×466 round AMOLED display — perfect for circular LVGL gauge and clock UIs. QSPI interface delivers smooth animations at high refresh rates.

View on Zbotic

Waveshare ESP32-S3 Round Display

Waveshare ESP32-S3 1.46inch Round Display, 412×412, WiFi+BT, Accelerometer, Speaker and Mic

All-in-one ESP32-S3 with a round display, IMU sensor, speaker, and microphone. Build LVGL UIs enhanced with motion sensing and audio feedback — ideal for wearable and smart home displays.

View on Zbotic

Setting Up LVGL with Arduino and PlatformIO

The most common way to use LVGL on ESP32 with Arduino is via the lvgl Arduino library combined with the TFT_eSPI or Arduino_GFX display driver.

PlatformIO Setup (Recommended)

In your platformio.ini:

[env:esp32s3]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino

lib_deps =
    lvgl/lvgl @ ^9.2.0
    bodmer/TFT_eSPI @ ^2.5.43

build_flags =
    -DBOARD_HAS_PSRAM
    -DLVGL_CONF_INCLUDE_SIMPLE
    -DLV_CONF_PATH="${PROJECT_DIR}/src/lv_conf.h"

lv_conf.h Key Settings

Copy lv_conf_template.h from the LVGL library to your src/ folder as lv_conf.h and configure these critical settings:

// Enable LVGL
#define LV_USE_STDLIB_MALLOC  LV_STDLIB_BUILTIN

// Color depth - must match your display
#define LV_COLOR_DEPTH  16  // RGB565 for most TFT displays

// Draw buffer size - increase for smoother rendering
// For 320x240: set to 320*40 (40 lines at once)
#define LV_DEF_REFR_PERIOD  10  // Screen refresh period in ms (10ms = 100fps max)

// Enable features you need
#define LV_USE_LABEL     1
#define LV_USE_BTN       1
#define LV_USE_SLIDER    1
#define LV_USE_CHART     1
#define LV_USE_TABVIEW   1
#define LV_USE_ARC       1
#define LV_USE_SPINNER   1
#define LV_USE_MSGBOX    1

// Font settings
#define LV_FONT_MONTSERRAT_14  1
#define LV_FONT_MONTSERRAT_20  1
#define LV_FONT_MONTSERRAT_28  1

// Theme
#define LV_USE_THEME_DEFAULT  1

Initializing LVGL in main.cpp

#include <lvgl.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();

// LVGL draw buffer — allocate in PSRAM for large displays!
static lv_display_t* display;
static lv_color_t* buf1;
static lv_color_t* buf2;

// LVGL flush callback — called when LVGL has pixels to send to display
void lvgl_flush_cb(lv_display_t* disp, const lv_area_t* area, uint8_t* px_map) {
  uint32_t w = area->x2 - area->x1 + 1;
  uint32_t h = area->y2 - area->y1 + 1;
  
  tft.startWrite();
  tft.setAddrWindow(area->x1, area->y1, w, h);
  tft.pushColors((uint16_t*) px_map, w * h, true);
  tft.endWrite();
  
  lv_display_flush_ready(disp);
}

void setup() {
  // Init display
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  
  // Init LVGL
  lv_init();
  
  // Allocate draw buffers in PSRAM
  size_t buf_size = TFT_WIDTH * 40 * sizeof(lv_color_t);
  buf1 = (lv_color_t*) ps_malloc(buf_size);
  buf2 = (lv_color_t*) ps_malloc(buf_size);
  
  // Create display
  display = lv_display_create(TFT_WIDTH, TFT_HEIGHT);
  lv_display_set_flush_cb(display, lvgl_flush_cb);
  lv_display_set_buffers(display, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
  
  // Create your UI
  create_dashboard_ui();
}

void loop() {
  lv_timer_handler();  // MUST call this in loop for LVGL to work!
  delay(5);
}

Building Your First LVGL UI

Let us build a practical IoT dashboard showing temperature, humidity, and a chart of historical values:

void create_dashboard_ui() {
  // Apply Material dark theme
  lv_theme_t* theme = lv_theme_default_init(display,
    lv_palette_main(LV_PALETTE_BLUE),
    lv_palette_main(LV_PALETTE_RED),
    true,  // dark mode
    LV_FONT_DEFAULT
  );
  lv_display_set_theme(display, theme);
  
  lv_obj_t* scr = lv_screen_active();
  lv_obj_set_style_bg_color(scr, lv_color_hex(0x1a1a2e), 0);
  
  // Title label
  lv_obj_t* title = lv_label_create(scr);
  lv_label_set_text(title, "Weather Station");
  lv_obj_set_style_text_font(title, &lv_font_montserrat_20, 0);
  lv_obj_set_style_text_color(title, lv_color_hex(0x4CC9F0), 0);
  lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 10);
  
  // Temperature arc gauge
  lv_obj_t* temp_arc = lv_arc_create(scr);
  lv_arc_set_range(temp_arc, -10, 60);
  lv_arc_set_value(temp_arc, 28);  // Update dynamically in loop
  lv_obj_set_size(temp_arc, 100, 100);
  lv_obj_align(temp_arc, LV_ALIGN_LEFT_MID, 10, 0);
  
  // Temperature label inside arc
  lv_obj_t* temp_label = lv_label_create(scr);
  lv_label_set_text(temp_label, "28°C");
  lv_obj_align_to(temp_label, temp_arc, LV_ALIGN_CENTER, 0, 0);
  
  // Humidity bar
  lv_obj_t* hum_bar = lv_bar_create(scr);
  lv_bar_set_range(hum_bar, 0, 100);
  lv_bar_set_value(hum_bar, 65, LV_ANIM_ON);
  lv_obj_set_size(hum_bar, 120, 20);
  lv_obj_align(hum_bar, LV_ALIGN_RIGHT_MID, -10, -20);
  
  // Historical temperature chart
  lv_obj_t* chart = lv_chart_create(scr);
  lv_chart_set_type(chart, LV_CHART_TYPE_LINE);
  lv_chart_set_point_count(chart, 24);  // 24 hours
  lv_obj_set_size(chart, 300, 80);
  lv_obj_align(chart, LV_ALIGN_BOTTOM_MID, 0, -10);
  
  lv_chart_series_t* temp_series = lv_chart_add_series(
    chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y
  );
  
  // Populate with dummy historical data
  for (int i = 0; i < 24; i++) {
    lv_chart_set_next_value(chart, temp_series, 25 + (i % 5) - 2);
  }
}

Working with LVGL Widgets and Themes

LVGL v9 offers an expanded widget set. Here are the most useful widgets for IoT dashboard projects:

Tabview — Multi-Screen Navigation

lv_obj_t* tabview = lv_tabview_create(lv_screen_active());
lv_tabview_set_tab_bar_position(tabview, LV_DIR_BOTTOM);
lv_tabview_set_tab_bar_size(tabview, 45);

lv_obj_t* tab_home = lv_tabview_add_tab(tabview, LV_SYMBOL_HOME " Home");
lv_obj_t* tab_sensors = lv_tabview_add_tab(tabview, LV_SYMBOL_SETTINGS " Sensors");
lv_obj_t* tab_alerts = lv_tabview_add_tab(tabview, LV_SYMBOL_WARNING " Alerts");

// Build content for each tab independently
build_home_tab(tab_home);
build_sensors_tab(tab_sensors);
build_alerts_tab(tab_alerts);

Custom Styles

// Create a styled card container
lv_obj_t* card = lv_obj_create(parent);
lv_obj_set_size(card, 150, 100);
lv_obj_set_style_bg_color(card, lv_color_hex(0x16213E), 0);
lv_obj_set_style_border_color(card, lv_color_hex(0x4CC9F0), 0);
lv_obj_set_style_border_width(card, 2, 0);
lv_obj_set_style_radius(card, 12, 0);
lv_obj_set_style_shadow_width(card, 20, 0);
lv_obj_set_style_shadow_color(card, lv_color_hex(0x4CC9F0), 0);

Performance Optimization for Smooth Rendering

Getting smooth LVGL animations on ESP32 requires attention to several factors:

1. Use PSRAM for Buffers

For displays larger than 240×240, allocating LVGL draw buffers in PSRAM is essential. Two buffers (double buffering) allows LVGL to render one buffer while the other is being sent to the display via DMA, eliminating rendering stalls.

2. DMA Transfers

TFT_eSPI supports DMA transfers on ESP32. Enable with tft.initDMA() and use tft.pushImageDMA() in your flush callback. DMA frees the CPU during pixel transfer, letting LVGL calculate the next frame simultaneously.

3. Task Pinning

In FreeRTOS, pin the LVGL task to Core 1 and keep network tasks on Core 0. This prevents network operations from interrupting LVGL rendering and causing frame drops:

void lvgl_task(void* param) {
  while (true) {
    lv_timer_handler();
    vTaskDelay(pdMS_TO_TICKS(5));
  }
}

void setup() {
  // ... init code ...
  xTaskCreatePinnedToCore(lvgl_task, "lvgl", 8192, NULL, 2, NULL, 1); // Core 1
  xTaskCreatePinnedToCore(network_task, "net", 8192, NULL, 1, NULL, 0); // Core 0
}

4. Limit Animated Widgets

Every animated widget (spinner, animated chart) triggers a screen redraw cycle. On SPI displays, keep simultaneous animations below 3-4. On faster displays (QSPI AMOLED), you can animate freely.

Waveshare ESP32-S3 1.47inch LCD Display

Waveshare ESP32-S3 1.47inch 172×320 LCD Display Development Board with 262K Colors

A compact ESP32-S3 display board with 262K color LCD — great starting point for LVGL projects. The built-in display eliminates wiring hassle and the ESP32-S3 provides enough processing power for fluid animations.

View on Zbotic

Waveshare ESP32-C3 Round Display

Waveshare ESP32-C3 0.71inch Round Display Development Board, ESP32-C3 Single-core Processor

A tiny round display on ESP32-C3 — affordable entry point for LVGL experimentation. Perfect for wearable projects and IoT status indicators that need a small but visually rich display.

View on Zbotic

Frequently Asked Questions

Q: What is the minimum resolution display I need for LVGL to look good?

LVGL works on displays as small as 80×160 pixels, but 240×240 is really the sweet spot for usable UIs with readable text. For dashboards with multiple data cards and charts, 320×240 (2.4″) or 320×480 (3.5″) is recommended. The round AMOLED displays at 466×466 from Waveshare look exceptionally sharp with LVGL.

Q: Can I use LVGL without a touchscreen?

Absolutely. LVGL supports multiple input devices including physical buttons, encoders (rotary knobs), and even keyboard input. You can navigate LVGL UIs entirely with a rotary encoder, which is a common approach for industrial panels where touchscreens are impractical due to gloved use or harsh environments.

Q: How much RAM does LVGL require on ESP32?

LVGL itself needs about 8-16KB for its internal state and object tree. The main memory consumer is the draw buffer. For a 320×240 display with 16-bit color, a single 40-line buffer requires 320 × 40 × 2 = 25.6KB. For double buffering (recommended), that is 51.2KB. On standard ESP32 with 320KB usable DRAM, this is tight. Use PSRAM buffers whenever possible.

Q: Is LVGL suitable for commercial products sold in India?

Yes. LVGL is released under the MIT licence, which allows commercial use without royalties or licence fees. You only need to keep the copyright notice. Many Indian startups building smart meters, POS systems, and agricultural devices already use LVGL commercially.

Q: How do I display Hindi text in LVGL?

LVGL supports Unicode fonts. Use the LVGL online font converter (lvgl.io/tools/fontconverter) to generate a C array font file from a Devanagari font (like Noto Sans Devanagari). Include the generated font in your project and set it as the label font. Note that right-to-left and complex script shaping for languages like Arabic require the LVGL BiDi feature to be enabled in lv_conf.h.

Start Your LVGL Display Project Today
Explore our range of ESP32 display boards and development kits at Zbotic’s IoT category. From bare ESP32 modules to complete ESP32-S3 display boards, we have everything you need shipped fast across India.
Tags: Embedded GUI, ESP32, LVGL, TFT display, UI Design
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
ESP32 Interrupt-Driven UART: H...
blog esp32 interrupt driven uart high speed serial communication 595470
blog wemos d1 mini compact esp8266 board project guide 595475
WEMOS D1 Mini: Compact ESP8266...

Related posts

Svg%3E
Read more

IoT Home Insurance Sensor Kit: Leak, Smoke, and Motion

April 1, 2026 0
Table of Contents IoT and Home Insurance Water Leak Detection Smoke and Fire Detection Motion and Intrusion Sensing Building the... Continue reading
Svg%3E
Read more

IoT Pet Tracker: GPS Collar with Geofencing Alerts

April 1, 2026 0
Table of Contents Introduction and Overview Hardware Components Required GPS Module Integration with ESP32 Cloud Platform Setup Real-Time Tracking Dashboard... Continue reading
Svg%3E
Read more

IoT Aquaponics Controller: Fish and Plant Automation

April 1, 2026 0
Table of Contents The Water Monitoring Challenge in India Sensor Technologies for Water Building the Sensor Node Data Transmission and... Continue reading
Svg%3E
Read more

IoT Composting Monitor: Temperature and Moisture Tracking

April 1, 2026 0
Table of Contents Why Temperature Monitoring Matters Sensor Selection Guide Hardware Assembly and Wiring Firmware Development Cloud Data Logging Alert... Continue reading
Svg%3E
Read more

IoT Beehive Monitor: Weight, Temperature, and Humidity

April 1, 2026 0
Table of Contents Why Monitor Beehives Weight Measurement System Temperature and Humidity Sensing Building the Monitor Data Analysis for Bee... Continue reading

Add comment Cancel reply

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

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now