【花雕学编程】Arduino LVGL 之模拟加载进度条

在这里插入图片描述

Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用Arduino IDE(集成开发环境)来编写、编译和上传代码到Arduino板上。Arduino还有一个丰富的库和社区,你可以利用它们来扩展Arduino的功能和学习Arduino的知识。

Arduino的特点是:
1、开放源码:Arduino的硬件和软件都是开放源码的,你可以自由地修改、复制和分享它们。
2、易用:Arduino的硬件和软件都是为初学者和非专业人士设计的,你可以轻松地上手和使用它们。
3、便宜:Arduino的硬件和软件都是非常经济的,你可以用很低的成本来实现你的想法。
4、多样:Arduino有多种型号和版本,你可以根据你的需要和喜好来选择合适的Arduino板。
5、创新:Arduino可以让你用电子的方式来表达你的创意和想象,你可以用Arduino来制作各种有趣和有用的项目,如机器人、智能家居、艺术装置等。

在这里插入图片描述
Arduino LVGL(Light and Versatile Graphics Library)是一个功能强大、轻量级的图形库,专为嵌入式系统设计,尤其适用于Arduino等微控制器平台。以下是对其主要特点、应用场景以及需要注意的事项的详细解释。

1、主要特点
1)轻量级:
LVGL是一个轻量级的图形库,适合资源有限的嵌入式系统。它在内存使用和处理速度上进行了优化,使其能够在低功耗设备上流畅运行。
2)丰富的组件:
LVGL提供了多种用户界面组件,比如按钮、滑块、图表、列表、图像等,开发者可以利用这些组件快速构建复杂的用户界面。
3)高效的渲染能力:
LVGL支持多种显示驱动程序,能够高效地渲染图形,支持抗锯齿、alpha混合等图形效果,从而提升界面的视觉质量。
4)灵活的主题和样式:
LVGL支持主题和样式的自定义,使得开发者可以根据需求轻松调整界面的外观,增加了界面的美观性和用户体验。
5)多种输入设备支持:
支持触摸屏、鼠标、键盘等多种输入设备,能够实现丰富的用户交互。
6)多平台支持:
LVGL不仅可以在Arduino上运行,还可以在多个嵌入式平台和操作系统上使用,包括ESP32、STM32、Linux等,具有良好的跨平台性。

2、应用场景
1)嵌入式设备的用户界面:
适用于需要图形用户界面的嵌入式设备,如智能家居控制面板、工业控制系统、医疗设备等。
2)物联网(IoT)设备:
在物联网应用中,LVGL可以用来构建设备的控制界面,例如智能传感器、网关设备的设置界面。
3)便携式设备:
适合用于便携式电子设备,如手持设备、智能手表等,因其轻量特性和高效性能能够满足电池供电的需求。
4)教育和原型开发:
适用于教育和原型开发环境,开发者可以快速实现用户界面,帮助学生和初学者理解图形界面的设计与实现。
5)高级应用:
可用于需要复杂图形和动画的应用,如游戏开发或多媒体应用,利用其渲染能力实现丰富的用户体验。

3、需要注意的事项
1)内存管理:
尽管LVGL是轻量级的,但在内存使用方面仍需谨慎。开发者需要合理管理内存,避免内存泄漏或溢出,特别是在资源受限的环境中。
2)性能优化:
在实现复杂界面时,需要对性能进行优化。例如,减少不必要的重绘,使用图像缓存等方法,提高界面的响应速度和流畅度。
3)输入设备的兼容性:
在选择输入设备时,要确保与LVGL的兼容性。例如,不同的触摸屏可能需要不同的驱动程序,开发者需要确保所用的硬件能够正常工作。
4)学习曲线:
LVGL虽然功能强大,但其使用和配置可能有一定的学习曲线。开发者需要花时间熟悉LVGL的API和工作流程,才能有效利用其功能。
5)文档与社区支持:
LVGL有较好的文档和社区支持,但在遇到问题时,开发者应积极查阅官方文档,参与社区讨论,以获得帮助和解决方案。

总结
Arduino LVGL是一个强大的图形库,适合在资源有限的嵌入式系统上构建高效的用户界面。通过其丰富的组件和灵活的特性,开发者可以实现多种应用场景中的图形界面。然而,在使用过程中,合理管理内存和优化性能是成功的关键。通过充分利用LVGL的特性,开发者能够创建出美观且功能强大的用户界面。

