当前位置: 首页 > news >正文

玩转树莓派屏幕之四:适配tslib增加触屏准确度

转载请标明出处,否则禁止转载。 标题:<玩转树莓派屏幕之四:适配tslib增加触屏准确度> / 作者:longtao 原始文章链接:http://liulongtao.com/index.php/树莓派/113/


由于使用从/dev/input/event0中直接读取数据,在屏幕上显示不准确。并且树莓派的MHS35是旋转90°的,所以导致树莓派的屏幕滑动和实际滑动不符,并且通过更改代码实现一致,也存在点击位置和屏幕显示位置存在偏差的问题。tslib中对从/dev/input/event0数据进行了过滤和矫正,准确性有了大幅度的提升。

一、主要思路

  1. 安装tslib仓库
  2. 实现从tslib中读取的方法,注册到lvgl中
  3. 添加tslib到cmake中
  4. 添加tslib的全局变量到.bashrc或者/etc/profile中

二、环境配置:

2.1 安装libts-dev开发环境

sudo apt install libts-dev

然后将树莓派的/usr /lib目录复制到WSL环境上,选择指定位置,我这里选择/home/longtao/raspberry/sysroot,用于交叉编译。

检查是否存在

ls /home/longtao/raspberry/sysroot/usr/include/tslib.h
ls /home/longtao/raspberry/sysroot/usr/lib/aarch64-linux-gnu/libts.*
ll /home/longtao/raspberry/sysroot/lib/aarch64-linux-gnu/pkgconfig

2.2 设置交叉编译选项:

设置toolchain.cmake

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)set(CMAKE_SYSROOT /home/longtao/raspberry/sysroot)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)# 确保 pkg-config 使用 sysroot
set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig)
  • PKG_CONFIG_LIBDIR: 设置让cmake识别tslib的pkg文件,引入tslib.pc引用。

2.3 设置cmake配置文件

# 查找 tslib
find_package(PkgConfig REQUIRED)
pkg_check_modules(TSLIB REQUIRED IMPORTED_TARGET GLOBAL tslib)message(STATUS "TSLIB include dirs: ${TSLIB_INCLUDE_DIRS}")
message(STATUS "TSLIB include dirs: ${TSLIB_LIBRARY_DIRS}")# 包含 tslib 头文件(自动从 pkg-config 获取)
include_directories(${TSLIB_INCLUDE_DIRS})
link_directories(${TSLIB_LIBRARY_DIRS})add_executable(lvglsim src/main.c ${LV_LINUX_SRC} ${LV_LINUX_BACKEND_SRC})
target_include_directories(lvglsim PRIVATE ${TSLIB_INCLUDE_DIRS})
target_link_libraries(lvglsim lvgl_linux lvgl PkgConfig::TSLIB dl pthread)
  • 上面已经把tslib.pc路径让cmake进行识别
  • include_directories 和 link_directories 是自动从 pkg-config中获取的
  • target_include_directories:目标文件使用TSLIB的路径
  • target_link_libraries:执行最后的链接

三、代码实现:

代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>#include "lvgl/lvgl.h"#define LVGL_TICK 5#include <tslib.h>
static struct tsdev *ts;void tsdev_init(void)
{char *tsdevname = getenv("TSLIB_TSDEVICE");if (tsdevname == NULL) {printf("Not found env named: TSLIB_TSDEVICE, %s \n", tsdevname);exit(-1);}printf("TSLIB_TSDEVICE : %s\n", tsdevname);ts = ts_open(tsdevname, 1);if (ts == NULL) {printf("Failed to open tsdev: %s\n", tsdevname);exit(-1);}ts_config(ts);
}/*** Get the current position and state of the tsdev* @param data store the tsdev data here* @return false: because the points are not buffered, so no more data to be read*/
static void tsdev_read(lv_indev_t * indev, lv_indev_data_t * data)
{static struct ts_sample samp;while (ts_read(ts, &samp, 1) == 1) {printf("%ld.%06ld: %6d %6d %6d %d\n",samp.tv.tv_sec, samp.tv.tv_usec,samp.x, samp.y, samp.pressure, data->state);}// printf("%ld.%06ld: %6d %6d %6d %d\n",//         samp.tv.tv_sec, samp.tv.tv_usec,//         samp.x, samp.y, samp.pressure, data->state);data->point.x = samp.x;data->point.y = samp.y;data->state = samp.pressure ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
}static void event_handler(lv_event_t* e)
{lv_event_code_t code = lv_event_get_code(e);if (code == LV_EVENT_CLICKED){LV_LOG_USER("Clicked");}else if (code == LV_EVENT_VALUE_CHANGED){LV_LOG_USER("Toggled");}
}void lv_example_btn_1(void)
{lv_obj_t* label;lv_obj_t* btn1 = lv_btn_create(lv_scr_act());lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_ALL, NULL);lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40);label = lv_label_create(btn1);lv_label_set_text(label, "Button");lv_obj_center(label);lv_obj_t* btn2 = lv_btn_create(lv_scr_act());lv_obj_add_event_cb(btn2, event_handler, LV_EVENT_ALL, NULL);lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 40);lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);lv_obj_set_height(btn2, LV_SIZE_CONTENT);label = lv_label_create(btn2);lv_label_set_text(label, "Toggle");lv_obj_center(label);
}int main()
{// 初始化LVGLlv_init();lv_display_t* disp = lv_linux_fbdev_create();lv_linux_fbdev_set_file(disp, "/dev/fb0");tsdev_init();lv_indev_t * indev = lv_indev_create();lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);lv_indev_set_read_cb(indev, tsdev_read);lv_indev_set_display(indev, disp);lv_example_btn_1();while (true){// printf("while\n");usleep(LVGL_TICK); /*Sleep for 5 millisecond*/lv_task_handler();lv_tick_inc(LVGL_TICK); /*Tell LVGL that 5 milliseconds were elapsed*/}
}

展示效果:

root@raspberrypi:~/lcd# ./lvglsim
[Warn]  (0.000, +0)      lv_init: Memory integrity checks are enabled via LV_USE_ASSERT_MEM_INTEGRITY which makes LVGL much slower lv_init.c:321
[Warn]  (0.000, +0)      lv_init: Object sanity checks are enabled via LV_USE_ASSERT_OBJ which makes LVGL much slower lv_init.c:325
[Warn]  (0.000, +0)      lv_init: Style sanity checks are enabled that uses more RAM lv_init.c:329
TSLIB_TSDEVICE : /dev/input/event0
[Warn]  (172029.872, +172029872)         lv_indev_set_read_cb: lv_indev_set_read_cb: read_cb is:  0x558126c130 lv_indev.c:314
1759772226.129870:     14     21    136 0
1759772226.143604:     13     22    141 01759772227.218917:    473     17    133 0
1759772227.228346:    472     18    138 01759772229.185915:      7    310    118 0
1759772229.199508:      8    310    126 01759772230.120387:    468    302    103 0
1759772230.132073:    468    303    129 01759772230.904041:    243    200    145 0
1759772230.915879:    244    201      0 0
[User]  (172037.650, +7778)      event_handler: Toggled main.c:352
[User]  (172037.651, +1)         event_handler: Clicked main.c:348

image

参考文档:

  • https://gitee.com/lqwu675/linux-lvgl/blob/gui-guider/main.c
  • https://blog.csdn.net/MOS_JBET/article/details/140488852
  • https://blog.csdn.net/qq_36413982/article/details/117308086
  • https://zmurder.github.io/lvgl/LVLG%E5%9C%A8%E6%A0%91%E8%8E%93%E6%B4%BE%E4%B8%8A%E7%A7%BB%E6%A4%8D%E5%9F%BA%E4%BA%8E9.3.0/
  • https://www.yanwenkai.com/?p=693
  • https://blog.gitcode.com/bd65a1bedf4c6696f912124418c8114d.html
http://www.hskmm.com/?act=detail&tid=25764

相关文章:

  • caddy搭建静态+PHP+伪静态Web服务器
  • 全自动 AI 视频创作与发布工具:LuoGen-agent
  • 静态库.a与.so库文件的生成与使用
  • CF2145D Inversion Value of a Permutation
  • 牛客刷题-Day8
  • Educational Codeforces Round 183 (Rated for Div. 2)
  • 高三闲话 #2
  • D. Inversion Value of a Permutation edu div2
  • 个人博客公告
  • 一个刚大一的普通大学生
  • 通过利用百度对于外链的检测算法上的缺陷
  • git常用助记
  • 云岚到家项目文字稿
  • 软件工程 第一次作业
  • 软工第一次团队作业
  • 教会音控组侍奉中的工序主义实践
  • 用 Kotlin 调用 Tesseract 实现验证码识别
  • Kotlin 调用 Tesseract 实现验证码识别
  • Dart 调用 Tesseract 实现验证码识别
  • Audacity导出音频后发声提醒
  • 做一个会Debug的程序员
  • 深度噪声抑制技术在语音增强中的突破
  • APUE学习笔记之UNIX标准及实现(二) - Invinc
  • 存一下刚开始学编程的东西
  • 线性偏微分方程和非线性偏微分方程的区别
  • 基于AXI模块的视频流传输(ps控制篇)
  • lora的各种变体
  • Kubernetes Deployment:部署与管理应用指南
  • GO+RabbitMQ+Gin+Gorm+docker 部署 demo - 实践
  • Python测试