LVGL (Light and Versatile Graphics Library) is an open-source graphics library that brings smartphone-quality user interfaces to embedded displays. With LVGL on an ESP32, you can create beautiful touchscreen applications with buttons, sliders, charts, and animations — all running on a microcontroller costing under Rs.500. This guide walks you through the complete setup.
What Is LVGL and Why Use It
LVGL is the industry standard for embedded GUI development:
- 30+ built-in widgets: buttons, sliders, charts, tables, keyboards, spinners
- Smooth animations: 30 FPS on ESP32 with hardware-accelerated rendering
- Touch support: native integration with resistive and capacitive touchscreens
- Themes and styles: professional-looking UI with minimal code
- Memory efficient: runs in as little as 64 KB RAM
- MIT licence: free for personal and commercial use
Hardware Setup: TFT Display with ESP32
For this guide, we use an ILI9341-based 2.8-inch TFT with resistive touch (XPT2046):
| TFT Pin | ESP32 Pin | Function |
|---|---|---|
| VCC | 3.3V | Power |
| GND | GND | Ground |
| CS | GPIO15 | Chip select |
| RESET | GPIO4 | Display reset |
| DC | GPIO2 | Data/Command |
| MOSI | GPIO23 | SPI data |
| SCK | GPIO18 | SPI clock |
| T_CS | GPIO21 | Touch chip select |
Installing LVGL and Display Drivers
Use PlatformIO and TFT_eSPI as the display driver:
lib_deps =
lvgl/lvgl@^9.0
bodmer/TFT_eSPI@^2.5
XPT2046_Touchscreen
The key function is the flush callback that bridges LVGL with TFT_eSPI:
void my_disp_flush(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);
}
Creating Your First GUI: Buttons and Labels
LVGL makes GUI creation remarkably simple:
lv_obj_t *btn = lv_button_create(lv_screen_active());
lv_obj_set_size(btn, 120, 50);
lv_obj_center(btn);
lv_obj_t *label = lv_label_create(btn);
lv_label_set_text(label, "Click Me");
lv_obj_center(label);
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);
You can add sliders, switches, dropdowns, and charts with just a few lines of code each.
Building a Multi-Screen Application
For complex apps, use LVGL screen management to switch between views:
- Home screen: Overview with key metrics and navigation buttons
- Settings screen: Configuration with sliders and toggles
- Graph screen: Real-time charts of sensor data
Use lv_screen_load_anim() for smooth transitions — fade, slide, or zoom effects.
Touch Calibration and Input Handling
Touchscreen calibration is critical. The XPT2046 returns raw ADC values needing mapping:
- Run a calibration routine with targets at known screen positions
- Record raw touch values and calculate mapping coefficients
- Store calibration data in ESP32 NVS for persistence across reboots
Performance Tips for Smooth UI
- Use DMA transfers: TFT_eSPI supports DMA on ESP32 for non-blocking updates
- Allocate sufficient buffer: At least 1/10th of screen size
- Run LVGL tick on timer: Call
lv_tick_inc()from a hardware timer - Use PSRAM if available: ESP32-WROVER has 4 MB PSRAM for larger buffers
Recommended TFT Modules from Zbotic
These TFT displays work excellently with LVGL and ESP32:
Frequently Asked Questions
Can LVGL run on Arduino Uno?
No. LVGL requires at least 64 KB RAM. ESP32, STM32, and RP2040 are recommended.
What frame rate can I expect?
25-30 FPS with DMA setup on a 240×320 ILI9341. Static screens feel instant.
Is LVGL free?
Yes, MIT licence — free for personal and commercial use.
Can I use LVGL without a touchscreen?
Yes. LVGL supports buttons, encoders, and keyboards as input devices.
Shop Display Modules at Zbotic.in
India’s trusted source for OLED, LCD, TFT, LED matrices, and more. Fast shipping across India.
Add comment