当前位置:网站首页>ESP32 LVGL8. 1 - input devices (input devices 18)
ESP32 LVGL8. 1 - input devices (input devices 18)
2022-04-23 18:37:00 【Please call me Xiao Peng】
Tips : This blog serves as a learning note , If there are mistakes, I hope to correct them
List of articles
One 、Input devices brief introduction
1.1 summary Overview
Input devices usually mean :
• Pointer input devices like touchpad or mouse
• The keypad is like an ordinary keyboard or a simple numeric keypad
• Encoder and left / Turn right and choose
• External hardware button , Assigned to a specific point on the screen
Before further reading , Please read the input of the portable device (/ transplant /indev) part ,
1.2 The pointer Pointers
The pointer input device can have a cursor .( Usually mouse )
lv_indev_t * mouse_indev = lv_indev_drv_register(&indev_drv);
LV_IMG_DECLARE(mouse_cursor_icon); /*Declare the image file.*/
lv_obj_t * cursor_obj = lv_img_create(lv_scr_act(), NULL); /*Create an image object␣ /*for the cursor */
lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/
lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image ␣ ,→object to the driver*/
Be careful , Cursor object should have lv_obj_set_click(cursor_obj, false). For the image , Clicking is disabled by default .
1.3 Keys and encoders Keypad and encoder
You can fully control the user interface without a touch pad or mouse using a keypad or encoder (s). It works like PC Upper TAB Key to select elements in an application or web page .
1.3.1 Group Groups
You need to add objects that you want to control with a keyboard or encoder to the group . In each group , There is a focused object that receives the action of the pressed key or encoder . for example , If a text area is centralized , You press a letter on the keyboard , The key will be sent and inserted into the text area . Similarly , If a slider is focused , And you press the left or right arrow , The value of the slider will change . You need to associate the input device with the Group . An input device can only send keys to one group , however , A group can also receive data from multiple input devices . To create a group , Please use lv_group_t * g = lv_group_create(); To add an object to a group , Please use lv_group_add_obj(g, obj). Use lv_indev_set_group(indev, g) Associate a group with an input device , among indev yes lv_indev_drv_register() The return value of .
1.3.1.1 Key Keys
There are some predefined keys that have special meanings :
• LV_KEY_NEXT Next object
• LV_KEY_PREV Focus on the previous object
• LV_KEY_ENTER Trigger LV_EVENT_PRESSED/CLICKED/LONG_PRESSED Other events
• LV_KEY_UP Add value or move up
• LV_KEY_DOWN Reduce value or move down
• LV_KEY_RIGHT Add value or move right
• LV_KEY_LEFT Decrease the value or move to the left
• LV_KEY_ESC Close or exit ( For example, close the drop-down list )
• LV_KEY_DEL Delete ( For example, a character to the right of the text area )
• LV_KEY_BACKSPACE Delete the character on the left ( For example, in the text area )
• LV_KEY_HOME Go to the beginning / Top ( For example, in the text area )
• LV_KEY_END Go to last ( For example, in the text area ))
The most important special key is LV_KEY_NEXT/PREV、LV_KEY_ENTER and LV_KEY_UP/DOWN/LEFT/RIGHT. stay
read_cb Function , You should convert some keys to these special keys , To navigate through the group and interact with the selected objects . Use only LV_KEY_LEFT/RIGHT That's enough , Because most objects can use them to fully control . For encoders , You should only use LV_KEY_LEFT、LV_KEY_RIGHT and LV_KEY_ENTER.
1.3.1.2 Edit and navigation mode Edit and navigate mode
Because the keypad has many keys , So it's easy to navigate between objects and edit them with the keypad . however , Encoder “ secret key ” Limited number , So it's hard to navigate with the default options . Navigation and editing are created to avoid this problem with the encoder .
In navigation mode , Encoder LV_KEY_LEFT/RIGHT Converted to LV_KEY_NEXT/PREV. therefore , The next or previous object is selected by the rotary encoder . Press LV_KEY_ENTER Switch to edit mode .
In edit mode , Usually use LV_KEY_NEXT/PREV To edit objects . According to the type of object , Short press or long press LV_KEY_ENTER Change back to navigation mode . Usually , An object cannot be pressed ( Such as slider ) Leave edit mode after a short click . But for those short clicks that make sense ( Button like ), It takes a long time to press .
This function is usually used to switch between navigation mode and editing mode lv_group_set_editing(group,false);
1.3.2 style Styling
If an object clicks focus through the touch pad , Or focus through encoder or keyboard , It will go to LV_STATE_FOCUSED. therefore , The emphasis style will be applied to it .
If the object enters edit mode , It will enter LV_STATE_FOCUSED | LV_STATE_EDITED state , Therefore, these style attributes will be displayed .
For a more detailed description , Please read the style section .
Two 、 Input device interface Input device interface
2.1 Enter device type Types of input devices
notes : Most of the content in the article comes from lv_port_indev_template.c Modified from the template .
To register an input device , Must be initialized lv_indev_drv_t Variable :: To initialize KeyPad As an example
2.1.1 Touch Pad , Mouse or any pointer Touchpad, mouse or any pointer
static lv_indev_drv_t indev_drv;
/*Initialize your keypad or keyboard if you have*/
keypad_init(); // Initialize hardware
/*Register a keypad input device*/
lv_indev_drv_init(&indev_drv); // Initialize registration
indev_drv.type = LV_INDEV_TYPE_KEYPAD; // Initialize the registration type
indev_drv.read_cb = keypad_read; // Initialize read callback
indev_keypad_or_encoder = lv_indev_drv_register(&indev_drv); // Initialize callback implementation
indev_drv.type It can be one of the following situations .
• LV_INDEV_TYPE_POINTER Touch pad or mouse
• LV_INDEV_TYPE_KEYPAD keyboard
• LV_INDEV_TYPE_ENCODER Encoder and left / Turn right and choose
• LV_INDEV_TYPE_BUTTON The external keys are almost pressing the screen
read_cb Is a function pointer , It will be called periodically to report the current status of the input device .
Input devices that can click on screen points fall into this category .
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_input_read;
void my_input_read(lv_indev_drv_t * drv, lv_indev_data_t*data)
{
if(touchpad_pressed) {
data->point.x = touchpad_x;
data->point.y = touchpad_y;
data->state = LV_INDEV_STATE_PRESSED;
} else {
data->state = LV_INDEV_STATE_RELEASED;
}
}
To set the mouse cursor , Please use lv_indev_set_cursor(my_indev, &img_cursor).(my_indev yes lv_indev_drv_register The return value of )
2.1.1 Keyboard or keyboard Keypad or keyboard
A full keyboard with all letters or a simple keyboard with several navigation buttons belong here .
Using the keyboard / Keypad :
• use LV_INDEV_TYPE_KEYPAD Type register a read_cb function .
• You must create an object group :lv_group_t * g = lv_group_create(), And must use lv_group_add_obj(g, obj) Add objects to it
• The created group must be assigned to the input device :lv_indev_set_group(my_indev, g) (my_indev yes lv_indev_drv_register The return value of )
• Use LV_KEY_…… Navigate between objects in a group . About the available keys , see also lv_core/lv_group.h.
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
indev_drv.read_cb = keyboard_read;
void keyboard_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
data->key = last_key(); /*Get the last pressed or released key*/
if(key_pressed()) data->state = LV_INDEV_STATE_PRESSED;
else data->state = LV_INDEV_STATE_RELEASED;
}
2.1.1 Encoder Encoder
Using the encoder, you can do 4 thing :
1. Press the button
2. Press and hold the button
3. turn left
4. turn right
In short ,Encoder The input device works like this :
• By rotating the encoder , You can focus on the next / The last object .
• When you're in a simple object ( Button like ) When the encoder is pressed up , It will be clicked ..
• If you're in a complex object ( As listing , Message box, etc ) Press the encoder up , The object will enter edit mode , In this way , You can navigate inside objects .
• To leave edit mode , Please press and hold the button .
Use the encoder ( Similar to a keypad ), Objects should be added to the group .
indev_drv.type = LV_INDEV_TYPE_ENCODER;
indev_drv.read_cb = encoder_read;
void encoder_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
data->enc_diff = enc_get_new_moves();if(enc_pressed()) data->state = LV_INDEV_STATE_PRESSED;
else data->state = LV_INDEV_STATE_RELEASED;
}
Use buttons and encoder logic Using buttons with Encoder logic In addition to standard encoder behavior , You can also use its logic to navigate ( The focus of ) And using buttons to edit widgets . If you only have a few buttons available , Or you want to use buttons other than the encoder wheel , This is particularly convenient .
You need 3 Button :
• LV_KEY_ENTER Simulate pressing or pressing the encoder button
• LV_KEY_LEFT Analog encoder moves to the left
• LV_KEY_RIGHT Analog encoder moves to the right
• Other keys will be passed to the focused widget
If you press and hold these keys , It will simulate the encoder click and specify the period as indev_drv.long_press_rep_time.
2.1.1 Button Button
A button is an external button next to the screen “ Hardware ” Button , They are assigned to specific coordinates of the screen . If a button is pressed , It will simulate pressing on the specified coordinates .( Similar to touch pad ) Assign buttons to coordinates and use lv_indev_set_button_points(my_indev,points_array).points_array It should be like this const lv_point_t points_array[] = { {12,30},{60,90}, …}
indev_drv.type = LV_INDEV_TYPE_BUTTON;
indev_drv.read_cb = button_read;
void button_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
static uint32_t last_btn = 0; /*Store the last pressed button*/
int btn_pr = my_btn_read(); /*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)*/
last_btn = btn_pr; /*Save the ID of the pressed button*/
data->state = LV_INDEV_STATE_PRESSED; /*Set the pressed state*/
} else {
data->state = LV_INDEV_STATE_RELEASED; /*Set the released state*/
}
data->btn = last_btn; /*Save the last button*/
}
2.2 Other features Other features
2.2.1 Parameters Parameters
The default values of the following parameters can be in lv_indev_drv_t:
• scroll_limit The number of pixels to slide before actually scrolling the object .
• scroll_throw Roll throw ( momentum ) Slow down at [%]. The bigger the value is. , The faster you slow down .
• long_press_time Press send LV_EVENT_LONG_PRESSED Time for ( millisecond )
• long_press_rep_timeLV_EVENT_LONG_PRESSED_REPEAT Send interval ( millisecond )
• read_timer Point to lv_rimer The pointer to , Used to read input devices . Its parameters can be through lv_timer_…() Function to change .
lv_conf.h Medium LV_INDEV_DEF_READ_PERIOD Set the default read cycle .
2.2.1 feedback Feedback
except read_cb, You can also do it in lv_indev_drv_t It is specified in feedback_cb Callback . When the input device sends any type of event , call Feedback_cb.( It's not about type ). It allows users to provide feedback , For example, in LV_EVENT_CLICKED Play sound on .
2.2.1 Associated with the display Associating with a display
Each input device is associated with a display . By default , The new input device is added to the last created or explicitly selected ( Use lv_disp_set_default()) Showing . Related display storage , And can be in the drive disp Field change .
2.2.1 Buffer reading Buffered reading
By default ,LVGL Will call... On a regular basis read_cb. Because of this intermittent polling , It is possible that some user gestures are missed .
To solve this problem , You can write an event driven driver for your input device to buffer the measurement data . stay read_cb in , You can set buffered data , Instead of reading the input device . You can set data-> continue_reading Sign to tell LVGL There's more data to read , It should call again read_cb.
2.1 API
About grouping API As shown below
lv_group_t * lv_group_create(void) // Create a new object group
void lv_group_del(lv_group_t * group) // Delete group object
void lv_group_set_default(lv_group_t * group) // Set the default group . If used in a class ' add_to_def_group = true ' Enable this group , The new object will be added to the group .
lv_group_t * lv_group_get_default(void) // Get default group
void lv_group_add_obj(lv_group_t * group, struct _lv_obj_t * obj) // Add an object to the group
void lv_group_remove_obj(struct _lv_obj_t * obj) // Remove an object from the group
void lv_group_remove_all_objs(lv_group_t * group) // Remove all objects in the group
void lv_group_focus_obj(struct _lv_obj_t * obj) // Focus on an object ( Defocus current )
void lv_group_focus_next(lv_group_t * group) // Focus on the next object in the group ( Defocus the current object )
void lv_group_focus_prev(lv_group_t * group) // Focus on the previous object in a group ( Defocus the current object )
void lv_group_focus_freeze(lv_group_t * group, bool en) // Don't change the focus of the current object
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c) // Send a control character to the focus object of the group
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb) // Set a function for a group , When a new object is focused , The function will be called
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy) // Set whether the next or previous item in the group is the focus , If the current focus object is deleted .
struct _lv_obj_t * lv_group_get_focused(const lv_group_t * group) // Get focus object , If not, get NULL
lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group) // Get the focus callback function of a group
void lv_group_set_editing(lv_group_t * group, bool edit) // Manually set the current mode ( Edit or navigate ).
bool lv_group_get_editing(const lv_group_t * group) // Get the current mode ( Edit or navigate ).
void lv_group_set_wrap(lv_group_t * group, bool en) // set focus next/prev Is it allowed to go from first->last or last->first Objects are packaged .
bool lv_group_get_wrap(lv_group_t * group) // Get focus next/prev Is it allowed to go from first->last or last->first Objects are packaged .
uint32_t lv_group_get_obj_count(lv_group_t * group) // Get the number of objects in the group
About input devices API As shown below
void lv_indev_read_timer_cb(lv_timer_t * timer) // Call periodically to read the input device
void lv_indev_enable(lv_indev_t * indev, bool en) // Input device enable
lv_indev_t * lv_indev_get_act(void) // Get the input device currently processed . Can also be used in functions .
lv_indev_type_t lv_indev_get_type(const lv_indev_t * indev) // Get the type of an input device
void lv_indev_reset(lv_indev_t * indev, lv_obj_t * obj) // Reset one or all input devices
void lv_indev_reset_long_press(lv_indev_t * indev) // Reset the long press state of the input device
void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj) // Input device for pointer (LV_INPUT_TYPE_POINTER and LV_INPUT_TYPE_BUTTON) Set cursor
void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group) // Set the target group for the keyboard input device ( by LV_INDEV_TYPE_KEYPAD)
void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t points[]) // by LV_INDEV_TYPE_BUTTON Set an array of points .
void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point)// Get the last point of an input device ( about LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
lv_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev) // Get the current gesture directly
uint32_t lv_indev_get_key(const lv_indev_t * indev) // Get the last key pressed by an input device (LV_INDEV_TYPE_KEYPAD)
lv_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev) // Check the scrolling direction of the current input device ( about LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
lv_obj_t * lv_indev_get_scroll_obj(const lv_indev_t * indev) // Gets the currently scrolling object (LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point)// Get the motion vector of an input device ( about LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
void lv_indev_wait_release(lv_indev_t * indev) // The next s Don't do anything before release
lv_obj_t * lv_indev_get_obj_act(void) // Gets a pointer to the currently active object in the currently processed input device .
lv_timer_t * lv_indev_get_read_timer(lv_disp_t * indev) // Get one indev Read the pointer of the timer and modify its parameters ' lv_timer_… The function of .
lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point) // Search the top , Clickable object points
void lv_indev_drv_init(struct _lv_indev_drv_t * driver) // Initialize an input device driver with default values . It is used to determine the known value in the field , Not memory garbage . After it, you can set the field .
lv_indev_t * lv_indev_drv_register(struct _lv_indev_drv_t * driver) // Register an initialized input device driver .
void lv_indev_drv_update(lv_indev_t * indev, struct _lv_indev_drv_t * new_drv)// Update the driver at run time .
lv_indev_t * lv_indev_get_next(lv_indev_t * indev) // Get the next input device .
void _lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data) // Read data from input device .
3、 ... and 、 Example
If you need to use an external input device, you need to initialize the external device , I'm here for external devices keypad And use encoder Modify the use of encoder mode , I don't use a real encoder here , Instead, the gyroscope is used as the input control , Take the pitch angle and roll angle of the gyroscope as the input variation parameters ( Key ), The rolling angle realizes the left and right rotation of the encoder , The pitch angle realizes the pressing and releasing of the encoder .
initialization lv_port_indev_Key.c file
#include "lv_port_indev_Key.h"
static const char *TAG = "lv_port_indev";
static void keypad_init(void);
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static uint32_t keypad_get_key(void);
static void encoder_init(void);
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static void encoder_handler(void);
lv_indev_t * indev_keypad_or_encoder;
static int32_t encoder_diff;
static lv_indev_state_t encoder_state;
void keypad_lv_port_indev_init(void)
{
static lv_indev_drv_t indev_drv;
/*Initialize your keypad or keyboard if you have*/
keypad_init(); // Initialize hardware
/*Register a keypad input device*/
lv_indev_drv_init(&indev_drv); // Initialize registration
indev_drv.type = LV_INDEV_TYPE_KEYPAD; // Initialize the registration type
indev_drv.read_cb = keypad_read; // Initialize read callback
indev_keypad_or_encoder = lv_indev_drv_register(&indev_drv); // Initialize callback implementation
}
/*------------------ * Keypad * -----------------*/
/*Initialize your keypad*/
static void keypad_init(void)
{
/*Your code comes here*/
key_init();
}
/*Will be called by the library to read the mouse*/
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
static uint32_t last_key = 0;
/*Get whether the a key is pressed and save the pressed key*/
uint32_t act_key = keypad_get_key();
if(act_key != 0) {
data->state = LV_INDEV_STATE_PR;
/*Translate the keys to LVGL control characters according to your key definitions*/
switch(act_key) {
case 1:
act_key = LV_KEY_NEXT;
break;
case 2:
act_key = LV_KEY_PREV;
break;
case 3:
act_key = LV_KEY_LEFT;
break;
case 4:
act_key = LV_KEY_RIGHT;
break;
case 5:
act_key = LV_KEY_ENTER;
break;
}
last_key = act_key;
} else {
data->state = LV_INDEV_STATE_REL;
}
data->key = last_key;
}
/*Get the currently being pressed key. 0 if no key is pressed*/
static uint32_t keypad_get_key(void)
{
uint8_t key_value = 0; // Press the key to return the value
#if UserGyroscope
short aacx = 0, aacy = 0, aacz = 0; // Original number of acceleration sensors
float pitch, roll;
Get_Accelerometer(&aacx, &aacy, &aacz); // get data
LIS3DH_get_angleXY(aacx,aacy,aacz,&pitch,&roll);// Deal with Euler angle
// ESP_LOGI(TAG,"angle: x=%.3f, y=%.3f,\r\n",pitch,roll);
if (pitch > 66){
key_value = LV_KEY_ENTER;
// ESP_LOGI(TAG,"LV_KEY_ENTER\r\n");
}
else if(pitch < -66){
key_value = LV_KEY_NEXT;
// ESP_LOGI(TAG,"LV_KEY_NEXT\r\n");
}
else if(roll > 66){
key_value = LV_KEY_LEFT;
// ESP_LOGI(TAG,"LV_KEY_LEFT\r\n");
}
else if(roll < -66){
key_value = LV_KEY_RIGHT;
// ESP_LOGI(TAG,"LV_KEY_RIGHT\r\n");
}
#else
// Key trigger The way
if(gpio_get_level(KEY_LEFT)==1)
key_value = LV_KEY_LEFT;
else if(gpio_get_level(KEY_CENTER)==1)
key_value = LV_KEY_ENTER;
else if(gpio_get_level(KEY_RIGHT)==1)
key_value = LV_KEY_RIGHT;
else if(gpio_get_level(KEY_RIGHT_ADD)==1)
key_value = LV_KEY_NEXT;
#endif
return key_value;
}
void encoder_lv_port_indev_init(void)
{
static lv_indev_drv_t indev_drv;
/*Initialize your encoder if you have*/
encoder_init();
/*Register a encoder input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_ENCODER;
indev_drv.read_cb = encoder_read;
indev_keypad_or_encoder = lv_indev_drv_register(&indev_drv);
}
/*------------------ * Encoder * -----------------*/
/*Initialize your keypad*/
static void encoder_init(void)
{
/*Your code comes here*/
key_init();
}
/*Will be called by the library to read the encoder*/
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
encoder_handler(); // State detection
data->enc_diff = encoder_diff; // Get key value
data->state = encoder_state; // Get the key status value
encoder_diff = 0; // Increment setting bit 0
}
/*Call this function in an interrupt to process encoder events (turn, press)*/
static void encoder_handler(void)
{
#if UserGyroscope
/*Your code comes here*/
short aacx = 0, aacy = 0, aacz = 0; // Original number of acceleration sensors
float pitch, roll;
Get_Accelerometer(&aacx, &aacy, &aacz); // get data
LIS3DH_get_angleXY(aacx,aacy,aacz,&pitch,&roll);// Deal with Euler angle
// ESP_LOGI(TAG,"angle: x=%.3f, y=%.3f,\r\n",pitch,roll);
if (pitch > 66){
encoder_state = LV_INDEV_STATE_PR; // Press state
// ESP_LOGI(TAG,"LV_INDEV_STATE_PR\r\n");
}
else {
encoder_state = LV_INDEV_STATE_REL; // Release status
// ESP_LOGI(TAG,"LV_INDEV_STATE_REL\r\n");
}
if(roll > 66 && pre_flag){
encoder_diff ++; // Increase the direction of rotation
pre_flag = 0;
// ESP_LOGI(TAG,"encoder_diff ++\r\n");
vTaskDelay(10 / portTICK_PERIOD_MS); // Delay chattering
}
else if(roll < -66 && pre_flag){
// Reduce the direction of rotation
encoder_diff --;
pre_flag = 0;
// ESP_LOGI(TAG,"encoder_diff --\r\n");
vTaskDelay(10 / portTICK_PERIOD_MS); // Delay chattering
}else{
pre_flag = 1; // Press the flag bit
}
#else
// Key trigger The way
if(gpio_get_level(KEY_LEFT)==1){
encoder_diff ++; // Increase the direction of rotation
pre_flag = 0;
}else if(gpio_get_level(KEY_RIGHT)==1){
encoder_diff ++; // Increase the direction of rotation
pre_flag = 0;
}
if(gpio_get_level(KEY_CENTER)==1){
encoder_state = LV_INDEV_STATE_PR; // Press state
}
else{
encoder_state = LV_INDEV_STATE_REL; // Release status
}
#endif
}
void my_lv_port_indev_init(void)
{
#if Encoder
encoder_lv_port_indev_init(); // Initialize encoder
ESP_LOGI(TAG,"init_encoder_indev\r\n");
#else
keypad_lv_port_indev_init(); // Initialization key kaypad
ESP_LOGI(TAG,"init_keypad_indev\r\n");
#endif
}
initialization lv_port_indev_Key.h file
#ifndef LV_PORT_INDEV_Key_H
#define LV_PORT_INDEV_Key_H
#include "../components/lvgl/lvgl.h"
#include "my_key.h"
#include "lis3dh.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include <stdio.h>
#include "esp_log.h"
#define Encoder 1 // Define whether to use encoder mode or Keypad Pattern
#define UserGyroscope 0 // Define whether to use gyroscope mode or ordinary key input mode
int pre_flag; // Press the flag bit
extern lv_indev_t * indev_keypad_or_encoder;
void my_lv_port_indev_init(void);
#endif /*LV_PORT_INDEV_TEMPL_H*/
The test program
/************************************************* * The name of the function : key_pad_event_cb * ginseng Count : lv_event_t * e Callback events * The functionality : The event callback displays *************************************************/
static void key_pad_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e); // Get event code
lv_obj_t * target = lv_event_get_target(e); // Get the object to which the event is sent
lv_obj_t * cur_target = lv_event_get_current_target(e); // Get the object to which the event was originally sent ( Same as when event bubbling is enabled lv_event_get_target Different )
lv_obj_t * label = lv_event_get_user_data(e); // Get as lv_obj_add_event_cb The pointer passed by the last parameter of
lv_obj_t * btn = lv_event_get_param(e); // Get as lv_event_send The last parameter of the passed parameter
if(code==LV_EVENT_KEY){
uint32_t key=lv_event_get_key(e); // Get key events
if(key == LV_KEY_ENTER){
printf("\r\n *ENTER_key=%d,code=%d",key,(uint32_t)code);
}else if(key == LV_KEY_NEXT){
printf("\r\n *NEXT_key=%d,code=%d",key,(uint32_t)code);
}else if(key == LV_KEY_LEFT){
printf("\r\n *LEFT_key=%d,code=%d",key,(uint32_t)code);
}else if(key == LV_KEY_RIGHT){
printf("\r\n *RIGHT_key=%d,code=%d",key,(uint32_t)code);
}
}
}
/************************************************* * The name of the function : Key_pad_test * ginseng Count : nothing * The functionality : Event input test *************************************************/
void Key_pad_test()
{
lv_group_t * group = lv_group_create(); // Create grouped variables
lv_indev_set_group(indev_keypad_or_encoder,group); // Set the target group for the keyboard input device
static lv_style_t style; // Create styles
lv_style_init(&style); // Initialize style
lv_style_set_radius(&style,3); // Setting fillet
lv_style_set_bg_color(&style,lv_palette_main(LV_PALETTE_RED)); // Set the background color
lv_style_set_bg_opa(&style,LV_OPA_COVER); // Set background transparency
lv_style_set_border_color(&style,lv_palette_darken(LV_PALETTE_RED,2));// Set widening
lv_style_set_border_opa(&style,LV_OPA_80); // Set the widening transparency
lv_obj_t * btn1 = lv_btn_create(lv_scr_act()); // establish btn object
// lv_obj_add_flag(btn1,LV_OBJ_FLAG_HIDDEN); // Add flag bit
lv_obj_add_style(btn1,&style,LV_STATE_PRESSED); // Add style to key object
lv_obj_add_event_cb(btn1,key_pad_event_cb,LV_EVENT_KEY,NULL); // Add key callback function
lv_obj_align(btn1,LV_ALIGN_CENTER,-40,0); // centered
lv_obj_t * label1 = lv_label_create(btn1); // establish label
lv_label_set_text(label1,"Btn1"); // Show label Word content
lv_obj_t * btn2 = lv_btn_create(lv_scr_act()); // establish btn object
// lv_obj_add_flag(btn2,LV_OBJ_FLAG_CHECKABLE); // Add flag bit
lv_obj_add_style(btn2,&style,LV_STATE_PRESSED); // Add style to key object
lv_obj_add_event_cb(btn2,key_pad_event_cb,LV_EVENT_KEY,NULL); // Add key callback function
lv_obj_align(btn2,LV_ALIGN_CENTER,40,0); // centered
lv_obj_t * label2 = lv_label_create(btn2); // establish label
lv_label_set_text(label2,"Btn2"); // Show label Word content
lv_group_add_obj(group,btn1); // add group
lv_group_add_obj(group,btn2); // add group
}
It is worth noting that external drivers need to be initialized when using , The initialization position needs to be placed after the initialization of the screen .

