"ESP32-Arduino Development" GUI design LVGL development environment setup tutorial (from project directory to simulator)

Preface: I have been bored lately and I happened to have a tft color screen on hand, so I thought about using it to play with. Since a display is used, UI design is naturally inseparable. lvgl is an embedded open source graphics library with the characteristics of "Light" (lightweight) and "Versatile" (strong usability). For me, the most difficult thing was setting up the initial environment. A lot of enthusiasm for learning was gradually extinguished at this moment. But hard work pays off, and I finally learned a rough idea after spending a day.

Follow my steps and teach you how to build an LVGL development environment from 0 to 1!

1. Preparation

Hardware:
1. ESP32 development version
2. 1.44TFT color screen ST7735S driver [Taobao a>] (Students cannot afford expensive color screens. Other color screens are similar. There are many official built-in driver libraries. Just look for the driver for your own screen and make slight modifications)

Knowledge reserve:
1. LVGL official website: https://lvgl.io/
2. LVGL document: [Official website document] (You may need to access the scientific Internet) [github
3. Other recommended documents

Library file download

A complete LVGL project file contains at least the following library files in its directory

Library file illustrate Link
lvgl lvgl main library https://github.com/lvgl/lvgl
lv_demos lvgl official sample library https://github.com/lvgl/lv_demos
TFT_eSPI tft color screen driver library https://github.com/Bodmer/TFT_eSPI
TFT_Touch tft color screen touch screen driver library https://github.com/Bodmer/TFT_Touch

Download these libraries locally for backup!


2. Project creation (based on VScode+PlatformIO)

I am using the VScode+PlatformIO environment here (see the construction tutorialentrance), and it is similar to developing with arduino IDE.

1. Create a Platform project

Insert image description here

Add monitor_speed = 115200 to the platform.ini configuration file. Its function is to modify the serial port frequency. The official routines of lvgl use the frequency of 115200.


2. Add library files to the platform project

Note: lvgl, TFT_eSPI, and TFT_Touch can all be downloaded directly on the platform platform. Except for lv_demos, they need to be added manually. Therefore, for the sake of unification, I will all add them manually here.

Right-click.pio\libdeps\esp32doit-devkit-v1 Open from the resource manager, add the required library files in this directory
Insert image description here
Insert image description here
Open.vscode/c_cpp_properties.json, add the path of the newly added library file
Insert image description here
Also copy the following
Insert image description here

Note: If there is no error, it is correct. If there is an error, check whether the path is correct. If the configuration is not successful here, an error will be reported when compiling later that the xx.h file cannot be found. 99% of the reasons are here, because it is added manually. Therefore, the platform.ini configuration file does not need to add imported library files, but it must add the lib_deps field (leave it blank), otherwise the above json file will be automatically modified during compilation.
Insert image description here


3. Configure color screen files

Open the .pio\build\esp32doit-devkit-v1\TFT_eSPI\User_Setup_Select.h configuration file for modification

Insert image description here
You can only uncomment one configuration file. Uncommenting more than one will result in an error. The official built-in configuration files are more than 60 common screen drivers. Of course, users can also set a configuration file themselves, which is ./User_Setup. .h configuration file, uncomment and go to the file to configure related options.
Since there is already a ST7735 configuration file here, I will use the official one directly.

Enter the .pio\build\esp32doit-devkit-v1\TFT_eSPI\User_Setups\Setup7_ST7735_128x128.h file and make slight modifications
Insert image description here
Note: All configuration files must be hugged Make modifications that are not necessary and don’t change if you don’t know its function, otherwise you will suffer a lot (personal experience)

Attached here is an ESP32 pin diagram
Insert image description here


4. Test whether the color screen is available

After making the above modifications, you can test whether the color screen is configured normally. After connecting the cables in order, open the file.\src\main.cpp and add the official color test code. In .pio\build\esp32doit-devkit-v1\TFT_eSPI\examples\Test and diagnostics\Colour_Test\Colour_Test.ino, as follows

#include <SPI.h>
#include <TFT_eSPI.h>       // Hardware-specific library
TFT_eSPI tft = TFT_eSPI();  // Invoke custom library
void setup(void) {
    
    
  tft.init();
  tft.fillScreen(TFT_BLACK);
  // Set "cursor" at top left corner of display (0,0) and select font 4
  tft.setCursor(0, 0, 4);
  // Set the font colour to be white with a black background
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  // We can now plot text on screen using the "print" class
  tft.println("Intialised default\n");
  tft.println("White text");
  
  tft.setTextColor(TFT_RED, TFT_BLACK);
  tft.println("Red text");
  
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.println("Green text");
  
  tft.setTextColor(TFT_BLUE, TFT_BLACK);
  tft.println("Blue text");
  delay(5000);
}

void loop() {
    
    
	// 设置文字颜色并打印
  tft.invertDisplay( false ); // Where i is true or false
  tft.fillScreen(TFT_BLACK);
  tft.setCursor(0, 0, 4);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.println("Invert OFF\n");
  tft.println("White text");
  tft.setTextColor(TFT_RED, TFT_BLACK);
  tft.println("Red text");
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.println("Green text");
  tft.setTextColor(TFT_BLUE, TFT_BLACK);
  tft.println("Blue text");
  delay(5000);


  // Binary inversion of colours
  // 反转屏幕颜色
  tft.invertDisplay( true ); // Where i is true or false
  tft.fillScreen(TFT_BLACK);
  
  tft.setCursor(0, 0, 4);
  // 设置文字颜色并打印
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.println("Invert ON\n");
  tft.println("White text");
  tft.setTextColor(TFT_RED, TFT_BLACK);
  tft.println("Red text");
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.println("Green text");
  tft.setTextColor(TFT_BLUE, TFT_BLACK);
  tft.println("Blue text");
  delay(5000);
}

The purpose of each function in the code is easy to understand. After uploading it to the ESP32 development version, check whether the color of the text matches the color described in the text. If it does not match, refer to the instructions on the first two pictures. If the color screen configuration is unsuccessful, then the lvgl in the back will naturally Can't be displayed either
Insert image description here


5. Configure LVGL

With the TFT_eSPI library, lvgl also has configuration files for modification.

Open.pio\libdeps\esp32doit-devkit-v1\lvgl\lv_conf_template.h, copy a file to the same directory, and rename it tolv_conf.h
Insert image description here

Change the 0 after if to 1
Insert image description hereChange LV_TICK_CUSTOM to 1
Insert image description hereChange other configurations according to your needs


6. Test LVGL case

Open.pio\libdeps\esp32doit-devkit-v1\lvgl\examples\arduino\LVGL_Arduino\LVGL_Arduino.ino file and copy the code to/src/main.cpp. The official case includes touch function testing, but since my color screen does not have touch function, The code needs to be modified as follows

#include <lvgl.h>
#include <TFT_eSPI.h>
/*If you want to use the LVGL examples,
  make sure to install the lv_examples Arduino library
  and uncomment the following line.
#include <lv_examples.h>
*/

#include <lv_demo.h>

TFT_eSPI tft = TFT_eSPI(); /* TFT instance */

/*屏幕的宽高在这里修改*/
static const uint32_t screenWidth  = 128;
static const uint32_t screenHeight = 128;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * 10 ];

//开启日志后调用的函数,启用该功能需要修改lvgl_conf.h的对应功能
#if LV_USE_LOG != 0
/* Serial debugging */
void my_print( lv_log_level_t level, const char * file, uint32_t line, const char * fn_name, const char * dsc )
{
    
    
   Serial.printf( "%s(%s)@%d->%s\r\n", file, fn_name, line, dsc );
   Serial.flush();
}
#endif

/* 刷新屏幕 */
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 );

   tft.startWrite();
   tft.setAddrWindow( area->x1, area->y1, w, h );
   tft.pushColors( ( uint16_t * )&color_p->full, w * h, true );
   tft.endWrite();

   lv_disp_flush_ready( disp );
}


void setup()
{
    
    
   Serial.begin( 115200 ); /* prepare for possible serial debug */
   Serial.println( "Hello Arduino! (V8.0.X)" );
   Serial.println( "I am LVGL_Arduino" );

   lv_init();

#if LV_USE_LOG != 0
   lv_log_register_print_cb( my_print ); /* register print function for debugging */
#endif

   tft.begin();          /* TFT init */
   tft.setRotation( 3 ); /* 旋转屏幕,n * 90度 ,3表示270度*/

  // 建立一个屏幕宽*10大小的缓冲区
   lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * 10 );

   /*初识化屏幕*/
   static lv_disp_drv_t disp_drv;
   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 );

   /*初识化输入设备*/
   static lv_indev_drv_t indev_drv;
   lv_indev_drv_init( &indev_drv );
   indev_drv.type = LV_INDEV_TYPE_POINTER;
   lv_indev_drv_register( &indev_drv );

#if 0	//取消注释会在屏幕中显示文字
   /* Create simple label */
   lv_obj_t *label = lv_label_create( lv_scr_act() );
   lv_label_set_text( label, "Hello Arduino! (V8.0.X)" );
   lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
#else

   // 取消注释会启用对应的案例
   lv_demo_widgets();            // OK
   // lv_demo_benchmark();          // OK
   // lv_demo_keypad_encoder();     // works, but I haven't an encoder
   // lv_demo_music();              // NOK
   // lv_demo_printer();
   // lv_demo_stress();             // seems to be OK
#endif
   Serial.println( "Setup done" );
}

void loop()
{
    
    
   lv_timer_handler(); /* 在循环中让lvgl处理一些相应的事件 */
   delay( 5 );
}

Since the screen is too small, I can’t fit the whole case, hhh
Insert image description here


7.next?

Since it is UI design, how to design a UI? This requires learning the official components of LVGL, such as text, sliders, input boxes, etc. This development method may be similar to the pyqt5 I learned before. I choose the building blocks that suit me from different components and finally build a fortress. , of course, you can also transplant it from other people's lvgl UI. The UI part of lvgl developed in C language is universal. A simple UI example is given below.

	//创建一个标签,如同画板(lv_src_act()用于获取当前活跃的屏幕)
   lv_obj_t *label = lv_label_create( lv_scr_act() );
   // 在画板上写上文字
   lv_label_set_text( label, "Hello World!I'm fine!" );
   // 设置画板上的对齐方式,也就是布局
   lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );

Now that the UI part is available, how to use it?
In fact, the code in the above case is common to all Arduino development boards. It is basically used as a template. Of course, you need to explore it yourself for deeper use
Insert image description here

Don’t want to bother? Of course, there is also a way to download the entire project file (including the simulator project). Just download and import the platform project [Portal]
Insert image description here


3. Use of LVGL simulator (based on VS2019)

Isn’t it troublesome to flash the firmware every time you design a UI? Therefore, with the help of the LVGL simulator, you can directly view the UI you designed on your computer, and then transplant it to the Arduino project after meeting your expectations.

Since the article is too long, I will introduce it in the next blog—>[Portal]

Guess you like

Origin blog.csdn.net/qq_45516773/article/details/119673328