57浏览
查看: 57|回复: 9

[项目] 【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL

[复制链接]
【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图2

ESP32-CYD(2432S028)液晶2.8寸屏开发板使用ESP32-WROOM-32模块作为主控,主控是一款双核MCU,集成了Wi-Fi和蓝牙功能,主频可达240MHz,具有520KB的SRAM、448KB的ROM,闪存容量为4MB+4MB,显示分辨率为240x320,采用电阻式触控式屏幕。该模块包括LCD显示器、背光控制电路、触控式屏幕控制电路、扬声器驱动电路、光敏电路和RGB LED控制电路。支持TF卡界面、序列界面、温湿度感测器界面(DHT11界面)和保留的IO口界面,该模块支持在Arduino IDE、ESP IDE、MicroPython和Mixly中进行开发。

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图1

驴友花雕  中级技神
 楼主|

发表于 4 天前

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL

安装TFT_eSPI、XPT2046_Touchscreen和LVGL库
网址:
TFT_eSPI库的网址:https://github.com/Bodmer/TFT_eSPI
XPT2046_Touchscreen库的网址: https://github.com/PaulStoffregen/XPT2046_Touchscreen

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 4 天前

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图1

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图2
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 4 天前

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL

本帖最后由 驴友花雕 于 2024-11-9 20:38 编辑

LVGL (Light and Versatile Graphics Library) 是一个免费的开源图形库,可为需要图形用户界面 (GUI) 的微控制器项目提供各种易于使用的图形元素。

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图1

以下是它的一些主要功能:

块:按钮、图表、列表、滑块、图像等......
具有动画、抗锯齿、不透明度、平滑滚动的高级图形;
各种输入设备,如触摸板、鼠标、键盘、编码器等......
UTF-8 编码的多语言支持;
多显示器支持,即同时使用多个 TFT 单色显示器;
具有类似 CSS 样式的完全可定制的图形元素;
独立于硬件:与任何微控制器或显示器一起使用;
可扩展:能够在很少的内存下运行(64 kB 闪存,16 kB RAM);
用 C 语言编写,以实现最大的兼容性(C++ 兼容)并绑定到 MicroPython。

它的文档中还有大量可供您使用的代码示例:文本、按钮、滑块、输入字段、键盘、自定义样式、图像、弧线、线条、动画、菜单、选项卡、布局、表格等等......

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图2


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 4 天前

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百三十八:ESP32开发板WiFi蓝牙2.8寸240*320智能液晶显示屏带触摸屏TFT模块
  项目实验之十九:ESP32 CYD液晶2.8寸开发板尝试LVGL(轻量级和多功能图形库)

