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

news/2025/10/7 2:24:39/文章来源:https://www.cnblogs.com/liulongtao/p/19128100

转载请标明出处,否则禁止转载。 标题:<玩转树莓派屏幕之四:适配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.mzph.cn/news/929902.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站上的图标用什么软件做的静态网页模版

掌握一些技巧&#xff0c;可尽量提高Python程序性能&#xff0c;也可以避免不必要的资源浪费。 追求性能极限是一个有趣的游戏, 而过度优化就会变成嘲弄了。虽然Python授予你与C接口无缝集成的能力, 你必须问自己你花数小时的艰辛优化工作用户是否买帐. 另一方面, 牺牲代码的可…

创意广告设计网站龙岗公司网站建设

第一次作业(2015.9.13)作业题目存在问题1.学生可能平时写博客的机会比较少&#xff0c;书写格式存在的问题比较多。比如文字排版、博客中的代码直接粘贴(没有使用代码样式)、插入的图片太大等等。这些问题老师在上课的时候可以专门抽出一节课的时间跟学生讲一下&#xff0c;计算…

做网站的语言有哪些网站不接入备案

#!/usr/bin/python # -*- coding: utf-8 -*- """ 写一个三层的BP神经网络&#xff08;3&#xff0c;2&#xff0c;1&#xff09;,3是输入数据的维度&#xff0c;隐层设置节点数为2&#xff0c;1是因为每个观测的target都是一个标量即只有一个数&#xff1b; 1.随…

免费推广网站有哪些建网站的工具有哪些

&#x1f48e; 欢迎大家互三&#xff1a;2的n次方_ &#x1f48e;1. 介绍 深度学习在人工智能领域中占据了重要地位&#xff0c;特别是生成对抗网络&#xff08;GANs&#xff09;、自监督学习和Transformer模型的出现&#xff0c;推动了图像生成、自然语言处理等多个领域的创…

顺德精品网站建设网站开发都需要什么工作

文章目录 1.主要属性DataSource行&#xff08;Row 相关属性&#xff09;列&#xff08;Column 相关属性&#xff09;单元格&#xff08;Cell 相关属性&#xff09;逻辑删除AllowUserToAddRowsAllowUserToDeleteRowsAllowUserToOrderColumns其他布局和行为属性 2.控件中的行、列…

阜新建设网站wordpress 音乐不中断

0、基础知识 1000毫秒内&#xff0c;允许2个请求&#xff0c;其他请求全部拒绝。 不拒绝就可能往db打请求&#xff0c;把db干爆~ interval 1000 rate 2&#xff1b; 一、固定窗口限流 固定窗口限流算法&#xff08;Fixed Window Rate Limiting Algorithm&#xff09;是…

简单美食网站模板怀宁建设局网站

文章目录 1. 为什么要建立自己的交易系统2. 一个朋友的交易体系分享2.1 开仓原则2.2 计算盈亏比2.3 第三原则&#xff1a;资金管理原则2.4 持股原则2.5 技术指标 3. 作者本人的交易系统 1. 为什么要建立自己的交易系统 有稳定的交易系统&#xff0c;会让人很清晰的 知道什么样…

网站怎么做啊变装 wordpress

区别 核心区别&#xff1a;显存&#xff0c;也被称作帧缓存。独立显卡拥有独立显存&#xff0c;而集成显卡通常是没有的&#xff0c;需要占用部分主内存来达到缓存的目的 集成显卡&#xff1a; 是集成在主板上的&#xff0c;与主处理器共享系统内存。 一般会在很多轻便薄型的…

caddy搭建静态+PHP+伪静态Web服务器

