IDF v5.4 & LVGL v9.2 & ESP-DL Integration (2025)

Introduction

This is the final post in my ESP-DL series.

My goal is to create a simple LVGL application that utilizes the esp-dl library for digit recognition.

In this blog, I will clearly explain how I implemented the integration and share key lessons learned.

Project Core Values

  • For learning purposes.
  • The implementation is kept simple and straightforward.
  • No fancy stuff, make it work.

Application Features

This application allows the user to handwrite a digit on the screen. The device then predicts the digit using the ESP-DL library.

The Hard Part

Previously, I created a sketchpad project using the Arduino framework and PlatformIO:
https://github.com/tommokmok/esp32s3_YetAnotherSketchpad

However, ESP-DL requires a higher version of ESP-IDF, so I needed to port the LVGL code to an ESP-IDF-based framework (not PlatformIO).

There are very few examples of using ESP-DL with the Arduino framework, so the first step was learning how to implement LVGL in ESP-IDF, then integrating it with the ESP-DL digit recognition example.

Porting LVGL to ESP-IDF

Hardware specs:

  • ESP32-S3 dev board + 2.8” TFT LCD
    (Purchased from Taobao. More info: ESP32-LVGL开发板)

    Note: This dev board is not recommended due to hardware issues. It may reset automatically, especially when connected to a PC.

  • ESP32-S3-N8R8 (8MB external RAM and 8MB external SPI flash)
  • LCD Driver: ST7789, 320 x 240 pixels (SPI interface)
  • Touch Driver: XPT2046 (SPI interface)

After researching, I found three possible approaches for porting LVGL to ESP-IDF:

  1. Espressif’s official LVGL port:
    https://components.espressif.com/components/espressif/esp_lvgl_port/versions/2.6.0/readme

    • Up-to-date library with example code.
    • Good starting point.
  2. LVGL team’s porting example:
    https://github.com/lvgl/lv_port_esp32/tree/master

    • Outdated (LVGL v7, ESP-IDF v4).
    • Not recommended for latest ESP-IDF, but useful as a reference.
  3. ESP-IDF example:
    https://github.com/espressif/esp-idf/tree/v5.5.1/examples/peripherals/lcd/spi_lcd_touch/main

    • Up-to-date code.
    • Less functionality, simpler than using esp_lvgl_port.

After careful consideration, I chose option 1 for easier porting to the latest LVGL and ESP-IDF versions.

Based on my previous sketchpad project, I used LVGL v9.2.2 and IDF v5.4.2.

Porting LVGL v9.2.2 to Current Hardware

Prerequisites

  • VS Code with the Espressif ESP-IDF extension and IDF v5.4.2 installed.

The porting process was straightforward, and adding the touch driver did not take much time.

Source code:
https://github.com/tommokmok/esp32s3_lvgl_idf

However, I spent some time manually adding calibration code for the touch point positions. For details, please check the repository above.

Integrating LVGL with ESP-DL Example Code

This was the most challenging and time-consuming part.

Key Issues Encountered

  • Incorrect sdkconfig settings caused ESP32 to hang:
    • When the canvas size is too large (e.g., 320x240), LVGL cannot allocate enough memory.
    • Solution: Set CONFIG_LV_USE_CLIB_MALLOC=y. By default, ESP32-S3 uses external PSRAM for allocations >4KB.

06-guru-meditation-error

Lessons Learned

  • Enable LVGL logging for development:
    Without logging, debugging is very difficult because ESP32-S3 may hang without any UART output.
1
2
3
CONFIG_LV_USE_LOG=y
CONFIG_LV_LOG_LEVEL_INFO=y
CONFIG_LV_LOG_LEVEL=1
  • In VS Code, configure ESP-IDF to avoid deleting managed_components during a Full Clean:
    This prevents unnecessary re-downloads and speeds up development.

05-not-delete-components-full-clean

  • Color format consistency:
    The color format set on the LCD driver, LCD display, and LVGL must match. Otherwise, colors will be displayed incorrectly.
1
2
3
4
5
6
7
8
// Color set on the driver
.color_space = EXAMPLE_LCD_COLOR_SPACE,

// Color set on the display
.color_format = LV_COLOR_FORMAT_RGB565,

// Color set on LVGL
lv_draw_buf_create(30, 25, LV_COLOR_FORMAT_RGB565, LV_STRIDE_AUTO);

Test Video

Watch the demo:
https://youtube.com/shorts/B73eYAXCKzQ?feature=share

lvgl-digit-reconigition

As shown in the video, the accuracy is not ideal, especially for digits 3, 9, and 8.

This leads to the next step: improving the project. The first thing to try is increasing the input size—30x25 pixels is too small for handwritten digits.

Conclusion

Source code:
https://github.com/tommokmok/esp32s3_lvgl_digit_recongnition

This is not the final version, but just a starting point.

Looking back, it seems like a lot of work, but in reality, it was very little outcome which still not perfect.

It’s similar to an RPG game: before completing the main quest, you need to finish several mini-tasks.
You can’t do it in just one big leap.

It’s time-consuming, but I enjoy the process—especially when things finally work.

Let’s see how far I can go with these little steps.