【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
cpp 复制代码
/*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部分主要是增加输入设备组的创建函数和读取按键状态值回调函数,下面是需要增加的代码:
cpp 复制代码
... ...
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
    主要是修改按键的事件,根据按键的值实现对应的功能,下面是需要增改的函数
cpp 复制代码
... ...
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添加物理按键代码,运行结果呈现

相关推荐
小禾苗_2 小时前
51单片机——按键实验
单片机·嵌入式硬件·51单片机
浅陌pa4 小时前
I2C(一):存储器模式:stm32作为主机对AT24C02写读数据
c语言·stm32·单片机·嵌入式硬件
半个番茄4 小时前
STM32 和 ESP32
stm32·单片机·嵌入式硬件
code .5 小时前
STM32G431收发CAN
单片机·嵌入式硬件·can·canfd·stm32g4
xachary6 小时前
Arduino 小白的 DIY 空气质量检测仪(5)- OLED显示模块、按钮模块
物联网·嵌入式·arduino
无情大菜刀7 小时前
EPS32基础篇开发
单片机·嵌入式硬件
亿道电子Emdoor14 小时前
【ARM】MDK-快捷键添加及修改
arm开发·stm32·单片机
heater40416 小时前
【STM32】stm32启动流程
stm32·单片机·嵌入式硬件
honey ball18 小时前
滤波器的主要参数
人工智能·单片机·嵌入式硬件·学习
浅陌pa18 小时前
RTC:实时时钟
c语言·stm32·单片机·嵌入式硬件