caddy搭建静态+PHP+伪静态Web服务器feieryun-v2.hk2.anan.cc {handle_path /AdminLTE/* {root C:\data\service\caddy\www\AdminLTEfile_serverencode}handle_path /static/* {root C:\data\service\caddy\www\v2.feie…

网站营销信息做调查问卷能赚钱的网站

NumPy数据处理详解的笔记3 第1章NumPy基础 NumPy是用于处理多维数组的数值运算库&#xff0c;不仅可用于 机器学习&#xff0c;还可以用于图像处理&#xff0c;语言处理等任务。 1.4 切片 python编程语言对数组切片功能有支持, NumPy 的ndarray 的切片功能是类似的&#xf…

全自动 AI 视频创作与发布工具:LuoGen-agent

对于短视频创作者而言,内容制作往往耗时且流程繁琐——从脚本撰写到口播录制,再到字幕、BGM、封面和发布,每个环节都需要投入大量精力。为了让创作者能专注于创意本身,LuoGen-agent 提供了一套完整的 AI 自动化解决…

网站建设丶金手指花总13大连建设工程信息网去哪里找

先按照https://zhuanlan.zhihu.com/p/494988089说明下载好Gitblit然后复制到tomcat的webapps目录下,如下: 双击"startup.bat"启动tomcat: 然后访问"http://127.0.0.1:8080/gitblit/"即可看到git的界面: 说明git服务器已经能够成功运行了! Vmware虚拟机…

会做网站开发 但是不会二次开发广告公司 网站制作

虽说使用的人大都对微软没什么好感&#xff0c;但不能否认微软确实也出了不少好东西呀&#xff0c;比如微软鼠标(IE系列) icon_smile.gif IE2.0和以上版本都有5个按钮&#xff0c;除了正常的左中右外&#xff0c;两侧还各有一个&#xff0c;在windows中可用来支持浏览器的前进/…

wordpress登录循环安徽关键词seo

JSP&#xff08;Java Server Page&#xff09;是J2EE的功能模块&#xff0c;是Java服务器页面&#xff0c;由Web服务器执行&#xff0c;作用就是降低动态网页开发难度&#xff0c;将Java代码与HTML分离&#xff0c;降低开发难度&#xff0c;本质就是Servlet。 Servlet的缺点&a…

qq空间关闭申请网站荥阳网站制作

第一次见这个题&#xff0c;看时间小于O(N)。。。。。 只能是二分啊。 但是怎么二分&#xff0c;条件是什么&#xff0c;真的想不到。 后来知道了&#xff0c;我们要找最深一层最右边那个结点。借此确定结点个数。 我们知道&#xff0c;满二叉树的结点个数和深度是有公式的&a…

站长工具域名wordpress外国主题

目录 常见思路更优的解法&#xff08;面试官喜欢的&#xff09; 常见思路 要选出最小的前K个数首先我们会想到排排升序建大堆&#xff0c;排降序建小堆 一个直观的想法是使用&#xff08;小根堆&#xff09;&#xff0c;起始将所有元素放入堆中&#xff0c;然后再从堆中取出k 个…

静态库.a与.so库文件的生成与使用

任务一.用gcc生成静态库和动态库 1.1在ubuntu系统中创建一个目录来保存程序文件并编辑三个程序hello.h,hello.c,main.c。 先通过后端代码创建目录然后用vim文本编辑器编辑三个程序文件 程序1 hello.h:程序2 hello.c:程…

CF2145D Inversion Value of a Permutation

错题好题集第二篇。 题意 你需要构造一个长度为 \(n\) 的排列,使得它的逆序值恰好为 \(k\)。逆序值的定义 对于一个排列 $p$,我们将其逆序值定义为至少包含一个逆序对的子段的数量。形式上,这就是满足以下条件的一对…

朔州如何做百度的网站网站数据库做好了 怎么做网页

一、服务器准备 1、服务器配置 准备3台服务器&#xff0c;建议最低配置如下&#xff08;阿里云大约每台每月六百多&#xff09;&#xff1a; centos7.4 8c 16G 39.101.192.109 node001 39.101.179.3 node002 39.99.236.205 node003 为服务器开启外网端口访问 7180、8900 2…

阿里 做网站北京市住房建设网站

SpringBoot教程(十六) | SpringBoot集成swagger&#xff08;全网最全&#xff09; 一. 接口文档概述 swagger是当下比较流行的实时接口文文档生成工具。接口文档是当前前后端分离项目中必不可少的工具&#xff0c;在前后端开发之前&#xff0c;后端要先出接口文档&#xff0c…