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

由于使用从/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()
{
    // 初始化LVGL
    lv_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*/
    }
}

修改全局变量:

export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/lib/aarch64-linux-gnu/ts0
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0

💡 注意:TSLIB_PLUGINDIR=/usr/lib/aarch64-linux-gnu/ts0 路径可能因系统版本略有不同,可用 find /usr -name "ts" -type d 查找。

也可以直接写入到/etc/profile或者~/.bashrc中,全局生效

展示效果:

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 0

1759772227.218917:    473     17    133 0
1759772227.228346:    472     18    138 0

1759772229.185915:      7    310    118 0
1759772229.199508:      8    310    126 0

1759772230.120387:    468    302    103 0
1759772230.132073:    468    303    129 0

1759772230.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

参考文档: