当前位置: 首页 > article >正文

【LVGL】给SquareLineStudio导出的Arduino工程添加物理按键

〇、前言

书接上回(用SquareLine Studio轻松实现ESP8266运行LVGL图形化界面-CSDN博客),用SquareLineStudio导出界面,并通过Arduino下载到esp8266后运行如下:

可是这里的屏幕不是触摸屏,该如何使用屏幕上的button组件呢?

下面使用的代码,是上篇文章中导出的界面代码,这里需要给界面添加可操作性,增加物理按键。

一、物理按键定义

1.1 物理按键引脚连接

这里使用 D0(GPIO16)和 D1(GPIO5)引脚分别作为【聚焦切换】和【确定】物理按键控制屏幕的2个按钮。
使用下拉电阻方式连接引脚,如图:

1.2 功能定义

如图,给两个物理按键定义功能:
这里举个例子,按下【D0】物理按键,假如选框在【add】按钮组件上,那么再按一下【D1】按键,就会实现value值的增加。再按下【D0】选框在【sub】按钮组件上,那么再按一下【D1】按键,就会实现value值的减少。
注意这里为什么2个物理按键不分别对应【add】按钮和【sub】按钮?
1、如果用这种方式,那么可以用2个物理按键控制更多的按钮组件。
2、lvgl运行后默认聚焦在第一个添加进组的按钮上,如果没有聚焦切换功能按钮,另一个按钮则无法使用。

二、修改代码部分

主要涉及修改的文件就2个,分别是 .\SquareLine_Project\ui\ui.ino.\SquareLine_Project\libraries\ui\src\ui.c文件,下面是修改部分和注释:

2.1 删除部分(可跳过)

因为这里用的屏幕是非触摸屏, SquareLineStudio导出的代码默认是带有触摸部分的,这里不需要,可以删除该部分。下面列出的部分是需要删除的代码(实际这部分不删,也不影响运行)
  • ui.ino
/*Read the touchpad*/
void my_touchpad_read (lv_indev_t * indev_driver, lv_indev_data_t * data)        //整个my_touchpad_read函数需要删除掉
{
    uint16_t touchX = 0, touchY = 0;

    bool touched = false;//tft.getTouch( &touchX, &touchY, 600 );

    if (!touched)
    {
        data->state = LV_INDEV_STATE_REL;
    }
    else
    {
        data->state = LV_INDEV_STATE_PR;

        /*Set the coordinates*/
        data->point.x = touchX;
        data->point.y = touchY;

        Serial.print( "Data x " );
        Serial.println( touchX );

        Serial.print( "Data y " );
        Serial.println( touchY );
    }
}

void setup(){
    ... ...     // 其他部分代码省略
    static lv_indev_t* indev;                // setup函数中的创建设备的部分, 从这里开始往下4行都删除
    indev = lv_indev_create();
    lv_indev_set_type( indev, LV_INDEV_TYPE_POINTER );
    lv_indev_set_read_cb( indev, my_touchpad_read );    
    ... ...
}

2.2 增加代码

  • ui.ino
ui.ino部分主要是增加输入设备组的创建函数和读取按键状态值回调函数,下面是需要增加的代码:
... ...
lv_group_t *gp;    // 新增全局变量gp,用于创建组
... ...
void my_keypad_read(lv_indev_t *indev_driver, lv_indev_data_t *data)    // 新增函数my_keypad_read:回调函数用于读取按键状态和按键值
{
    if(digitalRead(D0) == HIGH) {    // 读取D0是否被按下(实际高低由实际按键接线为准)
        data->state = LV_INDEV_STATE_PR;    // 定义按键状态是【press/按下】
        data->key = LV_KEY_NEXT;            // 设置值为LV_KEY_NEXT,D0定义为【聚焦切换】功能按键
    }else if(digitalRead(D1) == HIGH){      // 读取D1是否被按下
        data->state = LV_INDEV_STATE_PR;    // 定义按键状态是【press/按下】
        data->key = LV_KEY_ENTER;           // 设置值为LV_KEY_ENTER,D0定义为【确定】功能按键
    }
    else {
        data->state = LV_INDEV_STATE_REL;    // 定义按键状态是【release/松开】
    }
}

