〇、前言
书接上回(用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添加物理按键代码,运行结果呈现