1. ESP開發之實體按鍵(KEYPADBUTTON)控制LVGL控件

  • 說明
  • LV_INDEV_TYPE_BUTTON的使用
  • LV_INDEV_TYPE_KEYPAD的使用

說明

本實驗使用LVGL版本為v9.2

LVGL中有四種輸入設備,如下

LV_INDEV_TYPE_POINTER, /**< Touch pad, mouse, external button*/

LV_INDEV_TYPE_KEYPAD, /**< Keypad or keyboard*/

LV_INDEV_TYPE_BUTTON, /**< External (hardware button) which is assigned to a specific point of the screen*/

LV_INDEV_TYPE_ENCODER, /**< Encoder with only Left, Right turn and a Button*/

這里只記錄LV_INDEV_TYPE_KEYPAD和LV_INDEV_TYPE_BUTTON的使用。因為這兩個輸入設備都可以用實體按鍵實現。當然,這兩個輸入設備掌握了,LV_INDEV_TYPE_ENCODER也是很容易類推的。

LV_INDEV_TYPE_BUTTON的使用

此輸入設備其實是模擬的 LV_INDEV_TYPE_POINTER設備相應坐標被按下。使用它之前,應該有明確UI的布局,特別屏幕上按鈕的坐標是明確的。

  1. 實體按鍵初始化
void key_init(void)
{// 配置 GPIOgpio_config_t io_conf = {.pin_bit_mask = (1ULL << KEY1)|(1ULL << KEY2)|(1ULL << KEY3),   // 選擇 GPIO.mode = GPIO_MODE_INPUT,              // 設置為輸出模式.pull_up_en = GPIO_PULLUP_ENABLE,     // 啟用上拉.pull_down_en = GPIO_PULLDOWN_DISABLE, // 不啟用下拉.intr_type = GPIO_INTR_DISABLE         // 不啟用中斷};gpio_config(&io_conf);
}
  1. 按鍵匹配鍵值

此鍵值將對應一個數組的序號,此數組是由BUTTON控件的坐標構成。

源碼如下:

static int read_key(void)
{if(gpio_get_level(KEY1)==0){return 0;}if(gpio_get_level(KEY2)==0){return 1;}if(gpio_get_level(KEY3)==0){return 2;}	return -1;	
}
  1. 讀取鍵值并保存到lv_indev_data_t數據結構中

目的是將實體按鍵與LVGL建立聯系,后面通過創建輸入設備相關API完成建立

void button_read(lv_indev_t * drv, lv_indev_data_t*data){static uint32_t last_btn = 0;   /*Store the last pressed button*/int btn_pr = read_key();     /*Get the ID (0,1,2...) of the pressed button*/if(btn_pr >= 0) {     /*Is there a button press? (E.g. -1 indicated no button was pressed)*/data->state = LV_INDEV_STATE_PRESSED;  /*Set the pressed state*/last_btn = btn_pr;   /*Save the ID of the pressed button*/} else {data->state = LV_INDEV_STATE_RELEASED; /*Set the released state*/}data->btn_id = last_btn;            /*Save the last button*/
}
  1. 創建輸入設備
lv_indev_t * button_indev_drv;
button_indev_drv=lv_indev_create();
lv_indev_set_type(button_indev_drv,LV_INDEV_TYPE_BUTTON);//將輸入設備設置為BUTTON模式
lv_indev_set_read_cb(button_indev_drv, button_read);//注冊回調函數,即上一步實現的函數,這樣就完成了硬件和LVGL的聯系
//配置坐標點
static const lv_point_t btn_points[5] = {{0, 0},   /*當鍵值為0時模擬點擊的坐標*/{80, 0},   /*當鍵值為1時模擬點擊的坐標*/{160, 1},   /*當鍵值為2時模擬點擊的坐標*/{320, 120},   /*當鍵值為3時模擬點擊的坐標*/{160, 240},   /*當鍵值為4時模擬點擊的坐標*/
};
lv_indev_set_button_points(button_indev_drv, btn_points);//將按鍵與坐標連接
  1. 使用LVGL的API在界面上創建三個BUTTON控件
	lv_obj_t * btn1;btn1 = lv_button_create(scr);lv_obj_set_width(btn1,80);lv_obj_set_height(btn1,35);lv_obj_set_pos(btn1,0,0);/*Button event*/lv_obj_add_event_cb(btn1, btn_event_handler, LV_EVENT_ALL, NULL);lv_obj_add_flag(btn1, LV_OBJ_FLAG_CHECKABLE);lv_obj_t * lbl1 = lv_label_create(btn1);lv_label_set_text_static(lbl1, "LEFT");lv_obj_align(lbl1, LV_ALIGN_CENTER,0, 0);lv_obj_t * btn2;btn2 = lv_button_create(scr);lv_obj_set_width(btn2,80);lv_obj_set_height(btn2,35);lv_obj_set_pos(btn2,80,0);/*Button event*/lv_obj_add_event_cb(btn2, btn_event_handler, LV_EVENT_ALL, NULL);lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);lv_obj_t * lbl2 = lv_label_create(btn2);lv_label_set_text_static(lbl2, "RIGHT");lv_obj_t * btn3;btn3 = lv_button_create(scr);lv_obj_set_width(btn3,80);lv_obj_set_height(btn3,35);lv_obj_set_pos(btn3,0,70);/*Button event*/lv_obj_add_event_cb(btn3, btn_event_handler, LV_EVENT_ALL, NULL);lv_obj_add_flag(btn3, LV_OBJ_FLAG_CHECKABLE);lv_obj_t * lbl3 = lv_label_create(btn3);lv_label_set_text_static(lbl3, "DOWN");lv_obj_align(lbl3, LV_ALIGN_CENTER,0, 0);
  1. 創建群組,并將輸入設備綁定到群組且將以上三個BUTTON加入
	lv_group_t *g = lv_group_create();lv_indev_set_group(button_indev_drv, g); //綁定定義的lv_indev_t lv_group_add_obj(g ,btn1);lv_group_add_obj(g ,btn2);lv_group_add_obj(g ,btn3);

