《ESP32 学习笔记》之 Arduino环境下玩转 LVGL-搭建环境

0. 项目地址

【Arduino-LVGL-Project】

1. LVGL简介

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

2. 演示效果

对于ESP32上使用LVGL,我在三种设备上进行了测试,屏幕驱动型号分别为:1.14寸ST7789V3.5寸ILI94883.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进去后你可以发现该库已经有很多版本了,可以根据自己的喜好下载,并放入到你的ArduinoLibrary文件夹下:

  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. LITTELVGL 基础控件学习篇【f1c100/f1c200】
  4. 百问网LVGL中文教程手册文档

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_eSPITFT_Touchlv_arduino 三个库放入到你的ArduinoLibrary文件夹下。

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

打开ArduinoLibrary文件夹下的TFT_eSPI目录,打开 User_Setup_Select.h 文件:

将第22行的
#include <User_Setup.h> // Default setup is root library folder
注释掉为
//#include <User_Setup.h> // Default setup is root library folder
将第47行的
//#include <User_Setups/Setup21_ILI9488.h> // Setup file for ESP32 and ILI9488 SPI bus TFT
取消注释为
#include <User_Setups/Setup21_ILI9488.h> // 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 <lvgl.h>
#include <TFT_eSPI.h>
#include <Arduino.h>
#include <SPI.h>
#include <TFT_Touch.h>

#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(),下面放出演示效果:
在这里插入图片描述
在这里插入图片描述
当然可以前往【哔哩哔哩 】 查看,记得点赞关注哦!
↓↓↓↓↓↓↓↓演示视频↓↓↓↓↓↓↓↓

在Arduino上用ESP32玩LVGL?

3.3.6 第6步 (注意事项)

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

待续~~~~~~~~

  • 54
    点赞
  • 307
    收藏
    觉得还不错? 一键收藏
  • 26
    评论
### 回答1: 可以使用 Arduino IDE 来搭建 ESP32 的开发环境。在 Arduino IDE 中选择菜单栏的 "工具" - "板" - "管理器",搜索 "esp32" 并安装对应的驱动。然后在 "工具" - "板" 中选择 "ESP32 Dev Module" 即可使用 ESP32 开发板进行编程。 ### 回答2: ESP32是一种基于32位的微控制器,它具有高度集成、低功耗、可靠性高等优点。如果您想使用ESP32进行开发,您需要先搭建一个开发环境,这样才能进行编码和测试操作,本文将针对Arduino环境ESP32的开发环境搭建进行详细介绍。 第一步:下载及安装Arduino IDE Arduino IDE是一款开源免费的软件,它提供了编写和上传代码的一个界面。首先,您需要前往官网(https://www.arduino.cc/en/software)下载最新版本的Arduino IDE软件,并安装好。 第二步:添加ESP32开发板 Arduino IDE已经内置了大量的开发板,我们需要添加ESP32的支持。进入“文件>首选项”下的设置窗口,找到“附加开发板管理器的网址”,输入以下链接地址: https://dl.espressif.com/dl/package_esp32_index.json 接下来,进入“工具>开发板>开发板管理器”窗口进行ESP32的添加,搜索框输入“ESP32”,找到“esp32 by Espressif Systems”,点击“安装”。 第三步:选择开发板及串口 在完成开发板的添加后,我们需要选择开发板及其对应的串口。进入“工具”下选择“ESP32 Dev Module”开发板,然后选择正确的串口,如果您不知道该串口位置,可以到设备管理器中查看。 第四步:测试示例程序 在本地文件中新建文件夹,输入一个名字。接着,进入“文件>示例>ESP32>WiFi”下选择想要运行的示例程序,例如选择“ScanNetworks”无线网络扫描示例程序。代码中要修改的地方,主要是WLAN名和密码,修改成所在无线局域网的账号密码。 确认串口都是选择好的,设备已经连接电脑或是单片机板,然后上传程序,等待运行结束。上传结束之后,打开“工具>串口监视器”,等待串口接收到ESP32扫描到的无线局域网信息。 综上可见,ESP32开发环境搭建比较简单,只需要经过上述几个步骤即可完成。有了这个环境,我们可以更方便地进行ESP32的开发工作,创造出更多神奇、实用的应用。 ### 回答3: ESP32是一款非常受欢迎的物联网开发板,其使用广泛且功能强大。如果你是个初学者,想要学习ESP32的开发,建立一个基础的开发环境是非常重要的。本文将教你如何使用Arduino搭建ESP32开发环境。 步骤1:安装Arduino IDE 首先,你需要下载和安装Arduino IDE。到官方网站下载即可。 步骤2:添加ESP32开发板支持 打开Arduino IDE,点击菜单栏中的“文件”→“首选项”打开首选项窗口。在“附加开发板管理器网址”中输入以下网址: https://dl.espressif.com/dl/package_esp32_index.json 点击“确定”后关闭首选项窗口,在菜单栏中选择“工具”→“开发板”→“开发板管理器”,找到ESP32开发板,点击“安装”。 步骤3:选择开发板 在菜单栏选择“工具”→“开发板”,找到“ESP32 Dev Module”,即可选择它。 步骤4:选择端口 将ESP32开发板与电脑连接,打开“工具”菜单,选择“端口”,选择正确的端口。 步骤5:写代码 你可以在Arduino IDE中编写代码,然后通过“上传”按钮将代码烧录到ESP32上。上传按钮位于IDE右上角。 步骤6:测试 通过烧录程序测试,确保ESP32硬件和开发板都正常工作。如果一切正常,你的ESP32就已准备好开始开发啦! 总结 以上就是ESP32搭建Arduino开发环境的步骤,要搭建好开发环境需要时间和耐心。一定要确保步骤正确,最好再对重要步骤进行再次确认,才能顺利地开始ESP32的开发工作。希望这篇文章能够帮助你更轻松地搭建ESP32的开发环境

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值