【花雕学编程】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 之带有边框样式的计数器
在 Arduino 和 LVGL(Light and Versatile Graphics Library)开发中,带有边框样式的计数器是一种常用的用户界面控件,通常用于数值的增加或减少,能够直观地展示当前的计数值。通过边框样式的设计,计数器不仅具有功能性,还能提升界面的美观性。

主要特点
视觉分隔:
边框样式为计数器提供了明显的视觉分隔,帮助用户更容易地识别计数器的区域,提升了界面的可读性。
多样化的样式定制:
开发者可以根据需求自定义边框的颜色、厚度、样式(如实线、虚线等),以及计数器的背景颜色和字体样式,以适应不同的应用和设计风格。
状态反馈:
在不同操作状态下(如正常、按下、禁用等),计数器可以根据其状态变化边框样式,提供即时反馈,增强用户体验。
易于集成:
LVGL 提供简洁的 API,使得带有边框样式的计数器能够方便地与其他界面元素(如按钮、滑块等)结合使用,构建复杂的用户交互界面。
响应式设计:
计数器可以根据用户操作(如增加、减少计数)实时更新显示的数值,并在更新时保持边框样式的一致性,提升交互体验。

应用场景
参数设置:
在设备或应用的设置界面中,带有边框样式的计数器可以用于调整参数,如音量、亮度、温度等,确保用户能够方便地设置所需值。
库存管理:
在库存管理系统中,计数器可用于跟踪库存数量,用户可以通过增加或减少操作快速更新库存信息。
游戏计分:
在游戏应用中,计数器可以用于记录分数或时间,边框样式的设计能够使计数器在界面中更加突出,提升用户的使用体验。
数字选择:
在问卷调查或电子表单中,计数器可以用于选择数字类型的答案,如人数、数量等,通过视觉样式提高用户输入的准确性。
实时数据监控:
在数据监控系统中,计数器能够实时显示监测到的数据,如温度、湿度等,带有边框样式的计数器能够清晰地展示重要信息。

需要注意的事项
边框设计一致性:
在整个应用中保持边框样式的一致性,确保所有计数器的边框设计协调,提升用户界面的专业感和美观性。
性能考虑:
在设计复杂的边框样式时,需注意性能影响,避免过多的图形元素导致界面卡顿,特别是在资源有限的嵌入式设备上。
用户交互的清晰性:
确保计数器的操作逻辑清晰,用户能够直观理解如何增加或减少计数,避免因设计不当导致的混淆。
状态管理:
设计合理的状态管理机制,以确保计数器在不同状态下(如禁用、按下等)具有明确的视觉反馈。
适配不同屏幕尺寸:
在设计计数器时,考虑不同屏幕尺寸的适配问题,确保在各种设备上都有良好的显示效果。
测试与验证:
在开发完成后,进行充分的测试,确保计数器在各种情况下都能正常工作,并满足设计要求和用户期望。

总结
带有边框样式的计数器在 Arduino 和 LVGL 开发中提供了直观的数值输入和用户友好的交互体验。通过合理的设计和实现,计数器能够满足多种应用需求,提升用户体验。在开发过程中,关注边框设计的一致性、性能优化和用户交互的清晰性,将有助于创建高质量的用户界面,确保系统的稳定性和用户的满意度。

在这里插入图片描述
1、基本的带有边框样式的计数器

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

// TFT实例化
TFT_eSPI tft = TFT_eSPI();
int count = 0;

// 显示刷新回调
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  tft.startWrite();
  tft.setAddrWindow(area->x1, area->y1, area->x2 - area->x1 + 1, area->y2 - area->y1 + 1);
  tft.pushColors(&color_p->full, (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1), true);
  tft.endWrite();
  lv_disp_flush_ready(disp);
}

// 按钮事件回调
void btn_event_cb(lv_event_t *e) {
  lv_event_code_t code = lv_event_get_code(e);
  lv_obj_t *label = (lv_obj_t *)lv_event_get_user_data(e);

  if (code == LV_EVENT_CLICKED) {
    count++;
    lv_label_set_text_fmt(label, "Count: %d", count);
  }
}