void set_button(void){                                // 新增set_button函数:创建输入设备组函数
  static lv_indev_t* indev;
  indev = lv_indev_create();                        // 创建一个输入设备
(indev)
  lv_indev_set_type(indev, LV_INDEV_TYPE_KEYPAD);    // 该输入设备类型定义为键盘(KEYPAD)
  lv_indev_set_read_cb(indev, my_keypad_read);       // 键盘绑定回调函数my_keypad_read,回调函数读取键盘状态和按键值
  gp = lv_group_create();                            // 创建按键组
  lv_group_set_default(gp);                          // 设为默认组(实际开发可能多个设备组,这里就一个组)
  lv_group_add_obj(gp, ui_Button1);                  // 将按键组件1和按键组件2分别加入按键组
  lv_group_add_obj(gp, ui_Button2);
  lv_indev_set_group(indev, gp);                    // 将输入设备和按键组绑定。
}

void setup(){
    pinMode(D0, INPUT);  // 定义为【聚焦切换】按键
    pinMode(D1, INPUT);  // 定义为【确定】按键
    Serial.begin( 115200 );
    ... ...  // 中间省略部分
    ui_init();
    set_button(); // 一定在ui_init()函数后面调用set_button()函数创建输入设备组,因为按键组件在ui_init()中才被初始化。

    Serial.println( "Setup done" );
}

  • ui.c
主要是修改按键的事件,根据按键的值实现对应的功能,下面是需要增改的函数
... ...
void set_focus_obj(void){    //新增函数set_focus_obj,用于切换不同的聚焦组件
  lv_obj_t * arr[] = {ui_Button1, ui_Button2};    // 需要循环聚焦的按钮组件列表
  static unsigned char index = 0;
  lv_group_focus_obj(arr[++index % 2]);        // 设置当前需要聚焦的按钮组件
}

void ui_event_Button1(lv_event_t * e)            // 修改函数ui_event_Button1:需要修改的按钮1事件函数
{
    lv_event_code_t event_code = lv_event_get_code(e);    // 获取当前发生的事件
    if(event_code == LV_EVENT_KEY) {            // 判断是否有按键事件
      if(lv_event_get_key(e) == LV_KEY_NEXT){   // 判断是否【聚焦切换】按键按下
        set_focus_obj();                        // 调用切换聚焦组件函数
      }else if(lv_event_get_key(e) == LV_KEY_ENTER)    // 判断是否有【确定】键按下
          _ui_slider_increment(ui_Slider1, -1, LV_ANIM_ON);    // 使slider值加-1,即减1
    }

}

void ui_event_Button2(lv_event_t * e)            // 修改函数ui_event_Button2:需要修改的按钮2事件函数
{
    lv_event_code_t event_code = lv_event_get_code(e);     // 获取当前发生的事件
    if(event_code == LV_EVENT_KEY) {             // 判断是否有按键事件
      if(lv_event_get_key(e) == LV_KEY_NEXT){    // 判断是否【聚焦切换】按键按下
        set_focus_obj();                           // 调用切换聚焦组件函数
      }else if(lv_event_get_key(e) == LV_KEY_ENTER){    // 判断是否有【确定】键按下
        _ui_slider_increment(ui_Slider1, 1, LV_ANIM_ON);  // 使slider值加1,
      }
    }
}

... ...

三、查看效果

用SquareLine导出esp8266单片机的arduino工程,对其lvgl添加物理按键代码,运行结果呈现


http://www.kler.cn/a/467241.html

相关文章:

  • 【USRP】教程:在Macos M1(Apple芯片)上安装UHD驱动(最正确的安装方法)
  • Linux运维相关基础知识(二)
  • 【python因果库实战15】因果生存分析4
  • 凸包(convex hull)简述
  • 图像分割基础:使用Python和scikit-image库
  • 企业级网络运维管理系统深度解析与实践案例
  • 树莓派4b如何连接ov7670摄像头
  • pyinstaller冻结打包多进程程序的bug:无限创建进程直至系统崩溃
  • Computed在Vue2、Vue3写法的不同
  • 奇怪的Python:为何 list 和 dict 的元素顺序从 Python 3.7 开始保持插入顺序?
  • ROS小记
  • 提升汽车金融租赁系统的效率与风险管理策略探讨
  • DELL EMC Unity 存储系统扩容之传统池扩容
  • CSS clip-path 属性
  • Vue项目整合与优化
  • 2024秋语法分析作业-B(满分25分)
  • 【0x0014】HCI_Read_Local_Name命令详解
  • 在 macOS 上,你可以使用系统自带的 终端(Terminal) 工具,通过 SSH 协议远程连接服务器
  • 每天40分玩转Django:Django Celery
  • 升级ubuntu24后遗症
  • redis7基础篇2 redis的哨兵模式2
  • BGP基础配置实验
  • 【第二部分--Python之基础】04 函数
  • 广域网连接PPP
  • 气膜滑雪馆:科技创新引领四季滑雪,推动冰雪运动普及—轻空间
  • Unity 中计算射线和平面相交距离的原理