在这里插入图片描述
一、主要特点
(一)模拟加载特性
视觉反馈的渐进性
模拟加载进度条在 Arduino LVGL 中提供了一种直观的视觉反馈机制,它能够以渐进的方式展示加载过程。通过从初始状态(如 0% 加载)逐渐过渡到完成状态(如 100% 加载),让用户清晰地感知到任务的进展情况。例如,在加载一个大型文件或者初始化一个复杂系统时,进度条会随着加载进程的推进,如从左向右逐渐填充,给用户一种正在进行中的直观感受。
动态更新能力
可以根据加载任务的实际进度实时动态更新。这种动态更新是通过不断获取任务的完成比例,并将其映射到进度条的显示状态来实现的。例如,在一个网络数据下载任务中,进度条能够根据已接收的数据量与总数据量的比例,实时更新进度条的填充长度,精确地反映下载的进度。
(二)视觉呈现特点
自定义外观设计
具有高度的可定制性,包括进度条的颜色、形状、尺寸和样式。可以根据应用场景的整体风格和用户体验需求,将进度条设计成各种形式。例如,在一个具有科技感的应用中,进度条可以是带有发光效果的透明样式;在儿童教育应用中,进度条可以设计成色彩鲜艳、卡通形象的外观。
动画效果增强体验
通常可以添加动画效果来提升用户体验。比如,在进度条填充过程中,可以设置平滑的过渡动画,避免进度的跳跃式变化,使视觉效果更加自然流畅。还可以添加一些辅助动画,如在进度条两端添加闪烁的指示灯,或者在进度条上方显示动态的加载文本(如 “正在加载…”),增强用户对加载过程的关注度。
(三)与任务关联紧密
准确反映任务进度
进度条的状态紧密关联加载任务的实际进度。它能够准确地将任务的完成程度以可视化的方式呈现出来,帮助用户合理安排等待时间或者判断任务是否出现异常。例如,在一个软件更新任务中,如果进度条长时间停留在某个位置,用户可以据此推测可能是网络问题或者更新文件出现错误。
任务适配灵活性
可以适用于各种类型的加载任务,无论是文件读取、网络通信、系统初始化还是复杂算法的运算等。只要能够获取任务的进度信息,就可以通过适当的方式将其映射到进度条的显示上。例如,在一个机器视觉算法的处理过程中,根据已处理的图像帧数与总帧数的比例来更新进度条,展示算法的执行进度。

二、应用场景
(一)文件操作与数据传输
文件加载与保存
在文件读取和写入操作中,用于显示文件加载或保存的进度。例如,当打开一个高清视频文件或者大型数据库文件时,进度条可以向用户展示文件加载的进度,让用户知道还需要等待多长时间。同样,在保存文件时,进度条显示文件保存的完成情况,防止用户在文件未完全保存时误操作。
网络数据传输
用于网络数据的上传和下载场景。在移动应用的软件更新、云存储文件的下载或者向服务器上传数据(如监控视频上传)等过程中,模拟加载进度条可以让用户清楚地看到数据传输的进度,提高用户对网络状态和传输过程的感知。
(二)系统启动与初始化
设备开机过程
在电子设备开机时,用于展示系统初始化的进度。从硬件自检、系统内核加载到各种服务和应用的启动,进度条可以将这个复杂的过程以直观的方式呈现给用户。例如,在智能手机开机过程中,进度条可以显示手机从开机引导程序加载到桌面启动的各个阶段的进度,让用户对开机时间有一个预期。
软件初始化与配置加载
在软件启动时,用于显示软件初始化的进度。对于一些复杂的软件,如专业的图形设计软件或者工业控制软件,启动过程可能涉及加载大量的插件、配置文件和资源库,进度条可以告知用户软件正在进行初始化,减少用户的焦虑和误解。
(三)复杂任务执行与运算
算法运算过程
在执行复杂的算法运算时,如人工智能模型的训练、加密解密算法的运算或者科学计算中的大规模数据处理,进度条可以展示算法执行的进度。这对于需要长时间运行的算法尤其有用,用户可以根据进度条判断算法是否正常运行,以及大概还需要多长时间才能完成。
自动化设备任务执行
在自动化设备(如 3D 打印机、数控加工设备等)执行任务时,用于显示任务的进度。例如,3D 打印机在打印一个复杂的三维模型时,进度条可以根据已打印的层数与总层数的比例来展示打印进度,方便用户了解打印的剩余时间和进度情况。

