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

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

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

1. LVGL简介

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

2. 演示效果

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

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

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

    a7c59111643c02294f5e9295566643f6.png

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

看完这些演示,你应该明白我为什么使用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寸显示更漂亮:==96b94318f291f15d7aba5555a26dd19b.png屏幕的引脚说明为:a69bcc5ec30484328cc195168d658339.png

【屏幕驱动】:「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引脚
VCC5V
GNDGND
CSIO15
RESETIO4
DC/RSIO2
SDI(MOSI)IO23
SCKIO18
LEDIO21
SDO(MISO)IO19
————
T_CLKIO25
T_CSIO26
T_DINIO27
T_DOIO14
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(),下面放出演示效果:5b75502e88db833ff3f83d177c1c7fd7.png23fbb68c2b64f807e80fad49732f805d.png

3.3.6 第6步 (注意事项)

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

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

0f2dd2f6ea3b6f28642cab5d90734ab2.png

56a5911f7d7ab532fe0be9652cc61d88.png你点的每个在看,我都当成喜欢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/528884.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux内核开文件系统,内核必须懂(二): Linux文件系统初探

目录前言文件系统结构新建文件和inode文件创建过程inode解析打开文件参考最后前言这次来说文件系统. 文件系统是非常重要的, 提高磁盘使用率, 减小磁盘磨损等等都是文件系统要解决的问题. 市面上的文件系统也是数不胜数, 比较常用的像ext4, xfs以及ntfs等等, 国内的像鹅厂的tfs…

gps卫星位置计算程序matlab_科研项目 | BD/ GPS卫星导航仿真测试系统研究

一、项目背景在移动互联和互联网的时代&#xff0c;卫星导航定位已经成为生活中不可或缺的部分。目前&#xff0c;我国的交通、银行、电力、采矿、测绘等部门以及大众化市场都需要大量的定位、授时服务。许多企业也形成了覆盖卫星导航相关材料及元器件、卫星导航芯片、卫星导航…

linux docker权限,linux - 如何解决ubuntu中的docker权限问题? - Ubuntu问答

问题描述我已经按照here的说明安装了docker。我使用Ubuntu Trusty 14.04 (LTS) (64-bit)。安装过程中的一切都很好。另外&#xff0c;命令$ sudo docker run -i -t ubuntu /bin/bash可以很好地完成(在打开的控制台中键入”exit”之后。但是当我尝试执行其他操作时&#xff0c;我…

python虚拟人脸生成_GitHub - 597111463/seeprettyface-generator-yellow: 这是一个用StyleGAN训练出的黄种人人脸生成器...

黄种人人脸生成器注明&#xff1a;之前做的一些有意思的人脸生成器&#xff0c;现在全部开源分享出来。它的主要作用是可生成制作各类型的人脸素材&#xff0c;供我们任意使用且无须担心人脸版权的问题。在定制人脸上&#xff0c;开源的全系列生成器包括&#xff1a;黄种人脸生…

Linux输入密码接口,Linux下搭建接口自动化测试平台

前言我们今天来学习一下在Linux下如何搭建基于HttpRunner开发的接口自动化测试平台吧&#xff01;需要在Linux上提前准备的环境(下面是本人搭建时的环境)&#xff1a;1&#xff0c;Python 3.6.8 (可参考随笔&#xff1a;Linux学习6-安装Python3.6)2&#xff0c;MySQL 5.7(可参考…

python构建字典实现英文大写字母与ascii编码的转换_Python:将复杂的字符串字典从Unicode转换为ASCII...

作为从JSON API调用解析的多级字典,我有很多输入.字符串都是unicode,这意味着有很多ustuff like this.我正在使用jq来处理结果,需要将这些结果转换为ASCII.我知道我可以编写一个函数来像这样转换它:def convert(input):if isinstance(input, dict):ret {}for stuff in input:r…

linux下查看windows文件夹大小,如何从Windows命令行检查文件夹的大小?

我意识到这个问题要求使用进行文件大小分析CMD line。但是&#xff0c;如果您愿意使用它&#xff0c;PowerQuery (Excel add-in, versions 2010)则可以创建一些非常引人注目的文件大小分析。下面的脚本可以粘贴到空白查询中&#xff1b;您唯一需要做的就是添加一个名为“ param…

python多进程传递参数_急急急, Python 多进程,如何传递 epoll?

102019-06-16 15:39:41 08:00NoAnyLove 好的好的&#xff0c;我查了下&#xff0c;说 IPC 或向 worker 参数传递的东西必须要能 pickle&#xff0c;不然就报错&#xff0c;那就是 select.epoll 是不支持的。error&#xff1a;TypeError: cant pickle select.epoll objects。代码…

linux查看一小时之内的日志,linux – 在[timespan]内(例如最后一小时)查找日志文件中的条目...

