Skip to content

5-inch ESP32 Dispaly PlatformIO Tutorial

Overview


The example is an environmental monitoring project, using a DHT20 sensor to obtain the environment temperature and humidity and display it on the screen; and control the LED on and off by the buttons on the screen.

In this tutorial, we will show you how to design the UI with SquareLine Studio, and show you how to build a project on PlatformIO.

gif2

Hardware Preparation


CrowPanel ESP32 5.0'' HMI Crowtail-DHT20 Crowtail-LED
CrowPanel-ESP32-5-0inch CROWTAIL-DHT20 CROWTAIL-LED
BUYNOW BUYNOW BUYNOW

Design UI file with SquareLine Studio


Get Started with SquareLine Studio

Please click the card below to learn how to download the SquareLine Studio, and how to export the demo UI file.

GetStartedWithSquareLine

Design UI file with SquareLine Studio

Let's start learning how to create our own UI after getting an initial understanding of SquareLine Studio.

  1. Open the SquareLine Studio and create a project. Select "Arduino"->"Arduino with TFT_eSPI".

    SLS-UI-1

    Note:

    When select the Arduino framwork, there's only one option "Arduino with TFT_eSPI". By choosing this, the squareline studio will generate a template code suitable for the TFT_eSPI library. However, squareline studio not only supports the TFT_eSPI library, it supports a variety of libraries to suit different hardware and application needs. For example, Adafruit_GFX library, LovyanGFX etc.

    After using SLS to generate UI code, we then use different graphics libraries according to different hardware and modify the corresponding code to display the content you design.

  2. Set the name of the project, set the screen resolution to 800*480, set the color depth to 16bit, and keep other default settings. After setting, click CREATE to create the project.

    SLS-UI-2

    • 16-bit color depth: can represent 65,536 colors through RGB 5:6:5 sub-pixel representation, that is, each RGB channel occupies 5 bits and 1 bit (a total of 16 bits) to represent colors.
  3. After creation, enter the following interface with a blank background.

    SLS-UI-3

  4. In the "Assets" area, click "ADD FILE TO ASSETS" to add custom images or icons.

    Please click download to download the custom images used in this tutorial.

    SLS-UI-4

    Note:

    Images only support PNG format. The pixels of the image need to be smaller than the pixel size of the screen used in your project. The size of each image should not exceed 100k, preferably within 30k, to provide a smooth display effect.

  5. Add background.

    Find "Inspector"->"STYLE SETTING", click to expand "STYLE(MAIN)", then click the 2nd "Background"(in v1.3.4 is "Background image"). Check the "Bg Image" and select the background image.

    SLS-UI-5

    SLS-UI-6

  6. Add Label widget to display temperature and humidity.

    Click "Label" in the "Widgets" area, and "Label1" will be added to the current Screen.

    SLS-UI-7

    The position and size of the label can be adjusted by dragging the mouse. You can also directly enter numbers in the Inspector→LABEL→Transform to adjust.

    SLS-UI-8

    You can set the font color and other attributes in STYLE SETTING→STYLE(MAIN).

    SLS-UI-9

    Add a Label2 to display the humidity value in the same way. You can also directly right-click the Label1 to duplicate it.

    SLS-UI-10

    Then set different positions for the Label2.

    SLS-UI-11

    Modify the text content to display a default value.

    SLS-UI-18

  7. Add Button widget to control the LED.

    Click "Button" in the "Widgets" area, and "Button1" will be added to the current Screen.

    SLS-UI-12

    The position and size of the label can be adjusted by dragging the mouse. You can also directly enter numbers in the Inspector→BUTTON→Transform to adjust.

    SLS-UI-13

    Add an identification symbol to the button. The button in this tutorial controls the LED switch, so you only need to mark the button "on" and "off". You can add LABEL widgets or add a background images to the button. This tutorial will demonstrate how to add a background image to a button.

    Click the Button1, then find Inspector->STYLE SETTINGS ->STYLE(MAIN) ->Background, and select the image.

    SLS-UI-14

    SLS-UI-15

    In the same way, duplicate a Button widget. And drag it to the corresponding position to modify different background image.

    SLS-UI-16

    SLS-UI-17

    Set the status of the button to identify different states.

    In "Inspector"->"STYLE SETTINGS"->"STATE", set display white background color by DEFAULT and red when on the PRESSED state.

    SLS-UI-19

    SLS-UI-20

    Make the same settings for the "OFF" button.

  8. Add events to buttons.

    Note: Because the button controls the on and off of the LED, we can add any event here to generate the code framework for the button event when exporting the UI file. We will modify the code of the button event to control the LED latter.

    Select the button and click "ADD EVENT".

    SLS-UI-21

    Select "released" as the trigger condition, select a trigger event in "Action". It will be modified in the generated program to achieve the LED control function.

    SLS-UI-22

    Complete the event. Here I choose to change the screen, and the screen to be switched is Screen1.

    SLS-UI-23

    Add event to Button2 (OFF) in the same way.

    SLS-UI-24

  9. Export UI files.

    Click "File" -> "Project Settings" and make settings for the exported file.

    SLS-UI-25

    Set the export path of the file (set the path according to your own file).

    SLS-UI-26

    Fill in lvgl.h in LVGL Include Path. Check "Flat export(exports all files to one folder )".

    Then click "APPLY CHANGES".

    Tips: After selecting the flat export, the output files will be in the same folder, so that the output code does not need to modify the path in the program. If not, the output files will be classified and placed in different folders. The compiler may not be able to recognize different paths, which will cause some trouble. In this case, the user needs to modify it manually, so it is recommended to select all files to be output to the same folder.

    SLS-UI-27

    Export UI files. The exported files will be in the path we set earlier.

    SLS-UI-28

    SLS-UI-29

  10. Modify the button event code.

    First, define a ‘extern int led;' in the ui.h file to store the status of the LED. The value of this variable is judged to control the on and off of the LED.

    SLS-UI-30

    Then find "FUNCTION" in the ui.c file. Here is the corresponding code generated when we add events in SquareLine.

    SLS-UI-31

    Comment out or delete the code circled in red in the picture above, add new code to assign a value to the LED variable.

    • When button 1 (ON button) is pressed, set the LED value to 1.

    SLS-UI-32

    • When button 2 (OFF button) is pressed, set the LED value to 0.

    SLS-UI-33

    The UI file export is completed, and the button event function is also modified. Next we're going to learn about how to create a PlatformIO project.

Create PlatformIO Project


Please click download to download complete PlatformIO project that can be compiled and run directly.

Now let's explore how to build this project step by step!

Get Started with PlatformIO

Please click the card below to enter the page to get started with PlatformIO.

GetStartedWithPlatformIO

Create a new project

  1. Place the esp32-s3-devkitc-1-myboard.json to the directory in the following picture:

    PIO-1

    Please click download to download the esp32-s3-devkitc-1-myboard.json.

  2. Open Visual Studio Code, click the PlatformIO icon, click QUIK ACCESS 'Open', then click '+New Project'.

    PIO-2

  3. Add a project name "CrowPanel_ESP32_5.0". Select "Espressif ESP32-S3-DevKitC-1-N8 -ELECROW" for the board and Arduino for the framework.

    PIO-3

  4. Add the following code to the platformio.ini file

    build_flags = 
      -D LV_LVGL_H_INCLUDE_SIMPLE
      -I./include
    

    PIO-4

  5. Write the main program in main.cpp.

PIO-5

#include <lvgl.h>
#include <DHT20.h>
#include <SPI.h>
#include <Adafruit_GFX.h>

#include <LovyanGFX.hpp>
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>
#include "ui.h"

#define TFT_BL 2


class LGFX : public lgfx::LGFX_Device
{
public:

  lgfx::Bus_RGB     _bus_instance;
  lgfx::Panel_RGB   _panel_instance;

  LGFX(void)
  {


    {
      auto cfg = _bus_instance.config();
      cfg.panel = &_panel_instance;

      cfg.pin_d0  = GPIO_NUM_8; // B0
      cfg.pin_d1  = GPIO_NUM_3;  // B1
      cfg.pin_d2  = GPIO_NUM_46;  // B2
      cfg.pin_d3  = GPIO_NUM_9;  // B3
      cfg.pin_d4  = GPIO_NUM_1;  // B4

      cfg.pin_d5  = GPIO_NUM_5;  // G0
      cfg.pin_d6  = GPIO_NUM_6; // G1
      cfg.pin_d7  = GPIO_NUM_7;  // G2
      cfg.pin_d8  = GPIO_NUM_15;  // G3
      cfg.pin_d9  = GPIO_NUM_16; // G4
      cfg.pin_d10 = GPIO_NUM_4;  // G5

      cfg.pin_d11 = GPIO_NUM_45; // R0
      cfg.pin_d12 = GPIO_NUM_48; // R1
      cfg.pin_d13 = GPIO_NUM_47; // R2
      cfg.pin_d14 = GPIO_NUM_21; // R3
      cfg.pin_d15 = GPIO_NUM_14; // R4

      cfg.pin_henable = GPIO_NUM_40;
      cfg.pin_vsync   = GPIO_NUM_41;
      cfg.pin_hsync   = GPIO_NUM_39;
      cfg.pin_pclk    = GPIO_NUM_0;
      cfg.freq_write  = 15000000;

      cfg.hsync_polarity    = 0;
      cfg.hsync_front_porch = 8;
      cfg.hsync_pulse_width = 4;
      cfg.hsync_back_porch  = 43;

      cfg.vsync_polarity    = 0;
      cfg.vsync_front_porch = 8;
      cfg.vsync_pulse_width = 4;
      cfg.vsync_back_porch  = 12;

      cfg.pclk_active_neg   = 1;
      cfg.de_idle_high      = 0;
      cfg.pclk_idle_high    = 0;

      _bus_instance.config(cfg);
    }
            {
      auto cfg = _panel_instance.config();
      cfg.memory_width  = 800;
      cfg.memory_height = 480;
      cfg.panel_width  = 800;
      cfg.panel_height = 480;
      cfg.offset_x = 0;
      cfg.offset_y = 0;
      _panel_instance.config(cfg);
    }
    _panel_instance.setBus(&_bus_instance);
    setPanel(&_panel_instance);

  }
};


LGFX lcd;

//UI

int led;
DHT20 dht20;
SPIClass& spi = SPI;


/*******************************************************************************
   Please config the touch panel in touch.h
 ******************************************************************************/
#include "touch.h"


/* Change to your screen resolution */
static uint32_t screenWidth;
static uint32_t screenHeight;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t disp_draw_buf[800 * 480 / 10];
//static lv_color_t disp_draw_buf;
static lv_disp_drv_t disp_drv;

/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{

  uint32_t w = (area->x2 - area->x1 + 1);
  uint32_t h = (area->y2 - area->y1 + 1);


  //lcd.fillScreen(TFT_WHITE);
#if (LV_COLOR_16_SWAP != 0)
 lcd.pushImageDMA(area->x1, area->y1, w, h,(lgfx::rgb565_t*)&color_p->full);
#else
  lcd.pushImageDMA(area->x1, area->y1, w, h,(lgfx::rgb565_t*)&color_p->full);//
#endif

  lv_disp_flush_ready(disp);

}

void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
  if (touch_has_signal())
  {
    if (touch_touched())
    {
      data->state = LV_INDEV_STATE_PR;

      /*Set the coordinates*/
      data->point.x = touch_last_x;
      data->point.y = touch_last_y;
      Serial.print( "Data x :" );
      Serial.println( touch_last_x );

      Serial.print( "Data y :" );
      Serial.println( touch_last_y );
    }
    else if (touch_released())
    {
      data->state = LV_INDEV_STATE_REL;
    }
  }
  else
  {
    data->state = LV_INDEV_STATE_REL;
  }
  delay(15);
}

void setup()
{

  Serial.begin(9600);
  // Serial.println("LVGL Widgets Demo");
  Wire.begin(19, 20);
  dht20.begin();
  //IO Pin
  pinMode(38, OUTPUT);
  digitalWrite(38, LOW);

  // Init Display
  lcd.begin();
  lcd.fillScreen(TFT_BLACK);
  // lcd.setTextSize(2);
  delay(200);

  lv_init();

  delay(100);
  touch_init();

  screenWidth = lcd.width();
  screenHeight = lcd.height();

  lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * screenHeight / 10);
  //  lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, 480 * 272 / 10);
  /* Initialize the display */
  lv_disp_drv_init(&disp_drv);
  /* Change the following line to your display resolution */
  disp_drv.hor_res = screenWidth;
  disp_drv.ver_res = screenHeight;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register(&disp_drv);

  /* Initialize the (dummy) input device driver */
  static lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = my_touchpad_read;
  lv_indev_drv_register(&indev_drv);
#ifdef TFT_BL
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);
#endif
  ui_init();//开机UI界面

  lv_timer_handler();

  Serial.println( "Setup done" );

}

void loop()
{
  char DHT_buffer[6];
  int a = (int)dht20.getTemperature();
  int b = (int)dht20.getHumidity();
  snprintf(DHT_buffer, sizeof(DHT_buffer), "%d", a);
  lv_label_set_text(ui_Label1, DHT_buffer);
  snprintf(DHT_buffer, sizeof(DHT_buffer), "%d", b);
  lv_label_set_text(ui_Label2, DHT_buffer);

  if(led == 1)
  digitalWrite(38, HIGH);
  if(led == 0)
  digitalWrite(38, LOW);
  lv_timer_handler(); /* let the GUI do its work */
  delay( 10 );
}

Add Libraries

  1. Click the PlatformIO icon, click QUIK ACCESS 'Open', then click 'Libraries'.

    PIO-6

  2. Search for LVGL, and add it to the project.

    PIO-7

    PIO-8

    PIO-9

    PIO-10

    After adding, right click on lvgl and select "Open in Integrated Terminal"

    PIO-17

    Copy the "demos" and "examples" folders to "src" folder

    PIO-18

    Place the lv_conf.h we provide to the path: .pio\libdeps\esp32-s3-devkitc-1-myboard in the project folder.

    PIO-19

    Please click download to download the lv_conf.h file.

  3. Add Adafruit_GFX

    PIO-20

    PIO-21

  4. Add LovyanGFX library

    PIO-22

    PIO-23

    PIO-24

  5. Add GT911

    PIO-25

    PIO-26

    PIO-27

  6. Add Adafruit_Busio

    PIO-28

    PIO-29

    PIO-30

  7. We can see that the library has been added successfully!

    PIO-31

  8. This project uses a temperature and humidity sensor(DHT20). We need to add the DHT20 library. Right-click the "libdeps\esp32-s3-devkitc-1-myb...", click "Reveal in File Explorer", and select the DHT20 library we provided.

    Please click download to download the DHT20 library.

    PIO-32

    PIO-33

Add the UI file into PlatformIO Project

We need to add the UI file (generated from SquareLine Studio) to the PlatformIO project.

The .c file in the UI file should be placed in the /scr folder of the project file, and the .h files should be placed in the /include folder.

PIO-34

PIO-35

