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!
Article directory
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
- Baiwen Tutorial:http://lvgl.100ask.org/8.1/intro/index.html
- On-point atom step-by-step teaching video:https://www.bilibili.com/video/BV1ug4y1q7ha?p=1
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
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
Open.vscode/c_cpp_properties.json
, add the path of the newly added library file
Also copy the following
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.
3. Configure color screen files
Open the .pio\build\esp32doit-devkit-v1\TFT_eSPI\User_Setup_Select.h configuration file for modification
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
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
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
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
Change the 0 after if to 1
Change LV_TICK_CUSTOM to 1
Change 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
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
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]
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]