我的服务器CPU使用率不高&#xff0c;我可以看到Apache正在使用太多的内存。我有一种感觉&#xff0c;我正在用一个IP进行DOS.-也许你可以帮我找到他&#xff1f;我已经使用以下行找到10个最“活跃”的IP&#xff1a;cat access.log | awk {print $1} |sort |uniq -c |sort -n …

图像语义分割_图像语义分割(9)-DeepLabV3: 再次思考用于图像语义分割的空洞卷积...

论文地址 &#xff1a;Rethinking Atrous Convolution for Semantic Image Segmentation论文代码&#xff1a;Github链接1. 摘要文章主要的工作&#xff1a;使用空洞卷积来调整滤波器的感受野并控制特征图分辨率使用不同空洞率的空洞卷积的串联或者并行操作来分割不同尺度的目标…

linux系统列表,Linux常用系统调用列表-20210415054405.docx-原创力文档

LinuxLinux常用系统调用列表作者&#xff1a;雷震 2002年3月本文列出了大部分常见的Linux系统调用&#xff0c;并附有简要中文说明。以下是Linux系统调用的一个列表&#xff0c;包含了大部分常用系统调用和由系统调用派 生出的的函数。按照惯例&#xff0c;这个列表以man pages…

sql replace 双引号变单引号_sql-汇总、排序以及分析思路

一、汇总函数注&#xff1a;汇总函数&#xff0c;如果输入是列名&#xff0c;计算会把null 排除在外&#xff0c;count(*)对所有的行进行计数二、如何用sql解决业务问题注1&#xff1a;空值(null)的排序,排序是最小的&#xff0c;例如select * from tea order by tea_name注2&a…

linux subversion 根目录检出,经验总结:详解Linux下Subversion的安装配置记录 下

上节介绍额Linux下Subversion的安装问题&#xff0c;本节介绍Linux下Subversion配置问题&#xff0c;你可以和Windows下Subversion的安装配置做一个对比&#xff0c;你就会发现在这两种操作系统中Subversion的不同运行机制。第二章配置本系统采用为每个项目单独建一版本库的策略…

python用户名密码登录退出_用户登录登出

一、功能需求分析1.登录功能分析1.1登录流程1.2功能(一个请求为一个功能)&#xff5e;登录页面&#xff5e;登录功能&#xff5e;登出功能二、登录页面1.接口设计1.1.接口说明类目                  说明请求方式                GETurl定义…

openwrt是嵌入式linux,非常方便的OpenWrt的嵌入式Linux开发环境

今天听中央经济广播电台说,今年有559万大学毕业生,大学生的就业形式严峻.我想那些精通Linux开发的毕业大学生们,估计一点也不用担心,因为他们已经不再是一颗大白菜了.最近在帮一个朋友把OpenWrt移植到一块单板上,有一些心得,分享给大家.OpenWrt是一个很好的学习Linux的平台,而且…

linux添加有效群组,Linux中的有效群组和初始群组

在Linux中&#xff0c;每个账号都可以加入多个群组&#xff0c;那用户登录后默认的用的是哪个群组呢&#xff1f;关于这个问题就要说说有效群组和初始群组了。在用户账号信息文件/etc/passwd中&#xff0c;那个由冒号分割的7个栏目中&#xff0c;第四个栏目是群组ID(GID)&#…

php多个表中查找数据_HeidiSQL 免费的可视化数据库管理工具

HeidiSQL是一款免费的软件&#xff0c;并且易于学习和使用。HeidiSQL让你从数据库内可视化的读写数据、结构体。它支持MariaDB、MySQL、Microsoft SQL、PostgreSQL等数据库。功能免费且开源内置中文在同个窗口连接多个服务支持以命令行形式连接服务连接支持SSH、SSL创建修改表、…

嵌入式linux启动根文件系统,嵌入式Linux根文件系统制作和挂载

嵌入式Linux系统由三部分组成&#xff1a; uboot、kernel、根文件系统&#xff0c; 还是这张老图这里的根文件系统可以说是包含两个部分&#xff1a; 一个是根&#xff0c;一个是文件系统那么什么是根呢&#xff1f;哈哈 其实根表示的就是第一个的意思下面贴张图看看整个根文件…

sqlite 查询 支持多用户同时_SQLite支持多进程同时操作数据库文件吗?

多个进程可以同时打开同一个数据库。多个进程可以同时执行SELECT。但是&#xff0c;只有一个进程可以随时对数据库进行更改。SQLite使用读/写锁来控制对数据库的访问。(在Win95 / 98 / ME下&#xff0c;缺少对读写锁的支持&#xff0c;而是使用概率模拟。)但请注意&#xff1a;…

python 字符串处理 字典_python 字符串和字典

一、字符串操作name "my name is \t {name} and i am {year} years old"1.首字母大写print(name.capitalize())2.统计字符串中相同的字符print(name.count("n"))3.格式化字符串print(name.center(50,"-"))#打印50个-&#xff0c;把name的值放中…