微信关注 “DLGG创客DIY”设为“星标”,重磅干货,第一时间送达。

转载自慕容流年 https://me.csdn.net/qq_41868901

1. LVGL简介

LittlevGL是一个免费的开源图形库,提供了创建嵌入式GUI所需的一切,具有易于使用的图形元素、漂亮的视觉效果和低内存占用。使用效果可以去:LittlevGL开源GUI看看,使用效果真的很是惊艳,这里使用群友的一张图来看看近年来各种GUI图形库的发展趋势:

2. 演示效果

对于「ESP32」上使用「LVGL」,我在三种设备上进行了测试,屏幕驱动型号分别为:「1.14寸ST7789V」「3.5寸ILI9488」「3.5寸ST7796S」,为了方便对比,我在他们上边创建了同样的仪表控件,下面请看演示效果:

  1. 「我自己的小手表」我在前几个月基于ESP32制作的小手表,集成多种功能,硬件资源有:「1.14寸屏幕」「自动下载电路」「温湿度」「RTC时钟」「大气压计」「光亮度传感」「加速度计」「拨轮按键」「TFT卡」「蜂鸣器」「振动马达」「WS2812RGB灯」「锂电池管理」,可以说是可以满足目前的开发要求了;「项目地址 :」 「ESP32-Watch」

  2. 「启明云端GUI开发板」该开发板是「启明云端」公司推出的一款基于ESP32的GUI开发板,搭载了「3.5寸ST7796S屏幕」「FT6336U电容触摸」,开发平台为自研的「8ms创新视界」拖拽式平台,有点类似「Mixly」吧,具体使用效果请查看:ESP32GUI开发板
    屏幕和触摸的驱动,我也进行了移植和修改,下面放出修改后的库:
    ==①「3.5寸ST7796S屏幕驱动」==                              ==②「FT6336U电容触摸驱动」==
    移植了LVGL仪表盘的演示效果:

  3. 「3.5寸ILI9488屏幕」这种屏幕相信某宝能随处买到了,屏幕硬件为:「3.5寸ILI9488屏幕」「XPT2046电阻触摸」,屏幕分辨率为480x320,在初始化触摸屏时,也要注意触摸分辨率也要初始化为480x320,并设置好触摸方向,下面看演示效果:

看完这些演示,你应该明白我为什么使用LVGL了吧,同样的GUI源码可以很方便的在各种移植了LVGL的硬件上使用,达到同样的演示效果,这是我最喜欢的part了

3. 开始移植

3.1 源码准备

3.1.1 目前「lvgl」在GitHub上已经有了Arduino上的库支持,库名字为 「lv_arduino」进去后你可以发现该库已经有很多版本了,可以根据自己的喜好下载,并放入到你的「Arduino」「Library」文件夹下:

  1. 「lv_arduino V2.1.5」 版本对应的 「LVGL」 版本为V6,适合已经习惯 「LittlevGL V6」 的老师傅们了。

  2. 「lv_arduino V3.0.1」 版本对应的 「LVGL」 版本为V7,适合正在学习的新人们,但是无法兼容老版本的GUI程序。

3.1.2 完成以上操作,你可以根据你选择的 「lv_arduino」  版本下载 「LVGL」 的例程进行学习,版本对应关系请看上述“1和2”,例程链接为:「lv_examples」

3.1.3  「lv_arduino」 给出的 examples 使用的是  「TFT_eSPI」 库,这个库刷屏速度比其他库要快,配合 lv_arduino 的例程可以直接使用。

3.2 学习文档

  1. LVGL V7.3.1开发文档
  2. LVGL V7.1.0开发文档
  3. LVGL V6.1.2开发文档

当然,嫌麻烦的,可以把文档下载下来,进去之后页面顶部有PDF下载按钮。但是,这种英文文档对我们来说着实不友好,尤其是我这种英语四级还没通过的zhazha,还记得我之前提过GUI代码是通用的嘛,因此你可以学习其他厂商的LVGL教程,毕竟GUI代码通用,只是接口移植部分不一样而已。

  1. 正点原子手把手教你学littleVGL【轻量级开源GUI】
  2. 微雪电子 STM32之littlevGL系列教程

3.3 移植

