Skip to content

1.28 ESPHOME Lesson02 Light Up the Screen

1. Course Introduction

In this lesson, we will use ESPHome to write code to light up the CrowPanel 1.28inch-HMI ESP32 Rotary Display and display “Hello World” on the screen.

2. Learning Objectives

Learn how to drive the rotary display

Light up the screen and print hello world on the display

3. Project Demonstration

img

Click the GitHub link below to download the complete code:

https://github.com/Elecrow-RD/CrowPanel-1.28inch-HMI-ESP32-Rotary-Display-240-240-IPS-Round-Touch-Knob-Screen/tree/master/example/esphome/Lesson02

Next, we will explain the key parts of this code and how the screen display is driven on the ESPHome platform.

First, establish a core understanding

This code is not traditional "programming code" (such as Python/C++), but an ESPHome configuration file (YAML format) — you can think of it as a "manual" written for the ESP32: telling the ESP32 what hardware to connect, what functions to implement, and how to communicate with Home Assistant.

The core rule of YAML is to describe the configuration required by the program in a “manual-style text format” rather than writing complex code. In YAML, the most important aspect is that indentation represents hierarchical relationships — content at the same level must be left-aligned, and child content must be indented two spaces more than the parent (Tabs are not allowed). The program determines “who belongs to whom” based on indentation; each line is usually in the form of key: value, where the left side of the colon is the name and the right side is the specific content; if a key contains multiple items, use - to represent a list; comments use #, which are only for human reading and are not executed by the program; YAML is extremely sensitive to case and spaces — one missing space or one extra Tab may cause the configuration to fail.

(1) Basic Information & Compilation Configuration (esphome block)

This is the "identity card" and "compilation rules" of the entire device, telling ESPHome how to compile the firmware and what the device is called.

esphome:                                      
  name: rotary-screen-128-display             
  friendly_name: Rotary_Screen_1.28_Display   
  platformio_options:                        
    build_flags: "-DBOARD_HAS_PSRAM"     
    board_build.esp-idf.memory_type: qio_opi   
    board_build.flash_mode: dio                
  on_boot:                                     
    priority: 800                               
    then:                                    
      - logger.log: "Backlight ON"        
      - output.turn_on: gpio_3_backlight_pwm
      - delay: 200ms
      - output.turn_off: power_light
      - output.turn_on: out1
      - output.turn_on: out2

This section is the core configuration of ESPHome, essentially telling the system “what kind of device this is, how to compile it, and what to do after power-on.”

name is the unique identifier of the device in ESPHome and Home Assistant, and it can only use lowercase letters and hyphens;

friendly_name is the human-readable name and does not affect program logic.

platformio_options are parameters for the underlying compiler. Here you explicitly inform the ESP32-S3 board that it has PSRAM, that PSRAM uses the OPI interface, and that Flash uses DIO mode; otherwise, with a large display + LVGL, memory may easily be insufficient and result in a black screen.

on_boot defines actions executed immediately after power-on, and priority: 800 means “execute immediately after most components are initialized.”

Here, gpio_3_backlight_pwm is enabled, which actually turns on the screen backlight pin GPIO46, described in detail later in the output section.

img

Here, out1 corresponds to GPIO1. We need to pull this pin high so that current can flow through the screen and the screen can light up. In other words, if you only enable the screen backlight pin GPIO46, the screen will still not light up; you must also enable GPIO1 so that current can flow and the screen can illuminate. Both are indispensable for lighting up the screen.

Here, out2 corresponds to GPIO2. This pin supplies power to the UART interface and I2C interface on the 1.28inch rotary display. This pin must be pulled high for the UART and I2C interfaces to function and for current to flow.

img

Here, power_light corresponds to pin GPIO40. This pin controls the power indicator LED. When the 1.28inch rotary display is powered on, this pin lights up and serves only as an indicator. (This pin lights up when the level is pulled low.)

img

(2) Tell ESPHome Which Chip You Are Using

esp32:                                         
  board: esp32-s3-devkitc-1                     
  framework:                                   
    type: esp-idf                               
    version: recommended                       

This section is for selecting the hardware and development framework.

board tells ESPHome that you are using the ESP32-S3 series; pin mapping, power management, USB, and PSRAM initialization will all be handled according to the S3 specifications.

framework: esp-idf means you are using the official ESP-IDF framework rather than Arduino — this is very important for LVGL, high-resolution displays, SPI DMA, and PSRAM, as the Arduino framework can easily become unstable in these scenarios.

version: recommended means using the stable IDF version currently validated by ESPHome to avoid version-related issues.

(3) psram: Preparing a “Memory Warehouse” for Large Screens and LVGL

psram:                                     
  mode: octal             
  speed: 80MHz   

This section is the external PSRAM configuration.

The built-in internal RAM of the ESP32-S3 is very limited; a round screen + ILI9xxx + LVGL almost certainly requires PSRAM.

mode: octal means using 8-line OPI mode (high speed and large bandwidth), and speed: 80MHz is a commonly used stable configuration for S3 + display.

If this is not configured, LVGL’s framebuffer, font cache, and drawing buffer may fail to allocate. The most typical symptom is: flashing succeeds, but the screen remains completely black.

(4) logger: —— Serial “Life Probe”

logger: 

This section enables the serial logging function.

It does not directly control any hardware, but it is extremely important for beginners:

  • You can see whether the ESP has started

  • Whether it has entered on_boot

  • Whether SPI / Display / LVGL have been initialized

Without logger, if the screen turns black, you will hardly know where the problem occurred.

(5) api: —— Communicating with Home Assistant

api:                                            # Home Assistant API integration
  encryption:                                   # Enable API encryption
    key: "8b5jwOcT6EgrVNxIwglnvruzf2iNw8vBzuFkIxcxWgY="

This section is the communication interface between ESPHome and Home Assistant.

Even if you are currently only displaying “Hello World,” ESPHome is fundamentally designed for IoT devices; the api allows you to perform remote control, update interfaces, and send data in the future.

The encryption key is used to prevent unauthorized control within the local network.

(6) ota: —— Wireless Upgrade Without Repeatedly Plugging in USB

ota:                                            
  - platform: esphome                        
    password: "93cb9d390324fc2c57ee56237810090a"

This section allows you to flash firmware directly via Wi-Fi in the future. This OTA configuration matches the firmware flashing process you will perform later. After the device successfully connects to the network, you will be able to remotely upload programs via Wi-Fi. (The prerequisite is that you first upload the bin file using Manual download.)

img

(7) wifi: + captive_portal: —— Network Connection and Emergency AP

wifi:                             
  ssid: !secret wifi_ssid                      
  password: !secret wifi_password               
  ap:                                      
    ssid: "Rotary-Screen-128-Display"          
    password: "9XFEMJU11HLh"                    
captive_portal:

This section is the Wi-Fi network configuration.

Under normal circumstances, it connects to your home router; if the connection fails, it automatically enables a hotspot (AP), allowing you to reconnect using your phone and reconfigure it.

captive_portal is a web-based configuration interface that prevents the device from becoming unusable.

(8) output: —— The “Actuators” of GPIO and PWM

output:                                       
  - platform: ledc                              
    pin: GPIO46                                 
    id: gpio_3_backlight_pwm                    
  - platform: gpio
    id: power_light
    pin: GPIO40
  - platform: gpio
    id: out1
    pin: GPIO1
  - platform: gpio
    id: out2
    pin: GPIO2

This section defines the output capabilities of the ESP32.

ledc is the ESP32 hardware PWM, which you use to control backlight brightness

gpio is standard high/low level output, used to control power, enable pins, and peripherals

The philosophy of ESPHome is: first define “what can be controlled,” then use it elsewhere.

(This was explained earlier.)

(9) light: —— Wrapping PWM as a “Light”

light:                                         
  - platform: monochromatic                     
    id: back_light                              
    output: gpio_3_backlight_pwm               
    restore_mode: ALWAYS_ON 

This section is the logical abstraction layer.

It wraps a PWM output into the concept of a “light,” so that you can:

  • Turn on / off

  • Adjust brightness

  • Automatically turn on at startup

restore_mode: ALWAYS_ON is extremely critical to prevent the backlight from being off by default after power-on, which might make you think the screen is broken

(10) spi: —— Screen Communication Highway

spi:                                            
  id: spi_bus                                
  mosi_pin: 11                                  
  clk_pin: 10 

This section defines the SPI bus.

The round GC9A01A display is an SPI screen, and all pixel data is transmitted via SPI.

Here you only use MOSI and CLK (the display does not require reading data).

(11) display: —— The Actual Screen Driver

display:                                        
  - platform: ili9xxx                           
id: round_display                           
model: GC9A01A                            
    cs_pin: GPIO9                             
    dc_pin: GPIO3                              
    reset_pin: GPIO14                          
    invert_colors: true                         
    rotation: 0   

This section is the most critical configuration of the display.

platform: ili9xxx represents an entire class of LCD controllers

model: GC9A01A explicitly tells the driver that you are using a 1.28-inch round display

cs / dc / reset are the key control pins of the SPI display

invert_colors: true is commonly required for GC9A01A; otherwise, colors may appear abnormal

rotation controls the display orientation

(12) font: —— Text Is Not Drawn Out of Thin Air

font:                                           
  - file: "gfonts://Roboto"                     
    id: roboto24                            
    size: 24 

This section defines font resources.

When LVGL displays text, the font must be compiled into the firmware in advance.

You are using Google Fonts Roboto at 24 pixels, suitable for a 240×240 round screen.

(13) lvgl: —— The “Brain” of the Graphical Interface