此時按下實體按鍵將會控制對應BUTTON控件按下。

  1. 此時可以創建BUTTON回調函數了
void btn_event_handler(lv_event_t *e)//按鍵回調函數
{lv_event_code_t code = lv_event_get_code(e);if(code == LV_EVENT_CLICKED) {ESP_LOGI(TAG,"Clicked");}
}

LV_INDEV_TYPE_KEYPAD的使用

LV_INDEV_TYPE_KEYPAD的鍵值LVGL已經有實現,固定死了。

LV_KEY_NEXT 專注于下一個對象
LV_KEY_PREV 專注于上一個對象
LV_KEY_ENTER 觸發器 LV_EVENT_PRESSED/CLICKED/LONG_PRESSED 等事件
LV_KEY_UP 增加值或向上移動
LV_KEY_DOWN 減小值或向下移動
LV_KEY_RIGHT 增加值或向右移動
LV_KEY_LEFT 減小值或向左移動
LV_KEY_ESC 關閉或退出(例如,關閉下拉列表)
LV_KEY_DEL 刪除(例如,“ 文本”區域中右側的字符)
LV_KEY_BACKSPACE 刪除左側的字符(例如,在文本區域中)
LV_KEY_HOME 轉到開頭/頂部(例如,在“ 文本”區域中)
LV_KEY_END 轉到末尾(例如,在“ 文本”區域中)

LV_INDEV_TYPE_KEYPAD按鍵分兩個狀態,導航態和編輯態。導航態就是在同組中選擇相關控件,編輯態就是對控件數值上的增加/減少。LV_KEY_NEXT/PREV、LV_KEY_ENTER則是作為導航態。LV_KEY_UP/DOWN/LEFT/RIGHT則可以對控件進行數值上的編輯,一般而言LEFT/RIGHT就足夠使用了。

LV_INDEV_TYPE_KEYPAD只需要對上面的代碼做一些簡單的調整,如下:

  1. 鍵值匹配
static int read_key(void)
{if(gpio_get_level(KEY1)==0){return LV_KEY_NEXT;}if(gpio_get_level(KEY2)==0){return LV_KEY_RIGHT;}if(gpio_get_level(KEY3)==0){return LV_KEY_LEFT;}	return -1;	
}
  1. 輸入設備的回調函數
void button_read(lv_indev_t * drv, lv_indev_data_t*data){static uint32_t last_btn = 0;   /*Store the last pressed button*/int btn_pr = read_key();     /*Get the ID (0,1,2...) of the pressed button*/if(btn_pr >= 0) {     /*Is there a button press? (E.g. -1 indicated no button was pressed)*/data->state = LV_INDEV_STATE_PRESSED;  /*Set the pressed state*/last_btn = btn_pr;   /*Save the ID of the pressed button*/} else {data->state = LV_INDEV_STATE_RELEASED; /*Set the released state*/}
//注意這個地方做了修改data->key = last_btn;            /*Save the last button*/
}
  1. 創建輸入設備
lv_indev_t * button_indev_drv;
button_indev_drv=lv_indev_create();
lv_indev_set_type(button_indev_drv,LV_INDEV_TYPE_KEYPAD);//將輸入設備設置為KEYPAD模式
lv_indev_set_read_cb(button_indev_drv, button_read);//注冊回調函數,即上一步實現的函數,這樣就完成了硬件和LVGL的聯系
  1. 按鍵回調函數

既然編輯態會有值的變化,那自然會觸發相關事件,所以有了下面的改變

void btn_event_handler(lv_event_t *e)//按鍵回調函數
{lv_event_code_t code = lv_event_get_code(e);
//LV_EVENT_CLICKED這個事件在KEYPAD中只有ENTER才會觸發if(code == LV_EVENT_CLICKED) {ESP_LOGI(TAG,"Clicked");}else if(code == LV_EVENT_VALUE_CHANGED) {ESP_LOGI(TAG,"BUTTUN");}
}
  1. 只是按鍵不太能看到效果,可以創建一個slider加入組中,通過導航按鍵選中后,用LEFT/RIGHT進行編輯
	lv_obj_t *slider1;slider1=lv_slider_create(scr);lv_obj_set_pos(slider1,0,140);lv_group_add_obj(g ,slider1);

總結

經過以上編程后,其實LV_INDEV_TYPE_ENCODER也是很容易實現的,只要將左右旋轉和按下動作對應LV_KEY_LEFT/RIGHT以及LV_KEY_ENTER,剩下的代碼基本都差不多了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91122.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91122.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91122.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++:STL中list的使用和模擬實現

C中的list是標準模板庫&#xff08;STL&#xff09;提供的雙向鏈表容器&#xff0c;支持高效的元素插入和刪除操作。在上一篇中講解了vector的使用和模擬實現&#xff0c;vector是具有連續的空間&#xff0c;迭代器是可以隨機的&#xff0c;而list卻于vector不同&#xff0c;li…

【編號58-61】我國四大高原矢量示意圖shp數據

今天分享的是&#xff1a;中國四大高原&#xff0c;分別是青藏高原、內蒙古高原、黃土高原、云貴高原。青藏高原位置與范圍&#xff1a;位于中國西南部&#xff0c;包括西藏、青海的全部&#xff0c;川西高原及滇西北高原等部分地區。它的邊界&#xff0c;向東是橫斷山脈&#…

【AI落地應用實戰】利用 Amazon Bedrock Claude3 打造個性化 AI Character 應用

目錄一、引言&#xff1a;AI Character應用的市場前景與技術基礎二、技術架構設計2.1、整體方案概述2.2、核心組件介紹2.3、部署架構圖三、系統部署方案3.1、方案總述3.2、實踐流程1??. Bedrock 配置2??. 安裝 SillyTavern3??. 配置 SillyTavern 使用 Claude3 模型4??.…

Java常用日志框架介紹

Java提供了很多第三方的日志框架可供使用&#xff0c;按照現在的設計理念&#xff0c;一般把日志框架分成門面(Facade)部分和具體實現(Implementation)部分&#xff0c;門面(Facade)提供了抽象的api規范&#xff0c;實現(Implementation)負責實現api完成具體的日志記錄功能。開…

飛書 —— 多維表格 —— AI生成

1.添加關聯賬號&#xff1a; 2.獲取密鑰 ARK_API_KEY 進入火山引擎服務頁面&#xff1a;https://console.volcengine.com/ark/region:arkcn-beijing/model/detail?Iddeepseek-r1 先進入推理模型 > 快捷API接入 再去在線推理中創建推理接入點 點擊新創建好的接入點的API調…

我的世界模組開發教程——資源(1)

