《ESP32-Arduino开发》GUI设计 LVGL 开发环境搭建教程(从工程目录到模拟器)

前言:目前还在学习ROS+无人机框架中,,,
更多更新文章详见我的个人博客主页【前往】

前言:最近闲着无聊,看到手头正好有一块tft彩屏,想着拿来玩玩。既然用到了显示屏,自然是离不开ui设计,lvgl是嵌入式一个开源图形库,具备“Light”(轻量)和"Versatile"(可用性强)等特点。对于我而言,最难的莫过于最初的环境搭建了,许多学习的热情在此刻被逐渐浇灭。但功夫不负有心人,花了一天终于是学会了个大概。

跟随我的步伐,教你从0到1搭建LVGL开发环境!

1.准备工作

硬件:
1. ESP32开发版
2. 1.44TFT彩屏 ST7735S驱动【淘宝】(学生党,买不起贵的彩屏,其他彩屏类似,官方内置了很多驱动库,认准自己屏幕的驱动,稍作修改即可)

知识储备:
1. LVGL官网: https://lvgl.io/
2. LVGL文档:【官网文档】 (可能需要科学上网) 【github
3. 其他推荐文档

库文件下载

一个完善的LVGL工程文件,其目录下至少包含以下库文件

库文件说明链接
lvgllvgl主库https://github.com/lvgl/lvgl
lv_demoslvgl官方示例库https://github.com/lvgl/lv_demos
TFT_eSPItft彩屏驱动库https://github.com/Bodmer/TFT_eSPI
TFT_Touchtft彩屏触摸屏驱动库https://github.com/Bodmer/TFT_Touch

将这些库都下载到本地以做备用!


2.工程创建(基于VScode+PlatformIO)

我这里使用的是VScode+PlatformIO环境(搭建教程见入口),用arduino IDE开发类似。

1.创建Platform工程

在这里插入图片描述

在platform.ini配置文件中加入monitor_speed = 115200,其作用就是修改串口频率,lvgl官方例程使用的都是115200的频率


2.向platform工程中添加库文件

说明:lvgl,TFT_eSPI,TFT_Touch都是能在platform平台上直接下载到的,除lv_demos除外,需要手动添加,因此,为了统一,我这里全部统一为手动添加。

右击 .pio\libdeps\esp32doit-devkit-v1 从资源管理器中打开,在这个目录下添加所需的库文件
在这里插入图片描述
在这里插入图片描述
打开.vscode/c_cpp_properties.json,添加新添加库文件的路径
在这里插入图片描述
下面的也复制一份
在这里插入图片描述

注:没标错就是没错,标错的查看路径是否正确,这里没配置成功的话,到后面编译时报错xx.h文件找不到,99%的原因都是在这里,由于是手动添加,因此platform.ini配置文件不用添加导入的库文件,但要添加lib_deps字段(后边留空),否则编译的时候会自动修改上述的json文件的
在这里插入图片描述


3.配置彩屏文件

打开.pio\build\esp32doit-devkit-v1\TFT_eSPI\User_Setup_Select.h配置文价进行修改

在这里插入图片描述
配置文件只能取消注释一个,取消注释多个会报错,官方内置了60多个常见的屏幕驱动的配置文件,当然,也可以用户自己设定一个配置文件,就是./User_Setup.h配置文件,取消注释并到该文件下进行相关选项的配置,
由于这里已经有ST7735的配置文件了,我就直接用官方的了。

进入.pio\build\esp32doit-devkit-v1\TFT_eSPI\User_Setups\Setup7_ST7735_128x128.h文件中,进行略微的修改
在这里插入图片描述
注:所有的配置文件,一定要抱着非必要的,不知道其作用的就不改的原则进行修改,否则将会吃很多亏的(亲身经历)

这里附一张ESP32引脚图
在这里插入图片描述


4.测试彩屏是否可用

按上述修改后就可以测试彩屏是否正常配置了,按顺序连接好线后,打开.\src\main.cpp文件,加入官方提供的颜色测试代码,在.pio\build\esp32doit-devkit-v1\TFT_eSPI\examples\Test and diagnostics\Colour_Test\Colour_Test.ino,如下

#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);
}

代码各个函数的用途很好理解,上传到ESP32开发版上后查看文字的颜色是否跟文字描述的颜色相符,不符则看前2张图上的说明,彩屏若配置不成功,那后面的lvgl自然也无法显示了
在这里插入图片描述


5.配置LVGL

同TFT_eSPI库,lvgl也有配置文件进行修改

打开.pio\libdeps\esp32doit-devkit-v1\lvgl\lv_conf_template.h,复制一份文件到同目录下,并重命名为lv_conf.h
在这里插入图片描述

将if后面的0改为1
在这里插入图片描述将LV_TICK_CUSTOM修改为1
在这里插入图片描述其他的配置就根据自己需求修改


6.测试LVGL案例

打开.pio\libdeps\esp32doit-devkit-v1\lvgl\examples\arduino\LVGL_Arduino\LVGL_Arduino.ino文件,复制代码到/src/main.cpp中,官方给的案例包含触摸功能测试,但由于我的彩屏没有触摸功能,因此需要对代码进行修改,如下

#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 );
}

由于屏幕太小了,无法放下整个案例,hhh
在这里插入图片描述


7.next?

既然是ui设计,如何设计一个属于ui呢?这就需要学习LVGL官方的组件了,如文字,滑动条,输入框等等,这种开发方式可能就跟我之前学的pyqt5类似吧,从不同组件中挑选符合自己的积木,最终搭成堡垒,当然,你也可以从别人的lvgl的UI中移植过来,用C语言开发的lvgl的UI部分都是通用的,下面给出一个简单UI示例

	//创建一个标签,如同画板(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 );

那UI部分有了,如何使用呢?
其实上上案例中的代码是对于所有的arduino开发板都通用的,基本就是套模板使用,当然,更深层次的使用就需要自己慢慢探索了
在这里插入图片描述

不想麻烦?当然,这里也提供一整个工程文件下载方式(包括模拟器工程),下载导入platform工程即可【传送门
在这里插入图片描述


3.LVGL模拟器的使用(基于VS2019)

每设计一个UI就要刷固件岂不是很麻烦?因此,借助LVGL模拟器,可以直接在电脑上查看自己设计的UI,满足心中预想后就可移植到Arduino工程中。

由于文章篇幅过大,因此在下一篇博客中再介绍—>【传送门

  • 28
    点赞
  • 143
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 30
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MGodmonkey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值