三、需要注意的事项
(一)进度信息准确性
正确获取和更新进度
必须确保进度条所显示的进度信息与实际任务的进度准确匹配。这需要在加载任务的代码中,正确地计算和提供任务的完成比例。如果进度信息计算错误或者更新不及时,可能会导致进度条的显示与实际情况不符,误导用户。例如,在网络下载任务中,要准确计算已下载的数据量与文件总大小的比例,并及时更新进度条。
处理异常进度情况
需要考虑任务出现异常时进度条的显示情况。例如,当任务因为网络中断、资源不足或者其他原因而停止或失败时,进度条不能一直停留在最后更新的位置,而应该有相应的提示(如显示 “加载失败” 或者改变颜色等)来告知用户任务出现问题。
(二)用户体验优化
避免过度等待焦虑
虽然进度条能够让用户了解任务进度,但如果任务本身需要很长时间才能完成,长时间盯着进度条可能会让用户产生焦虑情绪。可以通过一些方式来缓解这种情绪,如在进度条旁边显示预计剩余时间,或者提供一些有趣的小动画、提示信息等,让用户在等待过程中不会感到过于无聊。
进度条速度与视觉效果平衡
进度条的填充速度应该与实际任务进度相匹配,同时要考虑视觉效果。如果填充速度过快,用户可能会觉得任务很简单,没有真实反映任务的复杂性;如果填充速度过慢,又会让用户觉得等待时间过长。此外,动画效果也不能过于复杂,以免分散用户对进度本身的注意力或者影响系统性能。
(三)性能和资源占用
实时更新的资源消耗
由于进度条需要实时更新,这可能会占用一定的系统资源,如 CPU 时间和内存。在资源有限的设备上,要注意进度条更新频率和动画效果对系统性能的影响。例如,在一个低功耗的物联网设备中,频繁地更新进度条可能会消耗过多的电量或者影响其他重要任务的执行。
资源管理和优化
要合理管理和优化进度条所占用的资源。可以通过减少不必要的动画效果、降低更新频率(在不影响用户体验的前提下)或者采用更高效的图形绘制方法等方式来降低资源占用。例如,在嵌入式系统中,可以根据设备的性能和任务的重要性,有选择地启用进度条的某些功能。

在这里插入图片描述
基本进度条
cpp

复制
#include <Arduino.h>
#include <lvgl.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();
lv_obj_t *progress_bar;

void setup() {
Serial.begin(115200);
tft.begin();
lv_init();
lv_disp_draw_buf_t draw_buf;
lv_color_t buf1[LV_HOR_RES_MAX * 10];
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, LV_HOR_RES_MAX * 10);

lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &draw_buf;
disp_drv.flush_cb = my_flush; // 自定义刷新函数
lv_disp_drv_register(&disp_drv);

progress_bar = lv_bar_create(lv_scr_act());
lv_obj_set_size(progress_bar, 200, 20);
lv_obj_align(progress_bar, LV_ALIGN_CENTER, 0, 0);
lv_bar_set_value(progress_bar, 0); // 初始化进度为 0

}

void loop() {
for (int i = 0; i <= 100; i++) {
lv_bar_set_value(progress_bar, i); // 更新进度条
lv_task_handler();
delay(50); // 模拟加载时间
}
}
示例代码 2:带文本的进度条
cpp

复制
#include <Arduino.h>
#include <lvgl.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();
lv_obj_t *progress_bar;
lv_obj_t *label;

void update_progress(int value) {
lv_bar_set_value(progress_bar, value); // 更新进度条
lv_label_set_text_fmt(label, “加载中: %d%%”, value); // 更新文本
}

void setup() {
Serial.begin(115200);
tft.begin();
lv_init();
lv_disp_draw_buf_t draw_buf;
lv_color_t buf1[LV_HOR_RES_MAX * 10];
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, LV_HOR_RES_MAX * 10);

lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &draw_buf;
disp_drv.flush_cb = my_flush; // 自定义刷新函数
lv_disp_drv_register(&disp_drv);

progress_bar = lv_bar_create(lv_scr_act());
lv_obj_set_size(progress_bar, 200, 20);
lv_obj_align(progress_bar, LV_ALIGN_CENTER, 0, 0);
lv_bar_set_value(progress_bar, 0); // 初始化进度为 0