void setup() {
  Serial.begin(115200);
  lv_init();
  tft.begin();
  tft.setRotation(1);

  static lv_color_t buf[TFT_WIDTH * 10];
  static lv_disp_draw_buf_t draw_buf;
  lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * 10);

  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.hor_res = TFT_WIDTH;
  disp_drv.ver_res = TFT_HEIGHT;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register(&disp_drv);

  lv_obj_t *label = lv_label_create(lv_scr_act());
  lv_label_set_text(label, "Count: 0");
  lv_obj_align(label, LV_ALIGN_CENTER, 0, -40);

  lv_obj_t *btn = lv_btn_create(lv_scr_act());
  lv_obj_set_size(btn, 100, 50);
  lv_obj_set_style_border_color(btn, lv_color_hex(0x0000FF), 0);
  lv_obj_set_style_border_width(btn, 3, 0);
  lv_obj_align(btn, LV_ALIGN_CENTER, 0, 40);
  lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, label);

  lv_obj_t *btn_label = lv_label_create(btn);
  lv_label_set_text(btn_label, "Increment");
  lv_obj_center(btn_label);
}

void loop() {
  lv_timer_handler();
  delay(5);
}

2、带有不同状态边框样式的计数器

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

// TFT实例化
TFT_eSPI tft = TFT_eSPI();
int count = 0;

// 显示刷新回调
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  tft.startWrite();
  tft.setAddrWindow(area->x1, area->y1, area->x2 - area->x1 + 1, area->y2 - area->y1 + 1);
  tft.pushColors(&color_p->full, (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1), true);
  tft.endWrite();
  lv_disp_flush_ready(disp);
}

// 按钮事件回调
void btn_event_cb(lv_event_t *e) {
  lv_event_code_t code = lv_event_get_code(e);
  lv_obj_t *label = (lv_obj_t *)lv_event_get_user_data(e);

  if (code == LV_EVENT_CLICKED) {
    count++;
    lv_label_set_text_fmt(label, "Count: %d", count);
  }
}

void setup() {
  Serial.begin(115200);
  lv_init();
  tft.begin();
  tft.setRotation(1);

  static lv_color_t buf[TFT_WIDTH * 10];
  static lv_disp_draw_buf_t draw_buf;
  lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * 10);

  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.hor_res = TFT_WIDTH;
  disp_drv.ver_res = TFT_HEIGHT;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register(&disp_drv);

  lv_obj_t *label = lv_label_create(lv_scr_act());
  lv_label_set_text(label, "Count: 0");
  lv_obj_align(label, LV_ALIGN_CENTER, 0, -40);

  lv_obj_t *btn = lv_btn_create(lv_scr_act());
  lv_obj_set_size(btn, 100, 50);
  lv_obj_set_style_border_color(btn, lv_color_hex(0x0000FF), 0);
  lv_obj_set_style_border_width(btn, 3, 0);
  lv_obj_align(btn, LV_ALIGN_CENTER, 0, 40);
  lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, label);

  // 设置按钮按下时的边框样式
  lv_obj_set_style_border_color(btn, lv_color_hex(0xFF0000), LV_STATE_PRESSED);
  lv_obj_set_style_border_width(btn, 5, LV_STATE_PRESSED);

  lv_obj_t *btn_label = lv_label_create(btn);
  lv_label_set_text(btn_label, "Increment");
  lv_obj_center(btn_label);
}

void loop() {
  lv_timer_handler();
  delay(5);
}

在这里插入图片描述
3、基本边框样式计数器

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

lv_obj_t *label;
lv_obj_t *btn_increment;
lv_obj_t *btn_decrement;
static int count = 0;

void update_label() {
    lv_label_set_text_fmt(label, "计数: %d", count);
}

void increment_event_handler(lv_event_t *e) {
    count++;
    update_label();
}

void decrement_event_handler(lv_event_t *e) {
    count--;
    update_label();
}

void setup() {
    lv_init();
    // 初始化显示和输入设备...

    // 创建边框样式的容器
    lv_obj_t *container = lv_obj_create(lv_scr_act());
    lv_obj_set_size(container, 200, 120);
    lv_obj_align(container, NULL, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_style_border_color(container, lv_color_hex(0x000000), 0); // 黑色边框
    lv_obj_set_style_border_width(container, 2, 0); // 边框宽度
    lv_obj_set_style_bg_color(container, lv_color_hex(0xFFFFFF), 0); // 白色背景

    // 创建标签
    label = lv_label_create(container);
    update_label(); // 初始化标签
    lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -10);

    // 创建增加按钮
    btn_increment = lv_btn_create(container);
    lv_obj_set_size(btn_increment, 80, 40);
    lv_obj_align(btn_increment, NULL, LV_ALIGN_CENTER, 0, 20);
    lv_obj_add_event_cb(btn_increment, increment_event_handler, LV_EVENT_CLICKED, NULL);
    lv_obj_t *label_increment = lv_label_create(btn_increment);
    lv_label_set_text(label_increment, "增加");
    lv_obj_center(label_increment);

    // 创建减少按钮
    btn_decrement = lv_btn_create(container);
    lv_obj_set_size(btn_decrement, 80, 40);
    lv_obj_align(btn_decrement, NULL, LV_ALIGN_CENTER, 0, 70);
    lv_obj_add_event_cb(btn_decrement, decrement_event_handler, LV_EVENT_CLICKED, NULL);
    lv_obj_t *label_decrement = lv_label_create(btn_decrement);
    lv_label_set_text(label_decrement, "减少");
    lv_obj_center(label_decrement);

    // 启动LVGL任务处理
    lv_task_create(lv_task_handler, 10, LV_TASK_PRIO_MID, NULL);
}

void loop() {
    lv_task_handler(); // 处理LVGL任务
    delay(5); // 延迟
}

要点解读
容器创建:使用lv_obj_create()创建一个容器对象,作为计数器的背景,并设置边框和背景颜色,增强界面的层次感。
边框样式设置:通过lv_obj_set_style_border_color()和lv_obj_set_style_border_width()设置容器的边框样式,使计数器看起来更加美观。
动态标签更新:在计数器的事件处理函数中使用lv_label_set_text_fmt()动态更新显示的计数值,提供实时反馈。
按钮交互:分别创建增加和减少按钮,并为其注册事件处理函数,实现计数器的基本功能。
LVGL任务处理:在loop()中调用lv_task_handler(),保持界面的动态更新,确保用户操作能够及时反馈到界面。

4、带有边框和渐变背景的计数器

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

lv_obj_t *label;
lv_obj_t *btn_increment;
lv_obj_t *btn_decrement;
static int count = 0;

void update_label() {
    lv_label_set_text_fmt(label, "计数: %d", count);
}

void increment_event_handler(lv_event_t *e) {
    count++;
    update_label();
}

void decrement_event_handler(lv_event_t *e) {
    count--;
    update_label();
}

void setup() {
    lv_init();
    // 初始化显示和输入设备...

    // 创建边框样式的容器
    lv_obj_t *container = lv_obj_create(lv_scr_act());
    lv_obj_set_size(container, 200, 120);
    lv_obj_align(container, NULL, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_style_border_color(container, lv_color_hex(0x000000), 0); // 黑色边框
    lv_obj_set_style_border_width(container, 2, 0); // 边框宽度
    lv_obj_set_style_bg_color(container, lv_color_hex(0xFFFFFF), 0); // 白色背景
    lv_obj_set_style_bg_opa(container, LV_OPA_COVER, 0);
    lv_obj_set_style_bg_grad_color(container, lv_color_hex(0xFFCCCC), 0); // 渐变背景
    lv_obj_set_style_bg_grad_dir(container, LV_GRAD_DIR_VER, 0); // 垂直渐变

    // 创建标签
    label = lv_label_create(container);
    update_label(); // 初始化标签
    lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -10);

    // 创建增加按钮
    btn_increment = lv_btn_create(container);
    lv_obj_set_size(btn_increment, 80, 40);
    lv_obj_align(btn_increment, NULL, LV_ALIGN_CENTER, 0, 20);
    lv_obj_add_event_cb(btn_increment, increment_event_handler, LV_EVENT_CLICKED, NULL);
    lv_obj_t *label_increment = lv_label_create(btn_increment);
    lv_label_set_text(label_increment, "增加");
    lv_obj_center(label_increment);

    // 创建减少按钮
    btn_decrement = lv_btn_create(container);
    lv_obj_set_size(btn_decrement, 80, 40);
    lv_obj_align(btn_decrement, NULL, LV_ALIGN_CENTER, 0, 70);
    lv_obj_add_event_cb(btn_decrement, decrement_event_handler, LV_EVENT_CLICKED, NULL);
    lv_obj_t *label_decrement = lv_label_create(btn_decrement);
    lv_label_set_text(label_decrement, "减少");
    lv_obj_center(label_decrement);

    // 启动LVGL任务处理
    lv_task_create(lv_task_handler, 10, LV_TASK_PRIO_MID, NULL);
}