Upload the Code

  1. Compile the program.

    Upload-code-1

  2. Select the serial port and upload the code.

    Here we select Auto. The software will automatically select the corresponding serial port for program download. If the automatically selected serial port is incorrect, you can manually select the correct serial port.

    Upload-code-2

  3. Click the upload button to up the program to the board.

    Upload-code-3

  4. The program will run on the board!

    gif2

Code Explanation


  1. Library introduction

    • LVGL: UI library
    • lv_demos: lvgl built-in demos library
    • DHT20.h: temperature and humidity sensor library
    • Adafruit_GFX.h: Adafruit_GFX library is a graphics library provided by Adafruit for drawing graphics on various display devices
    • LovyanGFX.hpp: LovyanGFX library is a library for drawing graphics on embedded systems, providing rich graphics functions and APIs
    • lgfx/v1/platforms/esp32s3/Panel_RGB.hpp: lgfx/v1/platforms/esp32s3/Bus_RGB.hpp:
    • These two libraries are part of the LovyanGFX library, specifically for driving RGB color panels on ESP32-S3 microcontrollers. Panel_RGB.hpp provides functions for communicating with RGB panels, while Bus_RGB.hpp provides functions for communicating with RGB buses, which are usually used to control devices such as LCD screens.
    • touch.h: touch drive
    • ui.h: files generated by squareline studio
    #include <lvgl.h>
    #include <DHT20.h>
    #include <SPI.h>
    #include <Adafruit_GFX.h>
    #include <LovyanGFX.hpp>
    #include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
    #include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>
    //UI
    #include "ui.h"
    
  2. Definition

    • LGFX class, which is a subclass of lgfx::LGFX_Device. The main function is to configure and initialize an RGB color panel, and then connect it to the RGB bus on the ESP32-S3 microcontroller to display graphics on the panel.
    class LGFX : public lgfx::LGFX_Device
    {
    public:
    
      lgfx::Bus_RGB     _bus_instance;
      lgfx::Panel_RGB   _panel_instance;
    
      LGFX(void)
      {
        {
          auto cfg = _bus_instance.config();
          cfg.panel = &_panel_instance;
          
          cfg.pin_d0  = GPIO_NUM_8; // B0
          cfg.pin_d1  = GPIO_NUM_3;  // B1
          cfg.pin_d2  = GPIO_NUM_46;  // B2
          cfg.pin_d3  = GPIO_NUM_9;  // B3
          cfg.pin_d4  = GPIO_NUM_1;  // B4
          
          cfg.pin_d5  = GPIO_NUM_5;  // G0
          cfg.pin_d6  = GPIO_NUM_6; // G1
          cfg.pin_d7  = GPIO_NUM_7;  // G2
          cfg.pin_d8  = GPIO_NUM_15;  // G3
          cfg.pin_d9  = GPIO_NUM_16; // G4
          cfg.pin_d10 = GPIO_NUM_4;  // G5
          
          cfg.pin_d11 = GPIO_NUM_45; // R0
          cfg.pin_d12 = GPIO_NUM_48; // R1
          cfg.pin_d13 = GPIO_NUM_47; // R2
          cfg.pin_d14 = GPIO_NUM_21; // R3
          cfg.pin_d15 = GPIO_NUM_14; // R4
    
          cfg.pin_henable = GPIO_NUM_40;
          cfg.pin_vsync   = GPIO_NUM_41;
          cfg.pin_hsync   = GPIO_NUM_39;
          cfg.pin_pclk    = GPIO_NUM_0;
          cfg.freq_write  = 15000000;
    
          cfg.hsync_polarity    = 0;
          cfg.hsync_front_porch = 8;
          cfg.hsync_pulse_width = 4;
          cfg.hsync_back_porch  = 43;
          
          cfg.vsync_polarity    = 0;
          cfg.vsync_front_porch = 8;
          cfg.vsync_pulse_width = 4;
          cfg.vsync_back_porch  = 12;
    
          cfg.pclk_active_neg   = 1;
          cfg.de_idle_high      = 0;
          cfg.pclk_idle_high    = 0;
    
          _bus_instance.config(cfg);
        }
                {
          auto cfg = _panel_instance.config();
          cfg.memory_width  = 800;
          cfg.memory_height = 480;
          cfg.panel_width  = 800;
          cfg.panel_height = 480;
          cfg.offset_x = 0;
          cfg.offset_y = 0;
          _panel_instance.config(cfg);
        }
        _panel_instance.setBus(&_bus_instance);
        setPanel(&_panel_instance);
    
      }
    };
    LGFX lcd;//
    
    /*
    (1) The LGFX class inherits from lgfx::LGFX_Device, which means it will inherit the member variables and methods defined in LGFX_Device.
    
    (2) In the constructor of the LGFX class, we first create an instance of _bus_instance for lgfx::Bus_RGB and an instance of _panel_instance for lgfx::Panel_RGB.
    
    (3) Next, initialize the RGB bus and RGB panel by configuring the parameters of these two instances. In this code, data pins for each color are set, as well as some parameters related to synchronization signals and clocks, to ensure the correct transmission and display of data.
    
    (4) The configuration of _bus_instance and _panel_instance is based on their respective configuration objects, which are lgfx::Bus_RGB::config_t and lgfx::Panel_RGB::config_t.
    
    (5) Finally, set the bus used by the panel by calling _panel_instance.setBus(&_bus_instance), and then call setPanel(&_panel_instance) to set the panel as the panel of the current device.
    
    (6) Finally, a global LGFX object lcd was created for graphical drawing operations using this configured panel elsewhere.
    */
    
    • Define backlight pins, led variables, and screen resolution parameters. And include touch driver.
    #define TFT_BL 2
    int led;
    #include "touch.h"
    /*Changing the screen resolution*/
    static const uint16_t screenWidth;
    static const uint16_t screenHeight;
    
    • Define a buffer variable to initialize the display driver of LVGL and prepare a buffer to store pixel data that will be rendered to the screen. The size of this buffer should be around 1/10 of the product of screen pixel values, which can balance the main control performance and the smoothness of screen display. Taking 10 as an example, the display will be smoother.
    static lv_disp_draw_buf_t draw_buf;
    static lv_color_t buf1[ 800 * 480/ 10 ];
    static lv_disp_drv_t disp_drv;  // Declare a static variable of type lv_disp_drv_t, disp_drv, to store configuration information for the display drive.
    
    • Initialize temperature and humidity sensors and an instance of SPI library
    // Initialize DHT20 sensor
    DHT20 dht20;
    SPIClass& spi = SPI;
    
  3. Function

    • Screen refresh function, this code is for the refresh function driven by the display in the LittlevGL (LVGL) graphics library. LVGL is an open-source graphics library for embedded systems, used to create graphical user interfaces (GUIs). This function my_disp_flush is a user-defined callback function used to refresh the content of the graphical interface onto the display device.
    /* Display Refresh */
    void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p )
    {
      uint32_t w = ( area->x2 - area->x1 + 1 );
      uint32_t h = ( area->y2 - area->y1 + 1 );
    
       //lcd.fillScreen(TFT_WHITE);
    #if (LV_COLOR_16_SWAP != 0)
     lcd.pushImageDMA(area->x1, area->y1, w, h,(lgfx::rgb565_t*)&color_p->full);
    #else
      lcd.pushImageDMA(area->x1, area->y1, w, h,(lgfx::rgb565_t*)&color_p->full);//
    #endif
      lv_disp_flush_ready( disp );
    }
    
    • A simple touch input device reading function, which is used to convert touch events into the input device data format required by the LVGL library, and output the coordinate information of touch points through serial communication.
    void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
    {
      if (touch_has_signal())
      {
        if (touch_touched())
        {
          data->state = LV_INDEV_STATE_PR;
    
          /*Set the coordinates*/
          data->point.x = touch_last_x;
          data->point.y = touch_last_y;
          Serial.print( "Data x :" );
          Serial.println( touch_last_x );
    
          Serial.print( "Data y :" );
          Serial.println( touch_last_y );
        }
        else if (touch_released())
        {
          data->state = LV_INDEV_STATE_REL;
        }
      }
      else
      {
        data->state = LV_INDEV_STATE_REL;
      }
      delay(15);
    }
    
  4. Set Up Part

    void setup()
    {
      Serial.begin( 9600 ); /*Initializing the Serial Port*/
    
      //IO Port Pins
      pinMode(38, OUTPUT);
      digitalWrite(38, LOW);
    
      //initialization of DHT20 pins(I2C)
      Wire.begin(19, 20);
      dht20.begin();
    
      lv_init(); // LVGL initialization
    
      lcd.begin();
      lcd.fillScreen(TFT_BLACK);
      delay(300);
    
      
      delay(100);
      touch_init(); // Touch initialization
    
    
      /*Obtain the width and height of the screen, and initialize the drawing buffer.*/
      screenWidth = lcd.width();
      screenHeight = lcd.height();
    
      lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * screenHeight / 10);
      //  lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, 480 * 272 / 10);
      /* Initialize the display */
      lv_disp_drv_init(&disp_drv);
      /* Change the following line to your display resolution */
      disp_drv.hor_res = screenWidth;
      disp_drv.ver_res = screenHeight;
      disp_drv.flush_cb = my_disp_flush;
      disp_drv.draw_buf = &draw_buf;
      lv_disp_drv_register(&disp_drv);
    
      /* Initialize the (dummy) input device driver */
      static lv_indev_drv_t indev_drv;
      lv_indev_drv_init(&indev_drv);
      indev_drv.type = LV_INDEV_TYPE_POINTER;
      indev_drv.read_cb = my_touchpad_read;
      lv_indev_drv_register(&indev_drv);
    
      /*Initialize the (virtual) input device driver*/
      static lv_indev_drv_t indev_drv;//Define the input device driver structure
    
      lv_indev_drv_init( &indev_drv );//Initialize the input device driver
    
      indev_drv.type = LV_INDEV_TYPE_POINTER;//Setting the input device type
    
      indev_drv.read_cb = my_touchpad_read;//Define the read callback function
    
      lv_indev_drv_register( &indev_drv );//Registering Input Device Drivers
    
    //Backlight settings
    #ifdef TFT_BL
      pinMode(TFT_BL, OUTPUT);
      digitalWrite(TFT_BL, HIGH);
    #endif
    
    
    // UI initialization
      ui_init();
    lv_timer_handler();
    
    }
    
  5. Main Program Part

void loop()
{

/*① obtain temperature and humidity data and store it in a char array. First, use two integer variables a and b to store the obtained temperature and humidity separately*/
  char DHT_buffer[6];
  int a = (int)dht20.getTemperature();
  int b = (int)dht20.getHumidity();

/*Then store the values in the array and display them on the label label through conversion*/
  snprintf(DHT_buffer, sizeof(DHT_buffer), "%d", a);
  lv_label_set_text(ui_Label1, DHT_buffer);
  snprintf(DHT_buffer, sizeof(DHT_buffer), "%d", b);
  lv_label_set_text(ui_Label2, DHT_buffer);

/*To determine the value of the LED, in the ui. c program, press the "ON" button to set the LED to 1, and control the LED light to turn on.*/
  if(led == 1)
  digitalWrite(38, HIGH);

/*In the ui. c program, press the "OFF" button to set the LED to 0, and at this time, control the LED to turn off.*/
  if(led == 0)
  digitalWrite(38, LOW);

  lv_timer_handler(); /* let the GUI do its work, only by executing this function can the entire animation run. */
  delay( 10 );
}

Resources