label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "加载中: 0%");
lv_obj_align(label, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

}

void loop() {
for (int i = 0; i <= 100; i++) {
update_progress(i); // 更新进度和文本
lv_task_handler();
delay(50); // 模拟加载时间
}
}
示例代码 3:使用定时器更新进度条
cpp

复制
#include <Arduino.h>
#include <lvgl.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();
lv_obj_t *progress_bar;
lv_obj_t *label;
lv_timer_t *progress_timer;
int progress_value = 0;

void update_progress(lv_timer_t *timer) {
if (progress_value <= 100) {
lv_bar_set_value(progress_bar, progress_value); // 更新进度条
lv_label_set_text_fmt(label, “加载中: %d%%”, progress_value); // 更新文本
progress_value++;
}
}

void setup() {
Serial.begin(115200);
tft.begin();
lv_init();
lv_disp_draw_buf_t draw_buf;
lv_color_t buf1[LV_HOR_RES_MAX * 10];
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, LV_HOR_RES_MAX * 10);

lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &draw_buf;
disp_drv.flush_cb = my_flush; // 自定义刷新函数
lv_disp_drv_register(&disp_drv);

progress_bar = lv_bar_create(lv_scr_act());
lv_obj_set_size(progress_bar, 200, 20);
lv_obj_align(progress_bar, LV_ALIGN_CENTER, 0, 0);
lv_bar_set_value(progress_bar, 0); // 初始化进度为 0

label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "加载中: 0%");
lv_obj_align(label, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

progress_timer = lv_timer_create(update_progress, 100, NULL); // 每 100 毫秒更新一次

}

void loop() {
lv_task_handler();
delay(5);
}
要点解读
进度条的创建与初始化:
在每个示例中,通过 lv_bar_create 创建一个进度条,并设置其初始值为 0。进度条的尺寸和位置通过 lv_obj_set_size 和 lv_obj_align 进行配置,确保其在界面上的显示效果。
动态更新进度:
使用 lv_bar_set_value 方法动态更新进度条的值。第一个示例通过循环直接更新进度,第二个示例结合文本标签实时更新显示的百分比,增强了用户体验。
文本标签的集成:
第二个示例中,使用标签显示加载进度的百分比。通过 lv_label_create 创建标签,并使用 lv_label_set_text_fmt 来格式化显示文本,使得界面更加直观。
定时器的使用:
第三个示例展示了如何使用 LVGL 的定时器功能,定时更新进度条和文本。使用 lv_timer_create 创建一个定时器,每 100 毫秒更新一次进度,避免了在主循环中直接控制进度的复杂性。
LVGL 的初始化与显示刷新:
在每个示例中,都需要初始化 LVGL,创建显示缓冲区并注册显示驱动。自定义的 my_flush 函数需要根据具体的显示模块实现,以确保图形界面能够正确渲染并显示。
总结
通过使用 Arduino LVGL 实现模拟加载进度条,可以有效地展示任务进度,增强用户的互动体验。这些示例展示了如何利用 LVGL 的基本功能创建进度条并动态更新其状态,帮助理解在嵌入式 GUI 开发中的常用方法和技巧。

在这里插入图片描述
基本加载进度条
代码示例
cpp

复制
#include <lvgl.h>
#include <Arduino.h>

lv_obj_t *bar;

void update_progress(lv_task_t *task) {
static int progress = 0;
progress += 5; // 每次增加 5%
if (progress > 100) {
progress = 0; // 重置进度
}
lv_bar_set_value(bar, progress, LV_ANIM_ON); // 更新进度条值
}

void setup() {
Serial.begin(115200);
lv_init();

lv_obj_t *screen = lv_obj_create(NULL);
lv_scr_load(screen);

bar = lv_bar_create(screen); // 创建进度条
lv_obj_set_size(bar, 240, 20); // 设置进度条大小
lv_obj_align(bar, LV_ALIGN_CENTER, 0, 0); // 对齐到中心

lv_task_create(update_progress, 1000, LV_TASK_PRIO_MID, NULL); // 每秒更新一次进度

}