==由于屏幕众多,就不一一演示移植过程了,下面就以最简单的 「3.5寸 ILI9488」屏幕为例,「lv_arduino」 库版本为 「lv_arduino V3.0.1」 ,购买链接就不放出来了,大家通过图片在某宝搜索即可,尺寸随意,但是我感觉3.5寸显示更漂亮:==屏幕的引脚说明为:

【屏幕驱动】:「TFT_eSPI」
【触摸驱动】:「TFT_Touch」
【LVGL库】:「lv_arduino」

3.3.1  第1步(下载库)

「TFT_eSPI」「TFT_Touch」「lv_arduino」 三个库放入到你的「Arduino」「Library」文件夹下。

3.3.2  第2步(修改屏幕驱动库TFT_eSPI)

打开「Arduino」「Library」文件夹下的「TFT_eSPI」目录,打开 「User_Setup_Select.h」 文件:

将第22行的

#include            // Default setup is root library folder`  

注释掉为

//#include            // Default setup is root library folder`  

将第47行的

//#include            // Setup file for ESP32 and ILI9488 SPI bus TFT`  

取消注释为

#include            // Setup file for ESP32 and ILI9488 SPI bus TFT`  

完成以上操作后打开 「User_Setups」 目录下的 「Setup21_ILI9488.h」 文件:

将其内容删掉并修改为:

// See SetupX_Template.h for all options available

#define ILI9488_DRIVER

//#define TFT_INVERSION_OFF

#define TFT_MISO 19 // (leave TFT SDO disconnected if other SPI devices share MISO)#define TFT_MOSI 23#define TFT_SCLK 18#define TFT_CS    15  // Chip select control pin#define TFT_DC    2  // Data Command control pin#define TFT_RST   4  // Reset pin (could connect to RST pin)#define TFT_BL    21 //背光引脚

#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts

#define SMOOTH_FONT

// #define SPI_FREQUENCY  20000000// #define SPI_FREQUENCY  27000000// #define SPI_FREQUENCY  40000000// #define SPI_FREQUENCY  80000000

#define SPI_FREQUENCY  60000000

// Optional reduced SPI frequency for reading TFT#define SPI_READ_FREQUENCY  16000000

#define SPI_TOUCH_FREQUENCY  2500000

3.3.3  第3步(ESP32与屏幕接线)

屏幕引脚 ESP32引脚
VCC 5V
GND GND
CS IO15
RESET IO4
DC/RS IO2
SDI(MOSI) IO23
SCK IO18
LED IO21
SDO(MISO) IO19
—— ——
T_CLK IO25
T_CS IO26
T_DIN IO27
T_DO IO14
T_IRQ 不接

3.3.4 第4步 (测试例程)

/*** @name:liuzewen* @title:lvgl_test* @time:2020/8/14*/#include #include #include #include #include 

#define LVGL_TICK_PERIOD 60

TFT_eSPI tft = TFT_eSPI(); /* TFT instance */static lv_disp_buf_t disp_buf;static lv_color_t buf[LV_HOR_RES_MAX * 10];

lv_obj_t * slider_label;int screenWidth = 480;int screenHeight = 320;

//触摸#define DOUT 14  /* Data out pin (T_DO) of touch screen */#define DIN  27  /* Data in pin (T_DIN) of touch screen */#define DCS  26  /* Chip select pin (T_CS) of touch screen */#define DCLK 25  /* Clock pin (T_CLK) of touch screen */TFT_Touch touch = TFT_Touch(DCS, DCLK, DIN, DOUT);int X_Raw = 0, Y_Raw = 0;

#if USE_LV_LOG != 0/* Serial debugging */void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc){

  Serial.printf("%s@%d->%s\r\n", file, line, dsc);  delay(100);}#endif

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

  tft.startWrite(); /* Start new TFT transaction */  tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */  for (int y = area->y1; y <= area->y2; y++) {    for (int x = area->x1; x <= area->x2; x++) {      c = color_p->full;      tft.writeColor(c, 1);      color_p++;    }  }  tft.endWrite(); /* terminate TFT transaction */  lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */}

bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data){    uint16_t touchX, touchY;

    bool touched = touch.Pressed();//检测触摸是否按下    //获取屏幕坐标    touchX = touch.X();    touchY = touch.Y();

    if(!touched)    {      return false;    }

    if(touchX>screenWidth || touchY > screenHeight)    {      Serial.println("Y or y outside of expected parameters..");      Serial.print("y:");      Serial.print(touchX);      Serial.print(" x:");      Serial.print(touchY);    }    else    {

      data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 

      /*Save the state and save the pressed coordinate*/      //if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);

      /*Set the coordinates (if released use the last pressed coordinates)*/      data->point.x = touchX;      data->point.y = touchY;

      Serial.print("Data x");      Serial.println(touchX);

      Serial.print("Data y");      Serial.println(touchY);

    }

    return false; /*Return `false` because we are not buffering and no more data to read*/}

lv_obj_t * gauge1;long date = 0;uint8_t date_cotter = 0;

void setup() {

  //屏幕背光采用PWM调光  ledcSetup(10, 5000/*freq*/, 10 /*resolution*/);  ledcAttachPin(TFT_BL, 10);  analogReadResolution(10);  ledcWrite(10,1023);

  Serial.begin(115200); /* prepare for possible serial debug */

  lv_init();

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

  //屏幕初始化  tft.begin(); /* TFT init */  tft.setRotation(1);

  //触摸初始化  touch.setCal(481, 3395, 755, 3487, 480, 320, 1);  //旋转  touch.setRotation(3);

  lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

  //显示刷新接口  lv_disp_drv_t disp_drv;  lv_disp_drv_init(&disp_drv);  disp_drv.hor_res = screenWidth;  disp_drv.ver_res = screenHeight;  disp_drv.flush_cb = my_disp_flush;  disp_drv.buffer = &disp_buf;  lv_disp_drv_register(&disp_drv);

  //触摸板输入接口  lv_indev_drv_t indev_drv;  lv_indev_drv_init(&indev_drv);             /*Descriptor of a input device driver*/  indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/  indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/  lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/

   //放置仪表盘控件    static lv_color_t needle_colors[1];    needle_colors[0] = LV_COLOR_PURPLE;    //gauge控件    gauge1 = lv_gauge_create(lv_scr_act(), NULL);    lv_gauge_set_needle_count(gauge1, 1, needle_colors);    lv_obj_set_size(gauge1, 300, 300);    lv_obj_align(gauge1, NULL, LV_ALIGN_CENTER, 0, 0);    //设置仪表指针指向的值    lv_gauge_set_value(gauge1, 0, 0);

    date = millis();}