下面我們來研究一下ResourceLocation,每次開啟游戲時都會報這個錯誤:“ResourceLocation 中的 ResourceLocation(String) 已過時, 且標記為待刪除”,下面我們來詳細的研究一下這個類 ResourceLocation ResourceLocation 是 Minecraft 中用于唯一標識游戲資源的核心類(如方…

我從 Web2 轉型到 Web3 的 9 條經驗總結

作者&#xff1a;Forte Group 高級區塊鏈工程師 Yurii Kovalchuk原文&#xff1a;https://cryptoslate.com/why-i-left-web2-for-web3-and-why-you-might-too/三年前&#xff0c;我做出了一個徹底改變職業軌跡的決定&#xff1a;離開熟悉的 Web2&#xff0c;投身于深邃、混亂卻…

【MySQL 數據庫】MySQL索引特性(一)磁盤存儲定位扇區InnoDB頁

文章目錄沒有索引&#xff0c;可能會有什么問題二、認識磁盤2.1 MySQL與存儲2.2 磁盤&#xff1a;2.3 扇區2.4 定位扇區2.5 結論三、三者作用流程&#xff08;磁盤&#xff0c;塊&#xff0c;InnoDB頁&#xff09;四、MySQL與磁盤交互基本單位五、建立共識&#x1f6a9;總結沒有…

2419. 按位與最大的最長子數組

Problem: 2419. 按位與最大的最長子數組 文章目錄思路解題過程復雜度Code思路 按位異或只會讓數值越來越小&#xff0c;因此最長的連續按位與的最大值只存在于連續最大值中。 解題過程 遍歷數組取出最大值&#xff0c;再遍歷找到每一次連續最大值&#xff0c;從中取出最長的連續…

基于Java(SpringBoot)+Vue+MySQL 實現(Web)的網絡課程平臺

基于 SpringBoot 的網絡課程平臺1 緒論1.1 引言本科題研究并實現了一個面向網絡學習的平臺&#xff0c;為需要學習的人提供了一個學習的平臺。任何人都課在本平臺進行注冊登錄&#xff0c;學習觀看視頻。本平臺是一個關于網絡課程學習平臺&#xff0c;學員科自主選擇視頻學習&a…

Centos7 | 防火墻(firewalld)使用ipset管理ip地址的集合

文章目錄一、firewalld中ipset的用途1.1 用途1.2 注意與iptables所用的ipset命令的不同&#xff0c;1.3 配置詳解二、firewalld中ipset的操作例子2.1 新建一個set2.2 在set中添加ip2.3 從set中刪除ip2.4 刪除一個set2.5 打印一個set的文件路徑2.6 打印一個set的內容2.8 判斷一個…

Day06_C++編程

01.思維導圖02.將鳥籠放飛所有鳥類的題&#xff0c;改成觀察者模式#include <iostream> #include <cstring> #include <cstdlib> #include <unistd.h> #include <sstream> #include <vector> #include <memory>//寫一個鳥類:有一個多…

【面試場景題】隨機立減金額計算

文章目錄背景設計思路方案結論高斯分布&#xff08;正態分布&#xff09;背景 某電商公司跟某銀行有合作&#xff0c;推進銀行信用卡辦卡&流水&#xff0c;使用此銀行信用卡用戶&#xff0c;支付可以隨機立減10&#xff5e;30元。其實公司每一筆都可獲得30元支付立減金&…

2025年湖北中級注冊安全工程師報考那些事

2025年湖北中級注冊安全工程師報考那些事各位從事建筑安全的人員看過來&#xff0c;注冊安全工程師是你們行業認可度較為高的證書。關于報考無論是安全相關專業跟不相關的專業都是可以報考的。只是年份要求不同。 本科&#xff1a;相關專業3年&#xff0c;不相關專業4年。 專科…

Prometheus + Grafana + Micrometer 監控方案詳解

這套組合是當前Java生態中最流行的監控解決方案之一&#xff0c;特別適合云原生環境下的微服務應用監控。下面我將從技術實現到最佳實踐進行全面解析。 一、技術棧組成與協作 1. 組件分工組件角色關鍵能力Micrometer應用指標門面(Facade)統一指標采集API&#xff0c;對接多種監…

實習小記(個人中心的編輯模塊)

實習小記&#xff08;個人中心的編輯模塊&#xff09; 項目需要加一個個人中心的編輯模塊&#xff0c;也是差不多搞了一天下來&#xff0c;其中遇到了很多問題&#xff0c;也是來記錄、分享一下。 技術棧&#xff1a;React、antd、TypeScript 需求 點擊編輯&#xff0c;彈出編…

【7】串口編程三種模式(查詢/中斷/DMA)韋東山老師學習筆記(課程聽不懂的話試著來看看我的學習筆記吧)

<1>前置概念補充在深入拆解三種模式前&#xff0c;先通過提供的 “函數對比表” 建立整體認知&#xff1a;這張表是串口收發的「武器庫索引」&#xff0c;清晰標注了查詢、中斷、DMA 三種模式下&#xff0c;收發 / 回調函數的對應關系。后續會結合實際代碼&#xff0c;講…

【Kubernetes 指南】基礎入門——Kubernetes 201(二)

二、滾動升級- 滾動升級&#xff08;Rolling Update&#xff09;通過逐個容器替代升級的方式來實現無中斷的服務升級&#xff1a;- 在滾動升級的過程中&#xff0c;如果發現了失敗或者配置錯誤&#xff0c;還可以隨時回滾&#xff1a;- 需要注意的是&#xff0c; kubectl rolli…

網絡資源模板--基于Android Studio 實現的圖書商城App

目錄 一、測試環境說明 二、項目簡介 三、項目演示 四、部設計詳情&#xff08;部分) 登錄注冊頁 首頁 五、項目源碼 一、測試環境說明 電腦環境 Windows 11 編寫語言 JAVA 開發軟件 Android Studio (2020) 開發軟件只要大于等于測試版本即可(近幾年官網直接下載…

JavaWeb 進階:Vue.js 與 Spring Boot 全棧開發實戰(Java 開發者視角)

作為一名 Java 開發工程師&#xff0c;當你掌握了 HTML、CSS 和 JavaScript 的基礎后&#xff0c;是時候接觸現代前端框架了。Vue.js 以其簡潔的 API、漸進式的設計和優秀的中文文檔&#xff0c;成為眾多 Java 開發者入門前端框架的首選。Vue.js 讓你能快速構建響應式、組件化的…