Skip to content

Lesson03: GC9309 Display, AXS5106L Touch, and LVGL 9.1

1. Lesson Objectives

This is the only lesson in the entire course that requires interface output to be displayed on the LCD screen. The program uses the GC9309 display initialization method verified in the reference project, the AXS5106L touch driver, LVGL 9.1, and the UI files in this lesson’s src/ui code folder.

2. Prerequisites

  • Complete the ESP32-S3 environment setup in Lesson01.
  • Additional library: GFX Library for Arduino; this project uses version 1.6.2.
  • Additional library: LVGL; this project uses version 9.1.0.
  • The lesson code folder must retain config.h, src/touch, and src/ui. These are dependency files required for the screen, touch functionality, and UI to operate.

How to add the library files:https://www.elecrow.com/wiki/Arduino_IDE_Library_Import_Guide.html

3. Arduino IDE Instructions

  1. Open Lesson03_Display_Touch_LVGL.ino in Arduino IDE. Do not open or move ui.c separately. lesson_1

  2. Confirm that config.h, src/touch, and src/ui are in the same lesson code folder as the .ino file. lesson_2

  3. Confirm that the board is set to ESP32S3 Dev Module, with 16MB Flash, OPI PSRAM, and Huge APP. lesson_3

  4. Confirm that GFX Library for Arduino and LVGL are installed, or use the libraries provided in the shared libraries folder. lesson_4

  5. Select the appropriate serial port and click Verify to compile. lesson_5

  6. Click Upload to flash the program. After flashing is complete, wait for the screen backlight to turn on. lesson_6

  7. Open Serial Monitor, select a baud rate of 115200, and drag the Slider on the screen. lesson_7

4. Hardware Instructions

  1. Connect the development board to the computer using a USB data cable. After flashing is complete, wait for the screen backlight to turn on.

lesson_8

  1. Confirm that the LVGL interface exported from src/ui appears on the LCD.

  2. Touch the screen with your finger and check whether the touch coordinates are printed to the serial port.

lesson_7

  1. Drag the Slider in the interface and observe the slider position change on the screen and the slider value displayed in the serial output.

  2. If the screen does not turn on, first check the battery level, USB power supply, GPIO47 peripheral power, and GPIO40 LCD power control logic.

5. Key Code Explanation

pinMode(PIN_PERIPHERAL_POWER, OUTPUT);
digitalWrite(PIN_PERIPHERAL_POWER, HIGH);
delay(30);
pinMode(PIN_LCD_POWER, OUTPUT);
digitalWrite(PIN_LCD_POWER, LOW);
analogWrite(PIN_LCD_BACKLIGHT, 0);

This code is essential for turning on the screen. GPIO47 is first driven high to enable the main peripheral power supply. GPIO40 is then driven low to enable the LCD power because the LCD power control on this hardware is active-low. The backlight remains at 0 during initialization and is turned on only after LVGL and the UI are ready, preventing uninitialized content from appearing on the screen.

displayBus = new Arduino_ESP32SPIDMA(PIN_LCD_DC, PIN_LCD_CS, PIN_LCD_SCK,
                                     PIN_LCD_MOSI, PIN_LCD_MISO, HSPI, true);
displayGfx = new Arduino_GC9309(displayBus, PIN_LCD_RST, 0, false,
                                DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, 0, 0, 0);
displayGfx->begin(DISPLAY_SPI_FREQUENCY);

Arduino_ESP32SPIDMA creates an SPI DMA bus that transfers pixel data to the screen at high speed. Arduino_GC9309 is the LCD controller driver responsible for initializing the GC9309 and providing the drawing interface. DISPLAY_SPI_FREQUENCY is set to 80MHz, using the speed that has already been verified to work in the reference project.

lvDisplay = lv_display_create(DISPLAY_WIDTH, DISPLAY_HEIGHT);
lv_display_set_color_format(lvDisplay, LV_COLOR_FORMAT_RGB565);
lv_display_set_flush_cb(lvDisplay, displayFlush);
lv_display_set_buffers(lvDisplay, drawBuffer, nullptr, drawBufferBytes,
                       LV_DISPLAY_RENDER_MODE_PARTIAL);

This code connects LVGL to the physical LCD. LVGL first creates a 240×296 display object and then sets the color format to RGB565. displayFlush is LVGL’s display flush callback. The pixels rendered by LVGL are ultimately passed to Arduino_GFX through this function. Because the screen resolution is relatively large, the code uses partial rendering mode and allocates a drawing buffer only 40 lines high.

ui_init();
lv_obj_add_event_cb(ui_Slider2, sliderChanged, LV_EVENT_VALUE_CHANGED, nullptr);

ui_init() comes from the UI export files in this lesson’s src/ui folder and creates the LVGL interface. The second line adds an event callback to ui_Slider2 in the UI. When the slider value changes, sliderChanged() is called and prints the value to the serial port.

6. How to Create the UI (This Section Explains How the UI Files for This Lesson Were Created)

Note: To modify the UI, use SquareLine Studio to generate the corresponding UI files, place them in the appropriate UI folder, and modify the corresponding code.

How to download SquareLine Studio:https://www.elecrow.com/wiki/Create_LVGL_UI_with_SquareLine_Studio.html

Open SquareLine Studio and create a file.

lesson_10

Change the background color.

lesson_11

Insert a Slider component.

lesson_12

Change the component’s internal background color.

lesson_13

Test the animation effect.

lesson_14

If the animation effect is correct, export the files by clicking Project Settings.

lesson_15

Configure the files.

lesson_16

After selecting the export path, save the settings.

lesson_17

Export the UI files.

lesson_18

Copy the UI files to the project folder.

lesson_19

This section demonstrates only a simple UI example. For a more complex UI, use SquareLine Studio to generate it.

Download the Lesson 03 code