如何使用Linux获得触摸屏Rawdata的坐标

有一个3米的微型触摸显示屏。 它通过USB连接到我的debian系统,并被识别为人机界面(hid)。 我试图访问和推送实时信息…如果它被触动,我想知道哪里(x,y),并通过netcatpipe道到另一个主机。

不幸的是我只能使用原始数据

cat /dev/input/event2 | hexdump 

evtest

你得到hex代码,似乎没有logging…

有谁知道如何获得这些信息? 必须有一种方法来从hex代码中提取它。 不幸的是,我不知道如何解释hex代码。 我无法find其logging的任何来源…

有没有一种方式的内核可以实时提供我所需的信息? 作为一个解决scheme,可能有一个解决scheme在哪里的X服务器可以告诉我? 触摸屏的行为就像X中的一个鼠标。我实际上已经试图通过xlib获得鼠标的x,y位置。 但它太慢,不会告诉我,如果有人触摸或不…

提前致谢!

evtest示例输出:

 Event: time 1425319271.595631, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 51 Event: time 1425319271.595631, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10304 Event: time 1425319271.595631, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30629 Event: time 1425319271.595631, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 893 Event: time 1425319271.595631, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 414 Event: time 1425319271.595631, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 1425319271.595631, type 3 (EV_ABS), code 0 (ABS_X), value 10304 Event: time 1425319271.595631, type 3 (EV_ABS), code 1 (ABS_Y), value 30629 Event: time 1425319271.595631, -------------- SYN_REPORT ------------ Event: time 1425319271.601632, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10306 Event: time 1425319271.601632, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30625 Event: time 1425319271.601632, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 962 Event: time 1425319271.601632, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 421 Event: time 1425319271.601632, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1 Event: time 1425319271.601632, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 52 Event: time 1425319271.601632, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 15416 Event: time 1425319271.601632, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 24159 Event: time 1425319271.601632, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 649 Event: time 1425319271.601632, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 354 Event: time 1425319271.601632, type 3 (EV_ABS), code 0 (ABS_X), value 10306 Event: time 1425319271.601632, type 3 (EV_ABS), code 1 (ABS_Y), value 30625 Event: time 1425319271.601632, -------------- SYN_REPORT ------------ Event: time 1425319271.606626, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 0 Event: time 1425319271.606626, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10318 Event: time 1425319271.606626, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30609 Event: time 1425319271.606626, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 1014 Event: time 1425319271.606626, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 426 Event: time 1425319271.606626, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1 Event: time 1425319271.606626, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 24161 Event: time 1425319271.606626, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 681 Event: time 1425319271.606626, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 376 Event: time 1425319271.606626, type 3 (EV_ABS), code 0 (ABS_X), value 10318 Event: time 1425319271.606626, type 3 (EV_ABS), code 1 (ABS_Y), value 30609 Event: time 1425319271.606626, -------------- SYN_REPORT ------------ Event: time 1425319271.611629, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 0 Event: time 1425319271.611629, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10320 Event: time 1425319271.611629, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30605 Event: time 1425319271.611629, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 1053 Event: time 1425319271.611629, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 430 Event: time 1425319271.611629, type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1 Event: time 1425319271.611629, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 705 Event: time 1425319271.611629, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 392 Event: time 1425319271.611629, type 3 (EV_ABS), code 0 (ABS_X), value 10320 Event: time 1425319271.611629, type 3 (EV_ABS), code 1 (ABS_Y), value 30605 

Solutions Collecting From Web of "如何使用Linux获得触摸屏Rawdata的坐标"

基于控制台的解决方案

您可以使用evtest工具获得解析的坐标。

  1. 如果您只需要单点触摸坐标:查找ABS_XABS_Y字段:

     type 3 (EV_ABS), code 0 (ABS_X), value 10306 type 3 (EV_ABS), code 1 (ABS_Y), value 30625 
  2. 如果您需要多点触摸坐标:

    • ABS_MT_SLOT表示手指的数量
    • ABS_MT_POSITION_XABS_MT_POSITION_Y – 坐标

    手指#0:

     type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 0 type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 10318 type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 30609 

    手指#1:

     type 3 (EV_ABS), code 47 (ABS_MT_SLOT), value 1 type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 20301 type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 24161 

例如,如果您需要通过网络发送单点触摸坐标,则可以使用如下脚本:

 #!/bin/sh # ---- Global variables ---- input=/dev/input/event0 code_prefix="ABS" code="${code_prefix}_[XY]" val_regex=".*(${code_prefix}_\(.\)), value \([-]\?[0-9]\+\)" val_subst="\1=\2" # ---- Functions ---- send_axis() { # 1. Convert axis value ($1) from device specific units # 2. Send this axis value via UDP packet echo $1 } process_line() { while read line; do axis=$(echo $line | grep "^Event:" | grep $code | \ sed "s/$val_regex/$val_subst/") if [ -n "$axis" ]; then send_axis $axis fi done } # ---- Entry point ---- if [ $(id -u) -ne 0 ]; then echo "This script must be run from root" >&2 exit 1 fi evtest $input | process_line 

基于程序的解决方案

您可以编写将读取您的事件文件的C应用程序。 获得的二进制数据可以很容易地解释,参见内核文档中的第5节。 您可以使用select()系统调用等待下一个数据部分。

 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <linux/input.h> #define EVENT_DEVICE "/dev/input/event2" #define EVENT_TYPE EV_ABS #define EVENT_CODE_X ABS_X #define EVENT_CODE_Y ABS_Y /* TODO: Close fd on SIGINT (Ctrl-C), if it's open */ int main(int argc, char *argv[]) { struct input_event ev; int fd; char name[256] = "Unknown"; if ((getuid ()) != 0) { fprintf(stderr, "You are not root! This may not work...\n"); return EXIT_SUCCESS; } /* Open Device */ fd = open(EVENT_DEVICE, O_RDONLY); if (fd == -1) { fprintf(stderr, "%s is not a vaild device\n", EVENT_DEVICE); return EXIT_FAILURE; } /* Print Device Name */ ioctl(fd, EVIOCGNAME(sizeof(name)), name); printf("Reading from:\n"); printf("device file = %s\n", EVENT_DEVICE); printf("device name = %s\n", name); for (;;) { const size_t ev_size = sizeof(struct input_event); ssize_t size; /* TODO: use select() */ size = read(fd, &ev, ev_size); if (size < ev_size) { fprintf(stderr, "Error size when reading\n"); goto err; } if (ev.type == EVENT_TYPE && (ev.code == EVENT_CODE_X || ev.code == EVENT_CODE_Y)) { /* TODO: convert value to pixels */ printf("%s = %d\n", ev.code == EVENT_CODE_X ? "X" : "Y", ev.value); } } return EXIT_SUCCESS; err: close(fd); return EXIT_FAILURE; } 

坐标单位

首先你需要知道下面的事情:

  • 坐标原点(即[x=0;y=0]
  • 您的设备用于表示坐标的单位

这些信息通常可以在您设备的驱动程序代码中找到。

这是您设备的驱动程序。

所以看起来你需要将你的坐标轴从evtest除以65535,然后乘以设备的宽度或高度(以像素为单位)。 例如,如果您获得X = 30000,并且您的LCD面板的宽度为1080像素,则需要执行以下操作:

 X = round((30000 / 65535) * 1080) = 494 pixels