void loop() {
lv_task_handler();
delay(5);
}
要点解读
进度条创建:使用 lv_bar_create 创建基本进度条,展示了 LVGL 提供的简洁 API。
动态更新进度:在 update_progress 函数中,每秒增加进度值,模拟加载过程。
进度重置:当进度达到 100% 时,重置为 0%,展示了循环加载的效果。
可视化反馈:通过进度条的变化,用户可以直观了解加载状态,提高了用户体验。
任务管理:使用 lv_task_create 创建定时任务,展示了 LVGL 在任务管理方面的能力。
案例 2:带文本的加载进度条
代码示例
cpp

复制
#include <lvgl.h>
#include <Arduino.h>

lv_obj_t *bar;
lv_obj_t *label;

void update_progress(lv_task_t *task) {
static int progress = 0;
progress += 5; // 每次增加 5%
if (progress > 100) {
progress = 0; // 重置进度
}
lv_bar_set_value(bar, progress, LV_ANIM_ON); // 更新进度条值
lv_label_set_text_fmt(label, “Loading… %d%%”, progress); // 更新文本
}

void setup() {
Serial.begin(115200);
lv_init();

lv_obj_t *screen = lv_obj_create(NULL);
lv_scr_load(screen);

bar = lv_bar_create(screen); // 创建进度条
lv_obj_set_size(bar, 240, 20);
lv_obj_align(bar, LV_ALIGN_CENTER, 0, 0); // 对齐到中心

label = lv_label_create(screen); // 创建标签
lv_label_set_text(label, "Loading... 0%"); // 初始化文本
lv_obj_align(label, LV_ALIGN_CENTER, 0, -30); // 对齐到进度条上方

lv_task_create(update_progress, 1000, LV_TASK_PRIO_MID, NULL);

}

void loop() {
lv_task_handler();
delay(5);
}
要点解读
文本标签添加:通过 lv_label_create 创建文本标签,实时显示当前加载进度,增强了用户交互体验。
文本动态更新:在 update_progress 函数中使用 lv_label_set_text_fmt 更新文本内容,直观显示进度。
布局设计:通过对齐设置,将进度条和文本标签进行合理布局,使界面清晰易读。
进度可视化:用户可以通过文本与进度条共同了解加载状态,提升了信息传递的有效性。
定时更新:每秒更新进度,展示了 LVGL 在动态界面设计中的应用。
案例 3:带动画效果的加载进度条
代码示例
cpp

复制
#include <lvgl.h>
#include <Arduino.h>

lv_obj_t *bar;

void update_progress(lv_task_t *task) {
static int progress = 0;
progress += 5; // 每次增加 5%
if (progress > 100) {
progress = 0; // 重置进度
}
lv_bar_set_value(bar, progress, LV_ANIM_ON); // 更新进度条值,带动画效果
}

void setup() {
Serial.begin(115200);
lv_init();

lv_obj_t *screen = lv_obj_create(NULL);
lv_scr_load(screen);

bar = lv_bar_create(screen); // 创建进度条
lv_obj_set_size(bar, 240, 20);
lv_obj_align(bar, LV_ALIGN_CENTER, 0, 0); // 对齐到中心

lv_bar_set_style(bar, LV_BAR_STYLE_BG, &style_bg); // 设置背景样式
lv_bar_set_style(bar, LV_BAR_STYLE_INDIC, &style_indic); // 设置进度条样式

lv_task_create(update_progress, 1000, LV_TASK_PRIO_MID, NULL);

}

void loop() {
lv_task_handler();
delay(5);
}
要点解读
动画效果:使用 LV_ANIM_ON 使进度条更新时带有动画效果,提升了用户视觉体验。
样式设置:通过 lv_bar_set_style 方法设置进度条和背景样式,提供了更好的界面美观性。
动态数据处理:在 update_progress 函数中动态更新进度值,模拟加载过程,适应不同需求。
界面交互:进度条的动画效果使得用户在等待时不会感到枯燥,提升了用户体验。
任务管理:使用定时任务实现进度更新,展示了 LVGL 在动态界面设计中的灵活性。

注意,以上案例只是为了拓展思路,仅供参考。它们可能有错误、不适用或者无法编译。您的硬件平台、使用场景和Arduino版本可能影响使用方法的选择。实际编程时,您要根据自己的硬件配置、使用场景和具体需求进行调整,并多次实际测试。您还要正确连接硬件,了解所用传感器和设备的规范和特性。涉及硬件操作的代码,您要在使用前确认引脚和电平等参数的正确性和安全性。

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

驴友花雕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值