art-pi lvgl 添加触摸事件部分代码
文档说明
该文章仅供学习参考使用,非官方使用说明文档。
littlevgl2rtt 介绍
上一篇文章(art-pi添加lvgl支持包)简单描述了如何在 art-pi 快速适配 lvgl,其实这篇文章只是笔者的学习笔记,仅供参考。为了后续开发方便,这里接着分析一下如何将触摸屏和 lvgl 结合,来实现触摸事件操作。
littlevgl2rtt 软件包是为了方便开发者快速在rt-thread 中适配 lvgl开源图形库使用的,查看这个软件包的源码,发现主要是多了两个文件,即 littlevgl2rtt.c
和 littlevgl2rtt.h
。
查看 littlevgl2rtt.h
发现,这个软件包目前对外只提供三个接口,其中 littlevgl2rtt_init
用来初始化 lvgl 使用;littlevgl2rtt_deinit
目前暂无实际用处;而 littlevgl2rtt_send_input_event
为向 lvgl 发送事件的接口,供外部事件触发调用。
rt_err_t littlevgl2rtt_init(const char *name);
void littlevgl2rtt_send_input_event(rt_int16_t x, rt_int16_t y, rt_uint8_t state);
void littlevgl2rtt_deinit(void);
有了 littlevgl2rtt_send_input_event
,这个接口,我们就可以将触摸屏的触摸事件和 lvgl 关联起来了。
工程修改
在上面文章中,已经可以通过添加 gt9147_sample.c
这个示例文件来获取到触摸屏的坐标信息了,通过初始化时候的打印信息发现,这个触摸屏的坐标范围为(0,0)~(480,480),支持5点触控。
\ | /
- RT - Thread Operating System
/ | \ 4.0.3 build Nov 25 2020
2006 - 2020 Copyright by rt-thread team
[I/touch] rt_touch init success
[I/gt9147] touch device gt9147 init success
[D/drv.lcd] LTDC init success
id = 9 1 4 7
range_x = 480
range_y = 480
point_num = 5
通过触摸屏幕操作,还可以获取到触摸的x轴和y轴坐标信息,触摸时长和触摸的宽度等参数信息。
这里就简单接着上次的工程,在 gt9147_sample.c
加入 littlevgl2rtt_send_input_event
,用来向 lvgl 传递事件。
修改 gt9147_entry
函数,修改后的函数实现如下。
// 在 gt9147_sample.c 文件头部加入头文件
#include "littlevgl2rtt.h"
#define TOUCH_LCD_WIDTH 800
#define TOUCH_LCD_HEIGHT 480
#define TOUCH_RANGE_X 480.0
static void gt9147_entry(void *parameter)
{
uint16_t x;
uint16_t y;
rt_device_control(dev, RT_TOUCH_CTRL_GET_INFO, &info);
read_data = (struct rt_touch_data *)rt_malloc(sizeof(struct rt_touch_data) * info.point_num);
while (1)
{
rt_sem_take(gt9147_sem, RT_WAITING_FOREVER);
if (rt_device_read(dev, 0, read_data, info.point_num) == info.point_num)
{
for (rt_uint8_t i = 0; i < info.point_num; i++)
{
//坐标转换
x= TOUCH_LCD_WIDTH-(uint16_t)(read_data[i].x_coordinate*TOUCH_LCD_WIDTH/TOUCH_RANGE_X);
y= TOUCH_LCD_HEIGHT-read_data[i].y_coordinate;
littlevgl2rtt_send_input_event(x,y,read_data[i].event);
if (read_data[i].event == RT_TOUCH_EVENT_DOWN || read_data[i].event == RT_TOUCH_EVENT_MOVE)
{
// rt_kprintf("%d %d %d %d %d\n", read_data[i].track_id,
// read_data[i].x_coordinate,
// read_data[i].y_coordinate,
// read_data[i].timestamp,
// read_data[i].width);
rt_kprintf("(%d,%d)\n",x,y);
}
}
}
rt_device_control(dev, RT_TOUCH_CTRL_ENABLE_INT, RT_NULL);
}
}
编译下载
修改完成后,重新编译工程,并下载到 ART-PI中,测试,通过触摸屏幕,发现串口已经可以打印正确的坐标信息,lvgl 也可以正常响应触摸操作了 。
\ | /
- RT - Thread Operating System
/ | \ 4.0.3 build Nov 25 2020
2006 - 2020 Copyright by rt-thread team
[I/touch] rt_touch init success
[I/gt9147] touch device gt9147 init success
[D/drv.lcd] LTDC init success
id = 9 1 4 7
range_x = 480
range_y = 480
point_num = 5
[littlevgl2rtt] Welcome to the littlevgl2rtt.
[littlevgl2rtt] You can find latest ver from https://github.com/liu2guang/LittlevGL2RTT.
msh />
msh />
msh />
msh />
msh />
msh />(165,368)
(165,368)
(165,368)
(165,368)
(182,363)
测试效果
经过几次简单的测试,这种方式已经可以正常的实现触摸控制lvgl了,但是如果就到此为止了,这代码还是有bug的,经过笔者的测试,发现过了几分钟之后再次触摸,就没有反应了,通过串口查看后台的线程状态,touch的线程被挂起了,再也恢复不回来了。暂时还不知道什么原因,留作后续解决吧。
msh />list_thread
thread pri status sp stack size max used left tick error
-------- --- ------- ---------- ---------- ------ ---------- ---
lv-task 5 suspend 0x000000b4 0x00002800 21% 0x00000006 000
touch 25 suspend 0x00000090 0x00000400 63% 0x0000000a 000
tshell 20 running 0x00000268 0x00001000 15% 0x0000000a 000
tidle0 31 ready 0x00000060 0x00000100 71% 0x0000001b 000
timer 4 suspend 0x0000007c 0x00000200 24% 0x00000008 000
main 10 suspend 0x00000148 0x00000800 36% 0x0000000a 000