ESP32上实现LVGL的界面显示

2023-11-07

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

基于Vscode中的 PlatformIO平台arduino框架,使用1.8` 128*160 RGB TFT,在ESP32上实现LVGL的界面显示尝试。


一、元器件

ESP32 TFT
ESP32 IO TFT 说明
GND GND GND
18 SCL 时钟线
23 SDA 数据线
4 RST 复位线
2 DC 数据命令选择线
15 CS 片选
32 BLK 背光

二、导入库

代码如下:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino


lib_deps =
  lvgl/lv_arduino @ ~3.0.1
  bodmer/TFT_eSPI @ ~2.4.42

三.调试TFT_eSPI

TFT 使用的驱动IC是 ST7735S,因此需要在修改User_Setup.h
User_Setup.h

需要修改的代码如下:

// ##################################################################################
//
// Section 1. Call up the right driver file and any options for it
//
// ##################################################################################
#define ST7735_DRIVER      // Define additional parameters below for this display
#define TFT_RGB_ORDER TFT_RGB  // Colour order Red-Green-Blue
#define TFT_WIDTH  128 
#define TFT_HEIGHT 160
// ##################################################################################
//
// Section 2. Define the pins that are used to interface with the display here
//
// ##################################################################################
#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   32
// ##################################################################################
//
// Section 3. Define the fonts that are to be used here
//
// ##################################################################################
#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_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT
// ##################################################################################
//
// Section 4. Other options
//
// ##################################################################################
#define SPI_FREQUENCY  27000000
// #define SPI_FREQUENCY  40000000
// #define SPI_FREQUENCY  55000000 // STM32 SPI1 only (SPI2 maximum is 27MHz)
// #define SPI_FREQUENCY  80000000

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

// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
#define SPI_TOUCH_FREQUENCY  2500000

调试一下tft-espi 自带demo

#include <Arduino.h>
#include <FS.h>
#include <SPIFFS.h>
#include <SPI.h>
#include <TFT_eSPI.h>
// Define meter size
#define M_SIZE 0.667

TFT_eSPI tft = TFT_eSPI();       // Invoke custom library

#define TFT_GREY 0x5AEB
#define TFT_ORANGE      0xFD20      /* 255, 165,   0 */

float ltx = 0;    // Saved x coord of bottom of needle
uint16_t osx = M_SIZE*120, osy = M_SIZE*120; // Saved x & y coords
uint32_t updateTime = 0;       // time for next update

int old_analog =  -999; // Value last displayed

int value[6] = {0, 0, 0, 0, 0, 0};
int old_value[6] = { -1, -1, -1, -1, -1, -1};
int d = 0;

// #########################################################################
// Update needle position
// This function is blocking while needle moves, time depends on ms_delay
// 10ms minimises needle flicker if text is drawn within needle sweep area
// Smaller values OK if text not in sweep area, zero for instant movement but
// does not look realistic... (note: 100 increments for full scale deflection)
// #########################################################################
void plotNeedle(int value, byte ms_delay)
{
  tft.setTextColor(TFT_BLACK, TFT_WHITE);
  char buf[8]; dtostrf(value, 4, 0, buf);
  tft.drawRightString(buf, 33, M_SIZE*(119 - 20), 2);

  if (value < -10) value = -10; // Limit value to emulate needle end stops
  if (value > 110) value = 110;

  // Move the needle until new value reached
  while (!(value == old_analog)) {
    if (old_analog < value) old_analog++;
    else old_analog--;

    if (ms_delay == 0) old_analog = value; // Update immediately if delay is 0

    float sdeg = map(old_analog, -10, 110, -150, -30); // Map value to angle
    // Calculate tip of needle coords
    float sx = cos(sdeg * 0.0174532925);
    float sy = sin(sdeg * 0.0174532925);

    // Calculate x delta of needle start (does not start at pivot point)
    float tx = tan((sdeg + 90) * 0.0174532925);

    // Erase old needle image
    tft.drawLine(M_SIZE*(120 + 24 * ltx) - 1, M_SIZE*(150 - 24), osx - 1, osy, TFT_WHITE);
    tft.drawLine(M_SIZE*(120 + 24 * ltx), M_SIZE*(150 - 24), osx, osy, TFT_WHITE);
    tft.drawLine(M_SIZE*(120 + 24 * ltx) + 1, M_SIZE*(150 - 24), osx + 1, osy, TFT_WHITE);

    // Re-plot text under needle
    tft.setTextColor(TFT_BLACK, TFT_WHITE);
    tft.drawCentreString("%RH", M_SIZE*120, M_SIZE*75, 4); // // Comment out to avoid font 4

    // Store new needle end coords for next erase
    ltx = tx;
    osx = M_SIZE*(sx * 98 + 120);
    osy = M_SIZE*(sy * 98 + 150);

    // Draw the needle in the new postion, magenta makes needle a bit bolder
    // draws 3 lines to thicken needle
    tft.drawLine(M_SIZE*(120 + 24 * ltx) - 1, M_SIZE*(150 - 24), osx - 1, osy, TFT_RED);
    tft.drawLine(M_SIZE*(120 + 24 * ltx), M_SIZE*(150 - 24), osx, osy, TFT_MAGENTA);
    tft.drawLine(M_SIZE*(120 + 24 * ltx) + 1, M_SIZE*(150 - 24), osx + 1, osy, TFT_RED);

    // Slow needle down slightly as it approaches new postion
    if (abs(old_analog - value) < 10) ms_delay += ms_delay / 5;

    // Wait before next update
    delay(ms_delay);
  }
}

运行显示
显示

四.调试LVGL

#include <Arduino.h>
#include <FS.h>
#include <SPIFFS.h>
#include <SPI.h>
#include <lvgl.h>
#include <TFT_eSPI.h>
//#include <TFT_eTouch.h>  // https://github.com/achillhasler/TFT_eTouch
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 = 160;
int screenHeight = 128;

#define LED_PIN 16

#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);
    Serial.flush();
}
#endif

/* Display flushing */
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(&color_p->full, w * h, true);
    tft.endWrite();

    lv_disp_flush_ready(disp);
}

/* Reading input device (simulated encoder here) */
bool read_encoder(lv_indev_drv_t * indev, lv_indev_data_t * data)
{ //输入识别}

void printEvent(String Event, lv_event_t event)
{}

void slider_event_cb(lv_obj_t * slider, lv_event_t event)
{

  printEvent("Slider", event);

  if(event == LV_EVENT_VALUE_CHANGED) {
     //事件
  }
}

void setup()
{

    pinMode(LED_PIN, OUTPUT);
    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); /* Landscape orientation */
    //tft.setTextFont(1);
    //tft.setTextColor(TFT_RED, TFT_WHITE);

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

    /*Initialize the display*/
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.hor_res = 160;
    disp_drv.ver_res = 128;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.buffer = &disp_buf;
    lv_disp_drv_register(&disp_drv);

    /*Initialize the (dummy) input device driver*/
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_ENCODER;
    indev_drv.read_cb = read_encoder;
    lv_indev_drv_register(&indev_drv);

    /* Create simple label */
    lv_obj_t *label = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_text(label, "Hello Arduino!");
    lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -30);

    /* Create a slider in the center of the display */
    lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL);
    lv_obj_set_width(slider, screenWidth-50);                        /*Set the width*/
    lv_obj_set_height(slider, 20);
    lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0);    /*Align to the center of the parent (screen)*/
    lv_obj_set_event_cb(slider, slider_event_cb);         /*Assign an event function*/
  
    /* Create a label below the slider */
    slider_label = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_text(slider_label, "0");
    lv_obj_set_auto_realign(slider, true);
    lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
}

void loop()
{
    lv_task_handler(); /* let the GUI do its work */
    delay(5);
}

运行显示:
lvgl显示


总结

本文仅仅简单的复制粘贴记录一下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ESP32上实现LVGL的界面显示 的相关文章

  • MNIST数据库介绍及转换

    MNIST数据库介绍 MNIST是一个手写数字数据库 它有60000个训练样本集和10000个测试样本集 它是NIST数据库的一个子集 MNIST数据库官方网址为 http yann lecun com exdb mnist 也可以在win
  • springMVC ResponseBody 返回汉字乱码解决方案

    本文查考借鉴 http blog yimik com archives 899 js里通过ajax调用springmvc 后台返回的中文字符串乱码 通过搜索找解决方 大都让配置StringHttpMessageConverter这个bean
  • 本地JAR打镜像,并启动

    1 准备好jar 和Dockerfile文件 2 使用命令打镜像 docker build t wstest 3 查看镜像 4 由于服务是两个端口 使用以下命令 5 优化怎么随着docker的开启而启动 docker run restart
  • Maltrail恶意流量检测系统

    Maltrail恶意流量检测系统 项目介绍 项目GitHub地址 项目架构 项目数据集 运行方式 订阅源扩展 数据采集模块提取 项目介绍 maltrail是一款轻量级的恶意流量检测系统 其工作原理是通过采集网络中各个开源黑样本 包括IP 域
  • python操作sql

    from pymysql import connect def main 创建connection连接 conn connect host localhost port 3306 user root password 123456 data
  • 深入浅出UML类图(一)

    在UML 2 0的13种图形中 类图是使用频率最高的UML图之一 Martin Fowler在其著作 UML Distilled A Brief Guide to the Standard Object Modeling Language
  • Redis中key-value实现

    实现字典的方法有很多种 最简单的就是使用链表或数组 但是这种方式只适用于元素个数不多的情况下 要兼顾高效和简单性 可以使用哈希表 如果追求更为稳定的性能特征 并且希望高效地实现排序操作的话 则可以使用更为复杂的平衡树 在众多可能的实现中 R
  • JAVA8新特性--集合遍历之forEach

    java中的集合有两种形式Collection

随机推荐

  • 5.2 activiti任务监听器TaskListener

    1 任务监听器定义 任务监听器用于在特定的任务相关事件发生时 执行自定义的Java逻辑或表达式 2 监听器监听的事件 String EVENTNAME CREATE create 创建 当任务已经创建 并且所有任务参数都已经设置时触发 St
  • Basic Level 1090 危险品装箱 (25分)

    题目 集装箱运输货物时 我们必须特别小心 不能把不相容的货物装在一只箱子里 比如氧化剂绝对不能跟易燃液体同箱 否则很容易造成爆炸 本题给定一张不相容物品的清单 需要你检查每一张集装箱货品清单 判断它们是否能装在同一只箱子里 输入格式 输入第
  • Linux期末复习总结

    目录 Linux 系统的结构 shell Linux用户类型及其用户主目录 shell提示符 输入输出重定向 标准输入 输出设备 Linux文件的类型 Linux 的目录结构 基本操作命令 链接命令 ln 链接的特点 tar命令举例 vi
  • 求一批整数中出现最多的各位数字

    描述 给定一批整数 分析每个整数的每一位数字 求出现次数最多的各 位数字 例如给定3个整数1234 2345 3456 其中出现最多次数的数字是3和4 均出现了3次 输入 输入在第1行中给出正整数N 1000 在第二行中给出N个不超过整型范
  • QT QLinearGradient (颜色渐变---应用控件背景渐变)

    示例 frame gt setStyleSheet background color qlineargradient spread pad x1 0 y1 0 x2 1 y2 0 stop 0 030303 stop 0 5 030303
  • 多线程及多进程的选择

    我的理解是进程是指在系统中正在运行的一个应用程序 程序一旦运行就是进程 或者更专业化来说 进程是指程序执行时的一个实例 线程是进程的一个实体 进程 资源分配的最小单位 线程 程序执行的最小单位 线程进程的区别体现在几个方面 0 因为进程拥有
  • 【手撕代码系列】JS手写实现bind方法

    公众号 Code程序人生 分享前端所见所闻 在JavaScript中 bind方法允许我们绑定函数的上下文并返回一个新的函数 在这篇文章中 我们将手写实现bind方法 以更好地了解它的内部工作原理 bind方法的语法 bind方法的语法如下
  • 整数转化为罗马数字

    1 问题描述 罗马数字包含以下七种字符 I V X L C D 和 M 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如 罗马数字 2 写做 II 即为两个并列的 1 12 写做 XII 即为 X
  • 多线程互斥锁 pthread_mutex 的使用及初始化问题

    一 互斥锁pthread mutex的使用 1 初始化锁 有两种方法初始化互斥锁 静态方式和动态方式 静态方式 pthread mutex t mutex lock PTHREAD MUTEX INITIALIZER 在LinuxThrea
  • 软件测试流程/需求分析之软件需求概述

    今天重点从四个方面来和大家对需求阶段需求分析做一个讲解 阅读测试文档 参与需求评审 测试需求分析 提取功能点 去做这些对应的事情之前 我们要先了解到底什么是需求 需求评审我们要从哪些点去评审 我们要去提取功能点要怎么样去进行提取 回忆测试流
  • 使用ffmpeg将mkv,rmvb转换成mp4

    cmd输入ffmpeg version 检查ffmpeg安装版本 1 进入mkv rmvb所在的文件夹 2 转换mkv ffmpeg i inputname mkv c v copy c a copy outputname mp4 转换rm
  • 几种优化算法(求最优解)

    几种优化算法 先简单备注下 今后接触到再看 参考资料 http blog sina com cn s blog 6a1bf1310101hhta html
  • SpringBean管理

    一 什么是SpringBean 在Spring中将管理对象称为 Bean Bean是由一个SpringIOC容器实例化 组装和管理的对象 也就是说 Bean并不是由我们程序员编写的 而是在程序运行过程中 由Spring通过反射机制生成的 S
  • 串口通信开发

    一开始做串口通信开发时 觉得并不难 无非就是发送 然后等一会 再接收就完事了 其实里面的水很深 特别是在各种设备都有的情况下 我们在整个开发过程中 遇到了以下的几个主要问题 1 设备出现严重的延迟 2 接收过程出现数据粘包或截断 3 多设备
  • 华为OD机试-目录删除

    Online C compiler to run C program online include
  • 解决错误:Plugin with id 'com.android.application' not found

    本文转载地址 https blog csdn net qq 26819733 article details 50935632 Error 1 0 Plugin with id com android application not fou
  • C++中的转移字符

    C 中转移字符 顺序 描述 表示 单引号 字节0x27 ASCII编码 双引号 字节0x22 ASCII编码 问号 字节0x3f ASCII编码 反斜线 字节0x5c ASCII编码 a 可听见钟 字节0x07 ASCII编码 b 退格 字
  • 深度学习方法在道路提取、图像检索上的几篇文章阅读笔记

    关于全卷积神经网络的upsampling还没有搞清楚 如果你有合适的资料或者好方法 欢迎评论交流 深度学习方法在道路提取上的应用1 传统方法 A review of road extraction from remote sensing i
  • Siebel Open UI

    阅读原文 http blog sina com cn s blog 70ea5c9101017qi4 html Open UI最常提到的特性是 W3C标准兼容 可在任何符合标准的浏览器上使用 可跨多种形式的因素 客户端JavaScript框
  • ESP32上实现LVGL的界面显示

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 元器件 二 导入库 三 调试TFT eSPI 四 调试LVGL 总结 前言 基于Vscode中的 PlatformIO平台arduino框架 使用1 8