lvgl:
  displays:
    - round_display

  default_font: roboto24
  disp_bg_color: white   

  style_definitions:
    - id: hello_style
      text_font: roboto24
      text_color: 0x000000   
      bg_opa: TRANSP
      align: center

  pages:
    - id: hello_page
      widgets:
        - label:
            id: hello_label
            text: "Hello World!"
            styles: hello_style
            align: CENTER   

The entire "lvgl:" configuration enables and builds a basic graphical interface system and displays the text “Hello World!” exactly at the center of the screen: first, through "displays," LVGL is bound to the previously initialized "round_display," telling LVGL that all interface elements should be drawn on this screen;

Next, "default_font" and "disp_bg_color" set the default font and background color of the entire interface, preventing a black-on-black situation that appears as a black screen;

Then, in "style_definitions," a reusable text style "hello_style" is defined, explicitly specifying the use of Roboto 24-pixel font, black text color, transparent background, and centered alignment, ensuring that the text is clearly visible;

Finally, in "pages," a page named "hello_page" is created, and a "label" text widget is placed on that page with the content “Hello World!”, applying the previously defined style and centered alignment, thereby completing a minimal, visible, and verifiable Hello World interface used to confirm that the display and LVGL are functioning properly.

5. Code Logic Flowchart

img

6. Flashing Steps

Next, we will teach you how to use ESPHome for the first time to write code, including the overall operation process. Please follow us step by step.

Emphasize again here:

The following devices need to be on the same LAN:

① Your computer

② CrowPanel HMI ESP32 Rotary Display

③ Raspberry Pi with the Home Assistant system

Here, our Raspberry Pi with the Home Assistant system acts as the server in this project. Therefore, every time you enter the IP address of this Raspberry Pi with the Home Assistant system, you are entering Home Assistant. Only after entering this page can you proceed with the following operations.

img

The following operations assume that you have completed the installation steps in the previous lesson and have arrived at the ESPHome main page.

Once the installation is complete, we can start adding devices. Click on + New Device -> Continue.

imgimg

Click “New Device Setup”

img

Enter a name and click Next.

(You can use any custom name. Do not include any strange symbols such as @, #, etc.)

img

Here, do not check "Use recommended settings."

Select the main chip of the CrowPanel 1.28inch-HMI ESP32 Rotary Display, ESP32-S3.

img

Next, choose any option (since we will replace it in the code later).

img

Here, click "SKIP".

img

Then, return to the main interface, find the Rotary_Screen_1.28_Display you just created, click "EDIT", and enter the code editor.

img

This code is automatically generated based on the previous steps. Next, we will make replacements in it to help optimize the code for more efficient operation.

Automatically generated code:

img

This is the complete code. You can click on the code link below to obtain it.

https://github.com/Elecrow-RD/CrowPanel-1.28inch-HMI-ESP32-Rotary-Display-240-240-IPS-Round-Touch-Knob-Screen/tree/master/example/esphome/Lesson02

Next, you can replace the relevant content in esphome and ESP32 as needed. And add the item "PSRAM".

img

Then, based on your existing code, follow the format shown in the figure to add or replace these codes.

(Other configurations remain unchanged)

Remember to replace your own Wi-Fi name and password.

Note: This Wi-Fi connection must be in the same local network as your computer and Raspberry Pi!

img

Our Wi-Fi account and password are configured on the ESPHome main page.

img

img

Therefore, we can write it in the code like this, meaning that we are using the Wi-Fi "elecrow888".

Of course, you can also directly write the Wi-Fi account and password in detail in the code.

img

Note: These items are specific to the device you created and cannot be the same as mine. Just keep the ones you originally created.

You can copy the other functional code from mine.

img

Once the code replacement is complete, click "INSTALL" in the top right corner.

img

Select "Manual download".

img

Wait for a few minutes until the installation is complete.

Then, select "Factory format".

img

Once the download is complete, you will see the .bin file.

img

Remember the path of this .bin file.

Open the following website: https://web.esphome.io/?dashboard_wizard

After opening this website, you will arrive at this interface:

img

Next, we will flash this .bin file into the CrowPanel 1.28inch-HMI ESP32 Rotary Display.

Connect the CrowPanel 1.28inch-HMI ESP32 Rotary Display to your computer.

img

Click "Connect"

img

Select the COM port and connect it.

img

After connecting the CrowPanel 1.28inch-HMI ESP32 Rotary Display, click "Install".

img

Add the .bin file you just downloaded, then click "Install".

img

Then select the bin file that you just downloaded.

img

Click "INSTALL"

img

Wait for a few minutes.

img

After the installation is complete, click "Close".

img

After successfully flashing the .bin file, return to the ESPHome page in Home Assistant.

img

Press the RESET button on the CrowPanel 1.28inch-HMI ESP32 Rotary Display.

img

Restart the ESP32 display, and you should see the device you created earlier show as ONLINE in the top right corner.

img

And if you have also added the functional code we provided, you will be able to see “Hello World!” displayed on the screen.

img

After it shows ONLINE here, if you make any further modifications to the code and want to upload it again, you can use the Wireless upload method, which will be much more convenient.

img