void loop() {
    lv_task_handler(); // 处理LVGL任务
    delay(5); // 延迟
}

要点解读
渐变背景设置:通过lv_obj_set_style_bg_grad_color()设置容器的渐变背景,使界面更加生动和美观。
边框样式保持:依然保留黑色边框的设置,使计数器在渐变背景下更加突出。
动态更新:与前一个案例相同,通过事件处理函数更新标签内容,实现计数器的功能。
交互按钮设计:增加和减少按钮的设计与功能保持一致,确保用户可以方便地操作计数器。
界面美观提升:通过渐变和边框的结合,提升了用户界面的视觉效果,增强用户体验。

5、带有边框和图标的计数器

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

lv_obj_t *label;
lv_obj_t *btn_increment;
lv_obj_t *btn_decrement;
static int count = 0;

void update_label() {
    lv_label_set_text_fmt(label, "计数: %d", count);
}

void increment_event_handler(lv_event_t *e) {
    count++;
    update_label();
}

void decrement_event_handler(lv_event_t *e) {
    count--;
    update_label();
}

void setup() {
    lv_init();
    // 初始化显示和输入设备...

    // 创建边框样式的容器
    lv_obj_t *container = lv_obj_create(lv_scr_act());
    lv_obj_set_size(container, 200, 120);
    lv_obj_align(container, NULL, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_style_border_color(container, lv_color_hex(0x000000), 0); // 黑色边框
    lv_obj_set_style_border_width(container, 2, 0); // 边框宽度
    lv_obj_set_style_bg_color(container, lv_color_hex(0xFFFFFF), 0); // 白色背景

    // 创建标签
    label = lv_label_create(container);
    update_label(); // 初始化标签
    lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -10);

    // 创建增加按钮
    btn_increment = lv_btn_create(container);
    lv_obj_set_size(btn_increment, 80, 40);
    lv_obj_align(btn_increment, NULL, LV_ALIGN_CENTER, 0, 20);
    lv_obj_add_event_cb(btn_increment, increment_event_handler, LV_EVENT_CLICKED, NULL);
    lv_obj_t *label_increment = lv_label_create(btn_increment);
    lv_label_set_text(label_increment, "增加");
    lv_obj_center(label_increment);

    // 创建减少按钮
    btn_decrement = lv_btn_create(container);
    lv_obj_set_size(btn_decrement, 80, 40);
    lv_obj_align(btn_decrement, NULL, LV_ALIGN_CENTER, 0, 70);
    lv_obj_add_event_cb(btn_decrement, decrement_event_handler, LV_EVENT_CLICKED, NULL);
    lv_obj_t *label_decrement = lv_label_create(btn_decrement);
    lv_label_set_text(label_decrement, "减少");
    lv_obj_center(label_decrement);

    // 添加图标
    lv_obj_t *icon = lv_img_create(container);
    lv_img_set_src(icon, &my_icon); // 假设my_icon是预定义的图标资源
    lv_obj_align(icon, label, LV_ALIGN_OUT_TOP_MID, 0, -10);

    // 启动LVGL任务处理
    lv_task_create(lv_task_handler, 10, LV_TASK_PRIO_MID, NULL);
}

void loop() {
    lv_task_handler(); // 处理LVGL任务
    delay(5); // 延迟
}

要点解读
图标添加:通过lv_img_create()添加图标,使计数器的界面更加丰富,提升视觉效果。
边框样式保持:边框样式和背景设置与前面案例相同,保持界面的统一性和美观性。
动态文本更新:通过事件处理函数更新计数标签的内容,确保用户能够实时看到计数变化。
交互性设计:保持增加和减少按钮的功能,为用户提供方便的交互方式。
界面元素布局:合理布局图标、标签和按钮,使界面清晰、简洁且易于操作,提升用户体验。

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

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

驴友花雕

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

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

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

打赏作者

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

抵扣说明:

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

余额充值