Skip to content

Lesson09_LVGL_Touch_LED: ESP32-P4 LVGL Touch-Controlled LED

1. Course Introduction

This lesson integrates the MIPI DSI display, GT911 touch panel, and LVGL graphics library to draw an LED control interface on the screen, containing two buttons: "LED ON" and "LED OFF". After the program is flashed, the development board powers on and resets; the screen lights up and displays a white background, the title "LED Controller", and the two buttons. When the learner taps the "LED ON" button with a finger, the onboard LED (GPIO48) turns on and the serial port prints LED turned ON. When the "LED OFF" button is tapped, the LED turns off and the serial port prints LED turned OFF.

This lesson is a comprehensive application of the display and touch courses, integrating the touch content from Lesson05 and the display and LVGL interaction from Lesson07. Through this experiment, learners will complete an end-to-end verification of the interaction chain involving LCD display, touch input, LVGL widget creation, and event callbacks.

2. Learning Objectives

  • Be able to open the Lesson09 project in ESP-IDF and set the target chip to esp32p4.
  • Be able to explain how LVGL display callbacks and touch callbacks are registered and their roles.
  • Be able to explain the mechanism by which lv_obj_add_event_cb registers button click events.
  • Be able to complete compilation, flashing, and control the LED on/off via touch buttons.
  • Be able to determine whether the display and touch chain is functioning normally based on whether the buttons respond to touch and whether the LED toggles.

3. Preparation

  • Hardware: One CrowPanel Advanced 7 / 9 / 10.1 inch ESP32-P4 HMI AI Display development board, and one USB Type-C data cable that supports data transfer.
  • Compatibility note: The hardware and software code for the 7 / 9 / 10.1 inch development boards are fully interchangeable; only the board size differs. Please select the appropriate model based on display size and use case.
  • Software: VS Code, ESP-IDF Extension (ESP-IDF v5.4 or later).
  • Project dependencies: Keep the main/main.c, peripheral/bsp_illuminate, peripheral/bsp_display, peripheral/bsp_i2c, and peripheral/bsp_extra components, as well as the esp_lcd_ek79007, esp_lcd_touch_gt911, esp_lvgl_port, and lvgl managed components.
  • Configuration: Target chip esp32p4.

Code download link:

CrowPanel-Advanced-7inch-ESP32-P4-HMI-AI-Display-1024x600-IPS-Touch-Screen/example at master · Elecrow-RD/CrowPanel-Advanced-7inch-ESP32-P4-HMI-AI-Display-1024x600-IPS-Touch-Screen

4. Software Operation Steps

  1. Open the ESP-IDF Extension panel in VS Code, click Open ESP-IDF Project, and select the Lesson09-LVGL_Lighting_Control folder. Open project

  2. First, select the code runtime environment ESP-IDF v5.4.2, set the flashing method to UART, and then select the serial port that actually corresponds to the development board. Next, in the ESP-IDF Extension panel, click Set Espressif Device Target and select esp32p4. After configuration, the status bar should display ESP-IDF v5.4.2, UART, the required COM port, and ESP32-P4.

Click SDK Configuration Editor

  1. Click SDK Configuration Editor in the VS Code bottom status bar or the ESP-IDF extension panel, and wait for the configuration page to fully load before modifying parameters. If the page is still loading, do not execute Build immediately.

Click SDK Configuration Editor

Wait for the SDK Configuration Editor to finish loading

  1. Enter flash in the search box and ensure Flash SPI mode: QIO; Flash Sampling Mode: STR Mode; Flash SPI speed: 80 MHz; Flash size: 16 MB. These parameters should match the onboard Flash of the Advance-P4 board. Configure Flash parameters

  2. Then refer to "4. Software Operation Steps" in Lesson07_Turn_on_the_Screen to complete the detailed SDK configuration; the relevant configuration methods were covered in Lesson 7.

    Note: The LVGL font size used in this lesson is 24; please adjust accordingly.

  3. After verifying the configuration is correct, click Save in the upper-right corner; confirm the changes are saved before proceeding with the Build compilation.

  4. Click Full Clean to clear the cache left over from the previous compilation. Performing this operation after the first compilation, switching project configuration, or modifying SDK parameters can prevent old configuration from affecting new build results. Run Full Clean

  5. Click Build to compile the project. The first compilation will automatically download the required managed components, and upon success it outputs Project build complete. Compile project

  6. Confirm that the development board is connected to the computer via USB, click Select Port to Use to choose the serial port, then click Flash to flash the firmware. Select serial port and flash

  7. After flashing is complete, click Monitor to open the serial monitor, where you should see the UI created successfully log. Press Ctrl + ] to exit the monitor. Open monitor

  8. After flashing is complete, wait for the device to reset and observe whether the screen lights up and displays the LED control interface. Observe the screen interface

  9. Finally, you may use the one-click operation button in the ESP-IDF status bar to sequentially execute compilation, flashing, and opening the serial monitor. Use this only after the project configuration, serial port, and code have all been verified correct; if you need to locate a problem, follow the steps above one by one. One-click compile, flash, and open monitor

5. Hardware Operation Steps

  1. Connect the ESP32-P4 development board to the computer using a USB data cable. Confirm that the LCD and touch panel ribbon cables are properly connected. Connect the development board
  2. After flashing and reset, observe whether the screen displays a white background, the title "LED Controller", and the two buttons, with a centered layout and no misalignment. Observe the interface display
  3. Tap the "LED ON" button on the screen with a finger, and observe whether the onboard LED lights up and whether the serial port prints LED turned ON. Tap the ON button
  4. Tap the "LED OFF" button and observe whether the LED turns off and whether the serial port prints LED turned OFF, confirming that the touch interaction works normally. Tap the OFF button

6. Key Code Explanation

my_lvgl_disp = lvgl_port_add_disp_dsi(&disp_cfg, &lvgl_dpi_cfg);
...
const lvgl_port_touch_cfg_t touch_cfg = {
    .disp = my_lvgl_disp,
    .handle = tp,
};
my_touch_indev = lvgl_port_add_touch(&touch_cfg);

This is the registration of the LVGL display and touch input devices. lvgl_port_add_disp_dsi registers the MIPI DSI panel as an LVGL display, and the image rendered by LVGL is flushed to the screen; lvgl_port_add_touch registers the GT911 touch driver as an LVGL pointer input device, and touch coordinates are automatically delivered to LVGL widgets. If only the display is registered without the touch device, the interface can be displayed but the buttons will not respond to clicks; conversely, nothing can be displayed.

lv_obj_t *btn_on = lv_btn_create(scr);
lv_obj_set_size(btn_on, 120, 50);
lv_obj_align(btn_on, LV_ALIGN_CENTER, 0, -40);
lv_obj_add_event_cb(btn_on, btn_on_click_event, LV_EVENT_CLICKED, NULL);

This creates the ON button and binds a click event. lv_btn_create creates a button on the screen; set_size sets the size to 120×50; align places the button 40 pixels above the screen center; add_event_cb registers the LV_EVENT_CLICKED event callback btn_on_click_event. If add_event_cb is forgotten, the button is visible but does not respond to clicks.

static void btn_on_click_event(lv_event_t *e)
{
    gpio_extra_set_level(true);
    MAIN_INFO("LED turned ON");
}

Click event callback: drives GPIO48 high to turn on the LED and prints a log. LVGL automatically calls this function when it detects that the button has been clicked. If true is changed to false, tapping the ON button will instead turn the LED off, which can be used to verify whether the callback is working.

gpio_extra_set_level(false);

At initialization, the LED is first set to off to ensure that the power-on initial state is consistent with the semantics of the OFF button. If it is not set initially, the LED may retain a random power-on state, causing the interface display to mismatch the actual hardware state.

7. Experimental Observations

After flashing and reset, the serial monitor outputs:

I (xxx) MAIN: Starting LED control application...
I (xxx) MAIN: LDO3 and LDO4 init success
I (xxx) MAIN: I2C init success
I (xxx) MAIN: Touch panel init success
I (xxx) MAIN: LCD init success
I (xxx) MAIN: LCD backlight opened (brightness: 100)
I (xxx) MAIN: LED initialized to OFF state
I (xxx) MAIN: UI created successfully
I (xxx) MAIN: System initialized successfully

Screen behavior: the backlight turns on, showing a white background, with "LED Controller" (Montserrat 24) displayed centered at the top, and two buttons below: "LED ON" (top) and "LED OFF" (bottom). The LED is initially off.

Interaction behavior: when the finger taps the "LED ON" button, the button provides a highlighted feedback, the onboard LED lights up, and the serial port prints LED turned ON; when the "LED OFF" button is tapped, the LED turns off and the serial port prints LED turned OFF. Repeated taps should not cause freezing, rebooting, or no response. If a button does not respond to touch, first check whether the touch registration succeeded and whether the touch coordinate orientation is correct; if the LED does not light up, check the GPIO48 configuration.