void loop() {  lv_task_handler(); /* let the GUI do its work */  delay(5);  if(millis()-date>20)  {    date = millis();    date_cotter++;    date_cotter = date_cotter>100?0:date_cotter;    //刷新仪表指针指向的值    lv_gauge_set_value(gauge1, 0, date_cotter);    Serial.printf("date_cotter: %d\n",date_cotter);  }}

上传程序到你的ESP32开发板,即可看到屏幕上出现仪表控件,并且指针也在转圈圈,哈哈!

3.3.5 第5步 (跑一下官方demo)

最后在启明云端的板子和3.5寸的ILI9488屏幕上跑一下LVGL官方的demo程序lv_demo_widgets(),下面放出演示效果:

3.3.6 第6步 (注意事项)

==如果你按照过程操作,却未看到预想的效果,请注意重新认真看一遍本文档,并留意其中每一句话。==

转载自慕容流年 https://me.csdn.net/qq_41868901

你点的每个在看,我都当成喜欢

arduino tft 方向_ESP32在Arduino环境下玩转 LVGL,ESP32移植LVGL详细教程相关推荐

  1. 在MAC环境下玩转树莓派

    在MAC环境下玩转树莓派 一.Mac使用终端装系统 二.Mac使用终端连接ssh 之前我们拍的基础视频都是在windows环境下进行写系统还有ssh连接这些基础操作. 那么这期教程就是对之前基础教程的 ...

  2. 基于keil环境下mm32f327单片机rtthread的移植

    基于keil环境下mm32f327单片机rtthread的移植 文章目录 基于keil环境下mm32f327单片机rtthread的移植 前言 一.所需资源 二.创建工程目录 三.复制所需文件到相应文 ...

  3. Ubuntu 22.04环境下安装lxr源码阅读器详细过程

    Ubuntu 22.04环境下安装lxr源码阅读器详细过程 一.lxr介绍 二.依赖关系 三.安装过程 1.下载源码 2.执行检查 3.安装依赖 4.安装数据库和服务器 四.配置过程 1.主配置 2. ...

  4. centos安装mysql5.7.19_Linux下Centos7安装Mysql5.7.19的详细教程

    1.下载mysql 2.选择源码包,通用版点击下载 直接下载就可以了,不用登录 3.解压编译 tar -zxvf mysql-5.7.19.tar.gz cd mysql-5.7.19.tar.gz ...

  5. arduino tft 方向_Arduino库教程-TFT Library

    TFT Library 可以在Arduino TFT图形显示器上绘制文本,图像,和形状,更多的信息参考the Reference for the TFT Library page.适用于所有的Ardu ...

  6. WIN10环境下配置hadoop+spark并运行实例的教程

    WIN10环境下配置 hadoop + spark 并运行开发实例的教程 前期准备 基本环境配置 虚拟机的安装 配置虚拟机中的静态网络 关闭并禁用防火墙 配置主机名 编辑host文件 使用ssh传输文 ...

  7. linux环境下玩转截图

    当习惯了使用linux环境处理事务时,总少不了截图的需求.windows环境下有各种截图工具方便大家进行截图处理,那么linux环境下都有哪些截图方式或工具呢?这里就给大家盘点一下linux环境下几种 ...

  8. 宝塔linux面板 h5ai,宝塔面板丨Nginx环境下H5ai(Dplayer)完整安装使用教程及注意事项...

    请注意,本文编写于 929 天前,最后修改于 123 天前,其中某些信息可能已经过时. 关于如何搭建 H5ai ,网上虽然有很多教程,但详细的却不多,有的也是比较模糊.本文将介绍一下如何在宝塔Ngin ...

  9. clion配置_Ubuntu16.04系统下用CLion编译器调试ROS代码详细教程

    本教程主要实践如何创建一个ROS工作空间和功能包实现基于ROS的信息发送和接收,同时用CLion如何去调试这个ROS工程.ROS允许多个工作空间并存,每个工作空间中创建需要的功能包,功能包创建于工作空 ...

最新文章

  1. 中setting怎么配置_maven的安装与配置(保姆级教学)
  2. 人工智能不仅仅是智能生活,还有失业问题!
  3. linux软件安装简介(apt和dpkg)
  4. The type org.springframework...DaoSupport cannot be resolved. It is indirectly..
  5. [原创].如何解决Nios II SBTE中出现的undefined reference to `xxx'警告
  6. ant混淆编译java web,Android中使用ant混淆编译
  7. 分布式事务2PC、3PC模型
  8. arm-linux-gnueabi和arm-linux-gnueabihf 的区别
  9. 【李宏毅2020 ML/DL】P88-96 Meta Learning – MAML | Reptile
  10. [新增:鸵鸟]软件开发团队的脓包:皇帝的新装、口号党、鸵鸟、废话迷
  11. python主函数怎么写_python主方法怎么写
  12. 炒股杠杆-API智能交易软件基本函数
  13. 数值分析的学科体系_清华大学 数值分析 视频教程
  14. Python实现简易图形用户界面计算器
  15. 二. 再熟悉 Markdown 标准语法
  16. 信息系统项目管理师必背核心考点(四)UML类与类之间的关系
  17. 【Python turtle】使用turtle实现随机满天星星效果(完整代码+效果图)
  18. 解决ChatGPT网络总是掉线问题
  19. R语言 tidyverse 之数据处理:dplyr (中)
  20. 涂鸦LZ201-CN开发板学习笔记(一)

热门文章

  1. 揭密|淘宝服务端千万级高并发架构的演进之路
  2. IEEE 回应禁止华为系审稿人;WiFi联盟、蓝牙联盟已恢复华为成员资格;中国计算机学会:暂时中止与IEEE通信学会合作……...
  3. 动态后台获取_后台管理系统的权限以及vue处理权限的思路
  4. overflowhidden把内容遮住了怎么办_图片有水印怎么办?不用PS,有这4招就够了
  5. VS Code 中的文件添加图标的插件vscode-icons
  6. JsonData工具类
  7. Flowable 数据库表结构 ACT_HI_VARINST
  8. Mybatis-plus批量插入、批量修改数据saveBatch等速度缓慢
  9. linux 修改当前系统时间
  10. Centos7 使用Docker 安装Oracle 截图+关键步骤说明