2.4_2.8inch_Lesson03_PWM_and_LVGL_Light_Control¶
1. Course Introduction¶
This lesson consists of two experimental segments. The main thread of the course is the 2.4_2.8_LVGL.ino lamp-control interface: it connects the LCD, touch input, and LVGL together, displays the UI exported from SquareLine Studio, and uses the ON / Off buttons to control GPIO18 on the UART1 interface. pwm.ino is a supplementary example used to demonstrate PWM duty cycle variation and backlight brightness control.
This lesson marks the transition from "peripherals can move" to "the interface can interact." The key focus is understanding how UI events call Lamp_on / Lamp_off to ultimately control GPIO18 output; the PWM portion supplements the understanding of backlight brightness adjustment.
Reference materials:
2. Learning Objectives¶
- Be able to understand the relationship between PWM frequency, resolution, and duty cycle.
- Be able to complete LVGL display, touch, and UI initialization.
- Be able to flash the PWM project and the LVGL project separately, following the Arduino IDE configuration method from Lesson 01.
- Be able to explain the relationship between
Lamp_on/Lamp_offand GPIO18, the main control pin in this lesson. - Be able to determine, based on on-screen behavior, whether the problem lies in the backlight, screen refresh, or touch stage.
3. What You Need¶
- CrowPanel Advance 2.4-inch development board.
- A USB data cable that supports data transfer.
- Optional: a measurement tool for observing PWM output, used to view GPIO38 backlight/PWM changes.
- A lamp/LED module for the lamp-control experiment, connected to the UART1 interface of the development board; the course code uses GPIO18 to control on/off.
- Arduino IDE, with
esp32 by Espressif Systems3.3.8 installed via Boards Manager. - LVGL 9.1.0, LovyanGFX, and the project's bundled UI files.
- SquareLine Studio, for recreating or exporting UI files.
- PWM project:
pwm.ino - LVGL project file:
2.4_2.8_LVGL.ino
Code and Resource Download¶
Code download: - 2.4_2.8_LVGL
Resource download: - lamp_28.png
4. Software Operation Steps¶
- Open the project
2.4_2.8_LVGL.inousing Arduino IDE.
Note: Check that the UI files such as ui.c, ui.h, ui_Screen1.c, ui_events.c, and ui_img_lamp_28_png.c are all in the same project directory.
- Confirm that
Lamp_onandLamp_offinui_events.ccontrol GPIO18.
- Connect the external LED, and use a USB cable that supports data transfer to connect the development board to the computer.
- Complete the development environment configuration in the Tools menu in order: first confirm that the version of
esp32 by Espressif Systemsin Boards Manager is 3.3.8; then set Board to ESP32S3 Dev Module, select the serial port corresponding to the board in Port, set Flash Size to 16MB (128Mb), set PSRAM to OPI PSRAM, and set Partition Scheme to Huge APP (3MB No OTA/1MB SPIFFS). After completing the above configuration, you can proceed with compiling and uploading the program.
Note: If Arduino IDE reports a compilation error, first return to Lesson 01 to check whether the ESP32 Core is 3.3.8, and confirm that the board model, PSRAM, Flash Size, and the course library files are consistent.
- Click Upload to compile and wait for the upload to complete. If it gets stuck at
Connecting..., check for port occupation and use the BOOT/RESET download mode as required by the board.
- Open Serial Monitor in the top-right corner, set the baud rate to
115200, and observe the log.
4.1 Flashing the PWM Output Project¶
- Open the project
pwm.ino, and confirm thatLovyanGFX_Driver.his in the same folder. The PWM example initializes the LCD, so this display driver file is required.
- Check whether
pwmPinin the code is38,pwmFreqis5000, andpwmResolutionis8.
- Click Upload in the top-left corner of Arduino IDE and wait for compilation and upload to complete.
- After the upload is complete, the screen should display
PWM Backlight,GPIO38,Duty: x / 255, and a blue progress bar. The progress bar will keep changing, and the Serial Monitor will also outputPWM duty = .... This project does not display the LVGL lamp-control interface; it is a supplementary example mainly used to understand the PWM output of GPIO38.
Note: The main lamp-control pin in this lesson is GPIO18. The PWM example uses GPIO38 to demonstrate backlight/PWM adjustment; it is not the main control pin for the lamp-control UI in this lesson.
Note: If you still cannot see backlight changes after flashing, first confirm whether the screen shows a Duty value and a blue progress bar. As long as the progress bar changes, the program is running; if the backlight change is not obvious, then check whether GPIO38 is consistent with the current hardware version.
5. Hardware Operation Steps¶
- Connect the external LED, and use a USB cable that supports data transfer to connect the development board to the computer.
- After flashing is complete, wait for the board to reset; the screen should display the lamp-control UI you just created.
- Tap the
ONandOffbuttons on the screen, and observe whether the lamp/LED on the UART1 interface toggles on and off.
Note: The PWM project and the LVGL project are two independent Arduino projects. When testing PWM, open pwm.ino; when testing touch-based lamp control, open 2.4_2.8_LVGL/2.4_2.8_LVGL.ino. Do not mix the two project files in a single window and compile them together. GPIO18 is the main control pin for the LVGL lamp-control UI in this lesson; GPIO38 is used for the PWM backlight/duty-cycle supplementary example. When troubleshooting lamp-control issues, prioritize checking GPIO18.
6. Key Code Explanation¶
6.1 UI Project Code¶
The complete touch UI project for this lesson mainly accomplishes five things: initialize the LCD, initialize the touch, register the LVGL screen-refresh callback, register the touch input callback, and create the UI exported from SquareLine.
gfx is the LovyanGFX display object, responsible for actually writing pixels to the LCD. buf and buf1 are LVGL draw buffers; the course code places them in PSRAM to store screen refresh data.
void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) {
gfx.pushImageDMA(
area->x1,
area->y1,
area->x2 - area->x1 + 1,
area->y2 - area->y1 + 1,
(lgfx::rgb565_t *)px_map
);
lv_display_flush_ready(disp);
}
my_disp_flush() is the LVGL screen-refresh callback. LVGL first renders the interface content into the buffer, then hands it off through this function to LovyanGFX, and finally gfx.pushImageDMA() pushes it to the LCD.
void my_touchpad_read(lv_indev_t *indev, lv_indev_data_t *data) {
data->state = LV_INDEV_STATE_REL;
if (gfx.getTouch(&touchX, &touchY)) {
data->state = LV_INDEV_STATE_PR;
data->point.x = LCD_H_RES - touchX;
data->point.y = touchY;
}
}
my_touchpad_read() is the LVGL touch-read callback. When the touchscreen is pressed, the function converts the touch coordinates into coordinates under the current screen orientation, then hands them to the LVGL widget system.
lv_display_set_flush_cb(disp, my_disp_flush);
lv_indev_set_read_cb(indev, my_touchpad_read);
ui_init();
The first line is responsible for sending the LVGL rendering result to the LCD, the second line is responsible for handing the touch coordinates to LVGL, and the third line is responsible for creating the interface objects. If any one of the three is missing, the screen may still light up, but a complete, interactive UI will not appear.
GPIO18 is used for the lamp-control output of the UI in this lesson; Lamp_on / Lamp_off will control its high and low levels. GPIO38 is used to turn on the screen backlight; if GPIO38 is not pulled high, the LCD may have initialized successfully, but the screen will still appear black.
lv_timer_handler() must be executed continuously for LVGL to refresh animations, process touch events, and respond to button clicks. The 5 ms delay keeps the main loop responsive while giving the system a little scheduling time.
7. UI Creation Steps¶
The UI in this section is created using SquareLine Studio. The official workflow is to first create an Arduino + TFT_eSPI type project, then add the lamp image, an On button, and an Off button, and finally bind the Lamp_on and Lamp_off callback functions to the two buttons respectively and export the UI files.
For SquareLine Studio download and basic installation, refer to:
7.1 Creating the SquareLine Project¶
- Open SquareLine Studio and click Create at the top. When creating a new project, you must select LVGL
9.1.0. - In the board category, select Arduino.
- Select the Arduino with TFT_eSPI project template.
- Confirm the resolution based on the screen size. The course projects for 2.4-inch and 2.8-inch use
320 x 240.
- In Project Settings on the right, set the project name and path, and confirm the key parameters:
- After confirming the parameters, click CREATE to create the project.
7.2 Importing the Lamp Image Asset¶
- After entering the project editing interface, switch to the Assets area at the bottom.
- Click ADD FILE INTO ASSETS to import the lamp image asset into the project resources.
- Of course, you can also choose other images you prefer to use.
- Image asset download link: lamp_28.png
- After the import is complete, drag the lamp image asset onto the
Screen1canvas. Adjust the position of the image on the canvas so that it is on the left side of the screen, leaving space for the button area on the right.
7.3 Adding the On Button¶
- In the left Widgets > BASIC, select Button.
- Drag the Button onto the right side of the canvas as the
Onbutton.
- Select the button and adjust its position and size in the Inspector on the right.
- Expand STYLE (MAIN) > Background and set the button background color to orange-red; the official example color is
FF5529.
- Add a Label from the left Widgets > BASIC and drag it into the button.
- Select the Label and change the text to
Onin the text box on the right.
- Adjust the Label style, set the text color to white, and choose an appropriate font size. Here
montserrat 40is used.
- In the Hierarchy panel on the right, confirm that
Labelis a child control ofButton.
7.4 Duplicating and Creating the Off Button¶
- In the Hierarchy panel, select the already-created
Button1. 2. Open the More menu and select Copy.
- Paste it as a new button on the canvas or in the hierarchy. Use Paste as child to complete the copy.
- Move the copied button below the
Onbutton.
- Select the Label inside the new button and change its text to
Off.
- Adjust the position and background color of the two buttons as needed so that the
OnandOffbuttons are arranged vertically on the right side.
7.5 Configuring Button Events¶
- Select the
Onbutton and scroll the Inspector on the right to the EVENTS section. - Click ADD EVENT to add an event.
- Set Trigger to
RELEASED. - Set Action to
CALL FUNCTION. - Enter the following for Function name:
- Select the
Offbutton and add an event in the same way. - Set Trigger to
RELEASED, set Action toCALL FUNCTION, and enter the following for Function name:
- Click the play button in the top-right corner to enter preview mode and check that the
OnandOffbuttons can be clicked normally.
Note: The function name set in Call function must match the function name in the Arduino project exactly. In this lesson, the ON button uses Lamp_on and the Off button uses Lamp_off; any error in capitalization or letter case will make the button clickable but unable to control GPIO18.
7.6 Setting the Export Path¶
- Click File > Project Settings to open the project settings.
- Set the export path in FILE EXPORT. In the example,
Project Export Rootpoints to the SquareLine project directory, andUI Files Export Pathpoints to theOutputfolder.
- Set
LVGL Include Pathto:
- Check Flat export (exports all files to one folder), then click APPLY CHANGES.
Note: It is recommended to check Flat export so that the exported UI files are consolidated into a single folder, making it less likely to omit files when copying them into the Arduino project later.
7.7 Exporting the UI Files and Copying Them to the Arduino Project¶
- Click the top menu Export > Export UI Files.
- Open the exported
Outputfolder and confirm that it contains the UI source files, event files, helper files, and image resource files. Common files include:
ui.c
ui.h
ui_events.c
ui_events.h
ui_helpers.c
ui_helpers.h
ui_Screen1.c
ui_comp_hook.c
ui_img_lamp_28_png.c
- Copy the exported UI files into the Arduino project directory
2.4_2.8_LVGL, placing them at the same level as2.4_2.8_LVGL.ino,LovyanGFX_Driver.h,pins_config.h, andtouch.h.
Note: The 2.4-inch / 2.8-inch displays must use a 320 x 240 resolution; if you mistakenly select 480 x 320 or 800 x 480, the exported UI coordinates and image dimensions will not match the screen. 2. The UI files in the local course code are exported from a SquareLine Studio / LVGL 9.1.0 project; confirm the destination path before exporting the UI files; when copying files, do not omit image resource files such as ui_img_lamp_28_png.c, otherwise the compilation will report undefined image symbols.
8. Observations¶
Click the ON and Off buttons on the screen and observe whether the lamp/LED on the UART1 interface toggles on and off.
9. Code Download¶
- Code download link: 2.4_2.8_LVGL
- Image asset download link: lamp_28.png











































