【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百三十八:ESP32开发板WiFi蓝牙2.8寸240*320智能液晶显示屏带触摸屏TFT模块
项目实验之十九:ESP32 CYD液晶2.8寸开发板尝试LVGL(轻量级和多功能图形库)
实验开源代码
- /*
- 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
- 实验二百三十八:ESP32开发板WiFi蓝牙2.8寸240*320智能液晶显示屏带触摸屏TFT模块
- 项目实验之十九:ESP32 CYD液晶2.8寸开发板尝试LVGL(轻量级和多功能图形库)
- */
-
- #include <lvgl.h> // 引入LVGL图形库
- #include <TFT_eSPI.h> // 引入TFT_eSPI库,用于驱动TFT显示屏
- #include <XPT2046_Touchscreen.h> // 引入XPT2046触摸屏库
-
- // 触摸屏引脚定义
- #define XPT2046_IRQ 36 // T_IRQ引脚
- #define XPT2046_MOSI 32 // T_DIN引脚
- #define XPT2046_MISO 39 // T_OUT引脚
- #define XPT2046_CLK 25 // T_CLK引脚
- #define XPT2046_CS 33 // T_CS引脚
-
- SPIClass touchscreenSPI = SPIClass(VSPI); // 实例化一个SPI类,用于触摸屏通信
- XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ); // 创建触摸屏对象
-
- #define SCREEN_WIDTH 240 // 屏幕宽度定义
- #define SCREEN_HEIGHT 320 // 屏幕高度定义
-
- // 触摸屏坐标:(x, y) 和压力(z)
- int x, y, z;
-
- #define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8)) // 绘图缓冲区大小定义
- uint32_t draw_buf[DRAW_BUF_SIZE / 4]; // 绘图缓冲区
-
- // 如果启用了日志记录,它将告知用户库中发生了什么
- void log_print(lv_log_level_t level, const char* buf) {
- LV_UNUSED(level); // LVGL中未使用的宏
- Serial.println(buf); // 打印日志信息
- Serial.flush(); // 清空串口缓冲区
- }
-
- // 获取触摸屏数据
- void touchscreen_read(lv_indev_t* indev, lv_indev_data_t* data) {
- // 检查触摸屏是否被触摸,并打印X, Y和压力(Z)
- if (touchscreen.tirqTouched() && touchscreen.touched()) {
- // 获取触摸屏坐标点
- TS_Point p = touchscreen.getPoint();
- // 使用map函数校准触摸屏坐标点到正确的宽度和高度
- x = map(p.x, 200, 3700, 1, SCREEN_WIDTH);
- y = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);
- z = p.z;
-
- data->state = LV_INDEV_STATE_PRESSED; // 设置状态为按下
-
- // 设置坐标点
- data->point.x = x;
- data->point.y = y;
-
- // 在串口监视器上打印触摸屏信息关于X, Y和压力(Z)
- /* Serial.print("X = ");
- Serial.print(x);
- Serial.print(" | Y = ");
- Serial.print(y);
- Serial.print(" | Pressure = ");
- Serial.print(z);
- Serial.println();*/
- } else {
- data->state = LV_INDEV_STATE_RELEASED; // 设置状态为释放
- }
- }
-
- int btn1_count = 0; // 按钮1的计数器
- // 当按钮1被点击时触发的回调函数
- static void event_handler_btn1(lv_event_t* e) {
- lv_event_code_t code = lv_event_get_code(e); // 获取事件代码
- if (code == LV_EVENT_CLICKED) {
- btn1_count++; // 按钮计数器加1
- LV_LOG_USER("Button clicked %d", (int)btn1_count); // 用户日志记录按钮点击次数
- }
- }
-
- // 当按钮2被点击/切换时触发的回调函数
- static void event_handler_btn2(lv_event_t* e) {
- lv_event_code_t code = lv_event_get_code(e); // 获取事件代码
- lv_obj_t* obj = (lv_obj_t*)lv_event_get_target(e); // 获取事件目标对象
- if (code == LV_EVENT_VALUE_CHANGED) {
- LV_UNUSED(obj); // LVGL中未使用的宏
- LV_LOG_USER("Toggled %s", lv_obj_has_state(obj, LV_STATE_CHECKED) ? "on" : "off"); // 用户日志记录开关状态
- }
- }
-
- static lv_obj_t* slider_label; // 滑块标签对象
- // 回调函数,用于在TFT显示屏和串口监视器上打印当前滑块值,用于调试目的
- static void slider_event_callback(lv_event_t* e) {
- lv_obj_t* slider = (lv_obj_t*)lv_event_get_target(e); // 获取事件目标对象(滑块)
- char buf[8]; // 缓冲区
- lv_snprintf(buf, sizeof(buf), "%d%%", (int)lv_slider_get_value(slider)); // 获取滑块值并格式化为字符串
- lv_label_set_text(slider_label, buf); // 设置滑块标签文本
- lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); // 将滑块标签对齐到滑块下方
- LV_LOG_USER("Slider changed to %d%%", (int)lv_slider_get_value(slider)); // 用户日志记录滑块值
- }
-
- void lv_create_main_gui(void) {
- // 创建一个文本标签,居中显示在顶部("Hello, world!")
- lv_obj_t* text_label = lv_label_create(lv_screen_active());
- lv_label_set_long_mode(text_label, LV_LABEL_LONG_WRAP); // 自动换行
- lv_label_set_text(text_label, "Hello, world!");
- lv_obj_set_width(text_label, 150); // 设置较小的宽度以使文本换行
- lv_obj_set_style_text_align(text_label, LV_TEXT_ALIGN_CENTER, 0);
- lv_obj_align(text_label, LV_ALIGN_CENTER, 0, -90);
-
- lv_obj_t* btn_label;
- // 创建一个按钮(btn1)
- lv_obj_t* btn1 = lv_button_create(lv_screen_active());
- lv_obj_add_event_cb(btn1, event_handler_btn1, LV_EVENT_ALL, NULL);
- lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -50);
- lv_obj_remove_flag(btn1, LV_OBJ_FLAG_PRESS_LOCK);
-
- btn_label = lv_label_create(btn1);
- lv_label_set_text(btn_label, "Button");
- lv_obj_center(btn_label);
-
- // 创建一个切换按钮(btn2)
- lv_obj_t* btn2 = lv_button_create(lv_screen_active());
- lv_obj_add_event_cb(btn2, event_handler_btn2, LV_EVENT_ALL, NULL);
- lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 10);
- lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);
- lv_obj_set_height(btn2, LV_SIZE_CONTENT);
-
- btn_label = lv_label_create(btn2);
- lv_label_set_text(btn_label, "Toggle");
- lv_obj_center(btn_label);
-
- // 在TFT显示屏底部居中创建一个滑块
- lv_obj_t* slider = lv_slider_create(lv_screen_active());
- lv_obj_align(slider, LV_ALIGN_CENTER, 0, 60);
- lv_obj_add_event_cb(slider, slider_event_callback, LV_EVENT_VALUE_CHANGED, NULL);
- lv_slider_set_range(slider, 0, 100);
- lv_obj_set_style_anim_duration(slider, 2000, 0);
-
- // 在滑块下方创建一个标签以显示当前滑块值
- slider_label = lv_label_create(lv_screen_active());
- lv_label_set_text(slider_label, "0%");
- lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
- }
-
- void setup() {
- String LVGL_Arduino = String("LVGL Library Version: ") + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
- Serial.begin(115200); // 初始化串口通信,波特率为115200
- Serial.println(LVGL_Arduino); // 打印LVGL库版本信息
-
- // 启动LVGL
- lv_init();
- // 注册打印函数用于调试
- lv_log_register_print_cb(log_print);
-
- // 启动触摸屏的SPI并初始化触摸屏
- touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
- touchscreen.begin(touchscreenSPI);
- // 设置触摸屏旋转为横屏模式
- // 注意:在某些显示屏上,触摸屏可能是倒置的,因此可能需要将旋转设置为0:touchscreen.setRotation(0);
- touchscreen.setRotation(2);
-
- // 创建一个显示对象
- lv_display_t* disp;
- // 使用TFT_eSPI库初始化TFT显示屏
- disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));
- lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);
-
- // 初始化一个LVGL输入设备对象(触摸屏)
- lv_indev_t* indev = lv_indev_create();
- lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
- // 设置回调函数以读取触摸屏输入
- lv_indev_set_read_cb(indev, touchscreen_read); // 注册触摸屏读取回调函数
-
- // 绘制GUI(文本、按钮和滑块)
- lv_create_main_gui();
- }
-
- void loop() {
- lv_task_handler(); // 让GUI执行其任务
- lv_tick_inc(5); // 告诉LVGL已经过去了多少时间
- delay(5); // 让这段时间过去
- }
复制代码
|