实验开源代码

  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验二百三十八:ESP32开发板WiFi蓝牙2.8寸240*320智能液晶显示屏带触摸屏TFT模块
  4.   项目实验之十九:ESP32 CYD液晶2.8寸开发板尝试LVGL(轻量级和多功能图形库)
  5. */
  6. #include <lvgl.h>                 // 引入LVGL图形库
  7. #include <TFT_eSPI.h>             // 引入TFT_eSPI库,用于驱动TFT显示屏
  8. #include <XPT2046_Touchscreen.h>  // 引入XPT2046触摸屏库
  9. // 触摸屏引脚定义
  10. #define XPT2046_IRQ 36   // T_IRQ引脚
  11. #define XPT2046_MOSI 32  // T_DIN引脚
  12. #define XPT2046_MISO 39  // T_OUT引脚
  13. #define XPT2046_CLK 25   // T_CLK引脚
  14. #define XPT2046_CS 33    // T_CS引脚
  15. SPIClass touchscreenSPI = SPIClass(VSPI);                  // 实例化一个SPI类,用于触摸屏通信
  16. XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);  // 创建触摸屏对象
  17. #define SCREEN_WIDTH 240   // 屏幕宽度定义
  18. #define SCREEN_HEIGHT 320  // 屏幕高度定义
  19. // 触摸屏坐标:(x, y) 和压力(z)
  20. int x, y, z;
  21. #define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))  // 绘图缓冲区大小定义
  22. uint32_t draw_buf[DRAW_BUF_SIZE / 4];                                             // 绘图缓冲区
  23. // 如果启用了日志记录,它将告知用户库中发生了什么
  24. void log_print(lv_log_level_t level, const char* buf) {
  25.   LV_UNUSED(level);     // LVGL中未使用的宏
  26.   Serial.println(buf);  // 打印日志信息
  27.   Serial.flush();       // 清空串口缓冲区
  28. }
  29. // 获取触摸屏数据
  30. void touchscreen_read(lv_indev_t* indev, lv_indev_data_t* data) {
  31.   // 检查触摸屏是否被触摸,并打印X, Y和压力(Z)
  32.   if (touchscreen.tirqTouched() && touchscreen.touched()) {
  33.     // 获取触摸屏坐标点
  34.     TS_Point p = touchscreen.getPoint();
  35.     // 使用map函数校准触摸屏坐标点到正确的宽度和高度
  36.     x = map(p.x, 200, 3700, 1, SCREEN_WIDTH);
  37.     y = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);
  38.     z = p.z;
  39.     data->state = LV_INDEV_STATE_PRESSED;  // 设置状态为按下
  40.     // 设置坐标点
  41.     data->point.x = x;
  42.     data->point.y = y;
  43.     // 在串口监视器上打印触摸屏信息关于X, Y和压力(Z)
  44.     /* Serial.print("X = ");
  45.     Serial.print(x);
  46.     Serial.print(" | Y = ");
  47.     Serial.print(y);
  48.     Serial.print(" | Pressure = ");
  49.     Serial.print(z);
  50.     Serial.println();*/
  51.   } else {
  52.     data->state = LV_INDEV_STATE_RELEASED;  // 设置状态为释放
  53.   }
  54. }
  55. int btn1_count = 0;  // 按钮1的计数器
  56. // 当按钮1被点击时触发的回调函数
  57. static void event_handler_btn1(lv_event_t* e) {
  58.   lv_event_code_t code = lv_event_get_code(e);  // 获取事件代码
  59.   if (code == LV_EVENT_CLICKED) {
  60.     btn1_count++;                                       // 按钮计数器加1
  61.     LV_LOG_USER("Button clicked %d", (int)btn1_count);  // 用户日志记录按钮点击次数
  62.   }
  63. }
  64. // 当按钮2被点击/切换时触发的回调函数
  65. static void event_handler_btn2(lv_event_t* e) {
  66.   lv_event_code_t code = lv_event_get_code(e);        // 获取事件代码
  67.   lv_obj_t* obj = (lv_obj_t*)lv_event_get_target(e);  // 获取事件目标对象
  68.   if (code == LV_EVENT_VALUE_CHANGED) {
  69.     LV_UNUSED(obj);                                                                     // LVGL中未使用的宏
  70.     LV_LOG_USER("Toggled %s", lv_obj_has_state(obj, LV_STATE_CHECKED) ? "on" : "off");  // 用户日志记录开关状态
  71.   }
  72. }
  73. static lv_obj_t* slider_label;  // 滑块标签对象
  74. // 回调函数,用于在TFT显示屏和串口监视器上打印当前滑块值,用于调试目的
  75. static void slider_event_callback(lv_event_t* e) {
  76.   lv_obj_t* slider = (lv_obj_t*)lv_event_get_target(e);                     // 获取事件目标对象(滑块)
  77.   char buf[8];                                                              // 缓冲区
  78.   lv_snprintf(buf, sizeof(buf), "%d%%", (int)lv_slider_get_value(slider));  // 获取滑块值并格式化为字符串
  79.   lv_label_set_text(slider_label, buf);                                     // 设置滑块标签文本
  80.   lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);    // 将滑块标签对齐到滑块下方
  81.   LV_LOG_USER("Slider changed to %d%%", (int)lv_slider_get_value(slider));  // 用户日志记录滑块值
  82. }
  83. void lv_create_main_gui(void) {
  84.   // 创建一个文本标签,居中显示在顶部("Hello, world!")
  85.   lv_obj_t* text_label = lv_label_create(lv_screen_active());
  86.   lv_label_set_long_mode(text_label, LV_LABEL_LONG_WRAP);  // 自动换行
  87.   lv_label_set_text(text_label, "Hello, world!");
  88.   lv_obj_set_width(text_label, 150);  // 设置较小的宽度以使文本换行
  89.   lv_obj_set_style_text_align(text_label, LV_TEXT_ALIGN_CENTER, 0);
  90.   lv_obj_align(text_label, LV_ALIGN_CENTER, 0, -90);
  91.   lv_obj_t* btn_label;
  92.   // 创建一个按钮(btn1)
  93.   lv_obj_t* btn1 = lv_button_create(lv_screen_active());
  94.   lv_obj_add_event_cb(btn1, event_handler_btn1, LV_EVENT_ALL, NULL);
  95.   lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -50);
  96.   lv_obj_remove_flag(btn1, LV_OBJ_FLAG_PRESS_LOCK);
  97.   btn_label = lv_label_create(btn1);
  98.   lv_label_set_text(btn_label, "Button");
  99.   lv_obj_center(btn_label);
  100.   // 创建一个切换按钮(btn2)
  101.   lv_obj_t* btn2 = lv_button_create(lv_screen_active());
  102.   lv_obj_add_event_cb(btn2, event_handler_btn2, LV_EVENT_ALL, NULL);
  103.   lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 10);
  104.   lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);
  105.   lv_obj_set_height(btn2, LV_SIZE_CONTENT);
  106.   btn_label = lv_label_create(btn2);
  107.   lv_label_set_text(btn_label, "Toggle");
  108.   lv_obj_center(btn_label);
  109.   // 在TFT显示屏底部居中创建一个滑块
  110.   lv_obj_t* slider = lv_slider_create(lv_screen_active());
  111.   lv_obj_align(slider, LV_ALIGN_CENTER, 0, 60);
  112.   lv_obj_add_event_cb(slider, slider_event_callback, LV_EVENT_VALUE_CHANGED, NULL);
  113.   lv_slider_set_range(slider, 0, 100);
  114.   lv_obj_set_style_anim_duration(slider, 2000, 0);
  115.   // 在滑块下方创建一个标签以显示当前滑块值
  116.   slider_label = lv_label_create(lv_screen_active());
  117.   lv_label_set_text(slider_label, "0%");
  118.   lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
  119. }
  120. void setup() {
  121.   String LVGL_Arduino = String("LVGL Library Version: ") + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
  122.   Serial.begin(115200);          // 初始化串口通信,波特率为115200
  123.   Serial.println(LVGL_Arduino);  // 打印LVGL库版本信息
  124.   // 启动LVGL
  125.   lv_init();
  126.   // 注册打印函数用于调试
  127.   lv_log_register_print_cb(log_print);
  128.   // 启动触摸屏的SPI并初始化触摸屏
  129.   touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
  130.   touchscreen.begin(touchscreenSPI);
  131.   // 设置触摸屏旋转为横屏模式
  132.   // 注意:在某些显示屏上,触摸屏可能是倒置的,因此可能需要将旋转设置为0:touchscreen.setRotation(0);
  133.   touchscreen.setRotation(2);
  134.   // 创建一个显示对象
  135.   lv_display_t* disp;
  136.   // 使用TFT_eSPI库初始化TFT显示屏
  137.   disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));
  138.   lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);
  139.   // 初始化一个LVGL输入设备对象(触摸屏)
  140.   lv_indev_t* indev = lv_indev_create();
  141.   lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
  142.   // 设置回调函数以读取触摸屏输入
  143.   lv_indev_set_read_cb(indev, touchscreen_read);  // 注册触摸屏读取回调函数
  144.   // 绘制GUI(文本、按钮和滑块)
  145.   lv_create_main_gui();
  146. }
  147. void loop() {
  148.   lv_task_handler();  // 让GUI执行其任务
  149.   lv_tick_inc(5);     // 告诉LVGL已经过去了多少时间
  150.   delay(5);           // 让这段时间过去
  151. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 4 天前

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL

代码解读
这段代码是一个用于Arduino的示例,它结合了LVGL图形库和TFT_eSPI库以及XPT2046触摸屏库,用于在TFT显示屏上创建一个简单的图形用户界面(GUI)。下面是代码的主要功能和组件的解释:

1、包含库:

lvgl.h:LVGL图形库的头文件。
TFT_eSPI.h:用于驱动TFT显示屏的TFT_eSPI库。
XPT2046_Touchscreen.h:用于驱动XPT2046触摸屏的库。

2、触摸屏引脚定义:

定义了连接XPT2046触摸屏的Arduino引脚。

3、SPI类实例化:

实例化了一个SPI类touchscreenSPI,用于与触摸屏通信。

4、触摸屏对象:

创建了一个XPT2046_Touchscreen对象touchscreen,用于管理触摸屏。

5、屏幕和缓冲区定义:

定义了屏幕的宽度和高度。
定义了一个缓冲区draw_buf,用于LVGL的绘图操作。

6、日志打印函数:

log_print函数用于将LVGL的日志信息打印到串口。

7、触摸屏读取函数:

touchscreen_read函数用于读取触摸屏的数据,并将其转换为LVGL可以理解的坐标。

8、按钮和滑块事件处理函数:

event_handler_btn1、event_handler_btn2和slider_event_callback函数分别用于处理按钮点击、切换和滑块值变化的事件。

9、GUI创建函数:

lv_create_main_gui函数用于创建GUI界面,包括文本标签、按钮和滑块。

10、setup函数:

初始化串口通信。
初始化LVGL库。
初始化触摸屏。
创建显示对象和输入设备对象。
调用lv_create_main_gui函数来绘制GUI。

11、loop函数:

包含LVGL的任务处理和时间增量,以保持GUI的响应。
这段代码展示了如何使用LVGL在TFT显示屏上创建一个基本的GUI,包括文本显示、按钮和滑块,并通过触摸屏进行交互。


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 4 天前

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL

实验串口返回情况

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图1
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 4 天前

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图1
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 4 天前

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL

实验场景图

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图1

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图2
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 4 天前

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL

实验场景图

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图1

【花雕学编程】Arduino动手做(238)---ESP32 CYD 尝试 LVGL图2
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail