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输入密码接口,Linux下搭建接口自动化测试平台

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

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

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

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

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

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

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

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

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

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;…

pgsql 查询每天的最后一条_Qamp;A | 如何允许他人查询表单数据?

小金Q&A来啦&#xff01;这一期小金Q&A中&#xff0c;小金收集到近期大家关注最多的几个问题。小金将定期为小金人们答疑解惑&#xff0c;帮助你每天用好小金一点。●Q&A●问&#xff1a;如何批量设置新数据微信提醒&#xff1f;答&#xff1a;点击右上角头像 个人…

linux 解压tar.jz,linux系统压缩文件和解压缩命令

linux系统压缩文件和解压缩命令tar命令   解包&#xff1a;tar zxvf FileName.tar打包&#xff1a;tar czvf FileName.tar DirName gz命令   解压1&#xff1a;gunzip FileName.gz解压2&#xff1a;gzip -d FileName.gz压缩&#xff1a;gzip FileName.tar.gz 和 .tgz解压&a…

linux fall delay 10,Cell的Rise delay和Fall delay、Rise transition和fall transition

Cell的Rise delay和Fall delay、Rise transition和Fall transition介绍&#xff1a;如下图所示为一个Cell的lib中关于cell_rise/cell_fall、rise_transition/fall_transition的描述&#xff1a;在NLDM模型的.lib中&#xff0c;cell_rise/cell_fall它描述的是Cell从输入到输出的…

keil流水灯c语言程序两个一起亮,我用keil c51编了一个流水灯程序,编译无误却只有第一和第二个灯亮了,最后停在第一个灯处不动...

满意答案zJ张俭2014.02.09采纳率&#xff1a;43% 等级&#xff1a;12已帮助&#xff1a;10469人你有几个错误:1 你的定时器没有重装,导致第一次中断和后面的中断时间不一样,第一次时间短,后面的时间一直是以65536个周期中断的.2 你在中断函数里用了 for 循环,for循环是一下子…

pyquery获取不到网页完整源代码_python动态网页爬取:爬取pexel上的图片

前言同样的&#xff0c;我们在写一个爬虫前要明确自己想要爬取的东西是什么&#xff0c;明确下载目标数据在浏览器的操作如何对于动态网页的爬取&#xff0c;在网页地址不变的情况下&#xff0c;我们首先要明确如何获取AJAX请求首先我们看看这个网站pexel打开页面后再Chrome浏览…

W ndows找不到explorer,windows找不到explorer.exe的处理教程

很多网友入手windows过程里找不到explorer.exe&#xff0c;很是烦恼&#xff0c;为了帮助大家排忧解难&#xff0c;这里小编就分享了windows找不到explorer.exe的处理教程&#xff0c;希望可以帮助到大家。windows找不到explorer.exe的处理教程1、按winr打开运行窗口&#xff0…

极光推送 android 最新,Android——快速集成极光推送-Go语言中文社区

集成极光推送1&#xff0c;首先肯定是注册&#xff0c;添加应用2&#xff0c;开始自动集成比手动集成简单第一步 在 build.gradledefaultConfig {multiDexEnabledtrueapplicationId rootProject.ext.cfg.applicationIdminSdkVersionrootProject.ext.cfg.minSdkVersiontargetSdk…

华为云服务怎么弄金卡会员_万科牵手华为终端云服务,共建松山湖智慧商圈

12月18日&#xff0c;坐落在东莞松山湖南华为旁的44000㎡的开放式商业mall——滨湖万科里正式启幕。现场华为终端云服务部还与万科南方区域商业事业部签署了战略合作协议&#xff0c;开启共建智慧商圈的新版图。值得一提的是&#xff0c;这也是华为终端云服务与万科在商业板块的…

cad2014打开文件崩溃_CAD玩的再牛,崩溃了咋办?

导读前几天&#xff0c;一入职新人晚上加班画完的图纸在最后一刻CAD崩溃了&#xff01;好在最后在临时保存文件夹中找到了完整的图纸。这才免于通宵。CAD崩溃是我们画图中经常遇到的问题。对于CAD崩溃后的处理&#xff0c;相信老司机都已经游刃有余。但也有防不胜防的时候&…

android 弹窗ui,Android 弹出窗口与对话框 UI设计

左图: Android 自带的日期选择弹窗; 右图: Android 自带的时间选择弹窗.左图: Android 日历中的重复选择; 右图: Chrome 中的打印.干净简洁的布局与有趣儿又引人注目的交互让操作变得轻松而愉快, 尤其是那在时间选择器中出现的双环.同样的, 也有很多人试图在自己的应用中给他们…