The test shows the video :LVGL8 External input key input
版权声明
本文为[Please call me Xiao Peng]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210609450406.html
边栏推荐
- After CANopen starts PDO timing transmission, the heartbeat frame time is wrong, PDO is delayed, and CANopen time axis is disordered
- CISSP certified daily knowledge points (April 13, 2022)
- Test questions of daily safety network (February 2024)
- Mysql database backup command -- mysqldump
- ctfshow-web361(SSTI)
- K210 serial communication
- Robocode tutorial 7 - Radar locking
- 数据库上机实验四(数据完整性与存储过程)
- Daily CISSP certification common mistakes (April 18, 2022)
- Analysez l'objet promise avec le noyau dur (Connaissez - vous les sept API communes obligatoires et les sept questions clés?)
猜你喜欢

kettle庖丁解牛第17篇之文本文件输出

Matlab tips (6) comparison of seven filtering methods

logstash 7. There is a time problem in X. the difference between @ timestamp and local time is 8 hours
![[mathematical modeling] - analytic hierarchy process (AHP)](/img/ff/2350c9604a03fff6a6a751aa3cfa3b.png)
[mathematical modeling] - analytic hierarchy process (AHP)

iptables初探

玻璃体中的硫酸软骨素

【ACM】455. Distribute Biscuits (1. Give priority to big biscuits to big appetite; 2. Traverse two arrays with only one for loop (use subscript index -- to traverse another array))

QT reading and writing XML files (including source code + comments)

ctfshow-web361(SSTI)

Stm32mp157 wm8960 audio driver debugging notes
随机推荐
Halo 开源项目学习(七):缓存机制
Test questions of daily safety network (February 2024)
Multifunctional toolbox wechat applet source code
kettle庖丁解牛第17篇之文本文件输出
Install the yapiupload plug-in in idea and upload the API interface to the Yapi document
Log4j2 cross thread print traceid
Configure iptables
ctfshow-web361(SSTI)
Daily CISSP certification common mistakes (April 19, 2022)
CISSP certified daily knowledge points (April 12, 2022)
14个py小游戏源代码分享第二弹
Can filter
ESP32 LVGL8. 1 - BTN button (BTN 15)
How to restore MySQL database after win10 system is reinstalled (mysql-8.0.26-winx64. Zip)
CISSP certified daily knowledge points (April 18, 2022)
机器学习理论基础篇--关于机器学习的一些术语
Test post and login function
CISSP certified daily knowledge points (April 14, 2022)
QT error: no matching member function for call to ‘connect‘
硬核解析Promise對象(這七個必會的常用API和七個關鍵問題你都了解嗎?)