[esp32 + LVGL]物理按键控制屏幕上开关和LED闪烁

本文介绍了一种使用按键控制LED闪烁,并通过软件模拟触摸屏开关状态的方法。利用Arduino平台,通过读取按键状态改变LED状态,同时更新LVGL界面上虚拟开关的状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请添加图片描述

1.简述

IO0 对应按键 控制 IO2LED闪烁,同时当LED亮的时候开关闭合,当LED灭的时候LED闪烁。
为什么这么做,因为手里没有触摸屏。

2. 实现原理

首先我们要明白开关闭合的原理,对于触摸屏来说,当你触摸开关的时候会触发点击事件,同时给开关控件添加点击事件。
添加点击事件,也就是开关闭合

 lv_obj_add_state(guider_ui.screen_sw_1,LV_STATE_CHECKED);
清除点击事件,也就是开关打开
lv_obj_clear_state(guider_ui.screen_sw_1,LV_STATE_CHECKED);

#3.部分代码

    pinMode(LED,OUTPUT);
    pinMode(key, INPUT);
}
    bool state_led = 0;
    uint8_t key_state = 0;
void key_scan()
{
    if(digitalRead(key)==LOW){
        delay(10);
        if(digitalRead(key)==LOW){
            key_state++;
            if(key_state>=200) key_state =200;
        }
    }
    else key_state = 0;
}
void loop()
{    key_scan();
    if(key_state==2){
        state_led = !state_led;
        if(state_led){
        digitalWrite(LED,LOW);
        lv_obj_clear_state(guider_ui.screen_sw_1,LV_STATE_CHECKED);
        }


        else {digitalWrite(LED,HIGH);
           lv_obj_add_state(guider_ui.screen_sw_1,LV_STATE_CHECKED);
        }
    }
    lv_timer_handler(); /* let the GUI do its work */
    delay( 5 );
}

ps: 我上面这种做法很不建议,很时消耗资源,导致LVGL运行十分的卡顿,LVGL内置键盘,鼠标,编码器的接口,因此当没有触摸屏幕的时候用以上器件最为合适了。

### ESP32LVGL 9.0按键控制 对于ESP32LVGL 9.0版本而言,实现通过物理按键控制屏幕上的元素或功能是一项常见的需求。考虑到直接利用硬件资源可能导致性能下降以及用户体验不佳的情况[^2],推荐的做法是借助LVGL框架本身提供的输入设备管理机制。 #### 输入设备初始化配置 为了使能对按键的支持,在项目启动初期需完成必要的初始化工作: ```c #include "lvgl/lvgl.h" // 假设定义了三个按键分别对应上、下、确认操作 #define KEY_UP GPIO_NUM_18 #define KEY_DOWN GPIO_NUM_19 #define KEY_OK GPIO_NUM_5 static void input_dev_init(void){ static lv_indev_drv_t indev_drv; /* 初始化GPIO */ gpio_config_t io_conf = { .pin_bit_mask = (1ULL<<KEY_UP | 1ULL<<KEY_DOWN | 1ULL<<KEY_OK), .mode = GPIO_MODE_INPUT, .pull_up_en = true, // 上拉电阻启用 }; gpio_config(&io_conf); /* 设置输入设备驱动并注册到系统中 */ lv_indev_drv_init(&indev_drv); indev_drv.type = LV_INDEV_TYPE_ENCODER; // 编码器模式适合方向加选择的操作方式 indev_drv.read_cb = encoder_read_callback; // 自定义读取回调函数 lv_indev_encoder_create(&indev_drv, NULL); } ``` 上述代码片段展示了如何设置一个基于编码器类型的虚拟输入装置,并将其关联至具体的GPIO引脚。这里采用的是编码器形式而非简单的按钮点击事件处理逻辑,因为这样可以更好地模拟滚动列表项或是菜单导航等交互行为,同时也提高了程序执行效率。 #### 定义读取回调函数 接下来要编写用于检测实际按压动作发生的`encoder_read_callback()`方法: ```c bool encoder_read_callback(lv_indev_data_t *data){ int key_state = 0; data->state = LV_INDEV_STATE_REL; // 默认状态为释放 if(!gpio_get_level(KEY_UP)){ key_state |= LV_KEY_NEXT; data->state = LV_INDEV_STATE_PR; // 当前有键被按下 } else if(!gpio_get_level(KEY_DOWN)){ key_state |= LV_KEY_PREV; data->state = LV_INDEV_STATE_PR; } else if(!gpio_get_level(KEY_OK)){ key_state |= LV_KEY_ENTER; data->state = LV_INDEV_STATE_PR; } data->key = key_state ? key_state : LV_KEY_NONE; return false; // 返回false表示数据有效 } ``` 此部分实现了针对不同按键的状态监测,并将识别的结果转换成LVGL可理解的标准指令集(如前进、后退、进入)。每当发生一次有效的按键活动时就会触发该回调并将相应的命令传递给图形界面层进行后续处理。 #### 创建响应控件 最后一步是在应用程序主循环里创建一些可视化的组件以便测试效果: ```c void app_main(){ // ...省略其他初始化过程... input_dev_init(); // 调用前面编写的初始化函数 // 构建简单UI结构 lv_obj_t *scr = lv_scr_act(); lv_obj_t *btnm = lv_btnmatrix_create(scr); const char *btnm_map[] = {"Up", "\n", "Down", "OK", ""}; lv_btnmatrix_set_map(btnm, btnm_map); lv_obj_align(btnm, LV_ALIGN_CENTER, 0, 0); while(1){ lv_task_handler(); // 处理GUI任务队列中的各项事务 vTaskDelay(pdMS_TO_TICKS(5)); } } ``` 这段示例构建了一个由上下移动选项及确认按钮构成的小型矩阵式按钮组,用户可以通过外部连接的实际按键来进行互动体验。值得注意的是,整个过程中并未涉及到任何阻塞式的轮询等待语句,从而确保了系统的流畅度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

おもいね

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

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

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

打赏作者

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

抵扣说明:

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

余额充值