如何使用Linux获取Touchscreen Rawdata的坐标

前端之家收集整理的这篇文章主要介绍了如何使用Linux获取Touchscreen Rawdata的坐标前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们有一个3米的微触摸显示屏.它通过usb连接到我的debian系统,并被识别为人机界面(hid).我正在尝试访问并推送实时信息…如果它被触及我想知道哪里(x,y)并通过netcat管道到另一台主机.

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

  1. cat /dev/input/event2 | hexdump

要么
evtest

你得到的hexcode似乎没有记录……

有人知道如何获取这些信息吗?必须有一种从十六进制代码提取它的方法.不幸的是我不知道如何解释hexcode.我找不到任何有文件记载的来源……

有没有办法让内核能够实时提供我想要的信息?
作为一个解决方案,可能有一个X-Server可以告诉我的解决方案?触摸屏的行为类似于X中的鼠标.我实际上已经尝试通过xlib获取鼠标的x,y位置.但它太慢了,无法告诉我是否有人在接触……

提前致谢!

evtest样本输出

  1. Event: time 1425319271.595631,type 3 (EV_ABS),code 57 (ABS_MT_TRACKING_ID),value 51
  2. Event: time 1425319271.595631,code 53 (ABS_MT_POSITION_X),value 10304
  3. Event: time 1425319271.595631,code 54 (ABS_MT_POSITION_Y),value 30629
  4. Event: time 1425319271.595631,code 48 (ABS_MT_TOUCH_MAJOR),value 893
  5. Event: time 1425319271.595631,code 49 (ABS_MT_TOUCH_MINOR),value 414
  6. Event: time 1425319271.595631,type 1 (EV_KEY),code 330 (BTN_TOUCH),value 1
  7. Event: time 1425319271.595631,code 0 (ABS_X),code 1 (ABS_Y),-------------- SYN_REPORT ------------
  8. Event: time 1425319271.601632,value 10306
  9. Event: time 1425319271.601632,value 30625
  10. Event: time 1425319271.601632,value 962
  11. Event: time 1425319271.601632,value 421
  12. Event: time 1425319271.601632,code 47 (ABS_MT_SLOT),value 1
  13. Event: time 1425319271.601632,value 52
  14. Event: time 1425319271.601632,value 15416
  15. Event: time 1425319271.601632,value 24159
  16. Event: time 1425319271.601632,value 649
  17. Event: time 1425319271.601632,value 354
  18. Event: time 1425319271.601632,-------------- SYN_REPORT ------------
  19. Event: time 1425319271.606626,value 0
  20. Event: time 1425319271.606626,value 10318
  21. Event: time 1425319271.606626,value 30609
  22. Event: time 1425319271.606626,value 1014
  23. Event: time 1425319271.606626,value 426
  24. Event: time 1425319271.606626,value 1
  25. Event: time 1425319271.606626,value 24161
  26. Event: time 1425319271.606626,value 681
  27. Event: time 1425319271.606626,value 376
  28. Event: time 1425319271.606626,-------------- SYN_REPORT ------------
  29. Event: time 1425319271.611629,value 0
  30. Event: time 1425319271.611629,value 10320
  31. Event: time 1425319271.611629,value 30605
  32. Event: time 1425319271.611629,value 1053
  33. Event: time 1425319271.611629,value 430
  34. Event: time 1425319271.611629,value 1
  35. Event: time 1425319271.611629,value 705
  36. Event: time 1425319271.611629,value 392
  37. Event: time 1425319271.611629,value 30605

解决方法

基于控制台的解决方

您可以使用evtest工具获取已解析的坐标.

>如果您只需要单点触控坐标:查找ABS_X和ABS_Y字段:

  1. type 3 (EV_ABS),value 10306
  2. type 3 (EV_ABS),value 30625

>如果您需要多点触控坐标:

> ABS_MT_SLOT表示手指的数量
> ABS_MT_POSITION_X和ABS_MT_POSITION_Y – 坐标

手指#0:

  1. type 3 (EV_ABS),value 0
  2. type 3 (EV_ABS),value 10318
  3. type 3 (EV_ABS),value 30609

手指#1:

  1. type 3 (EV_ABS),value 1
  2. type 3 (EV_ABS),value 20301
  3. type 3 (EV_ABS),value 24161

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

  1. #!/bin/sh
  2.  
  3. # ---- Global variables ----
  4.  
  5. input=/dev/input/event0
  6. code_prefix="ABS"
  7. code="${code_prefix}_[XY]"
  8. val_regex=".*(${code_prefix}_\(.\)),value \([-]\?[0-9]\+\)"
  9. val_subst="\1=\2"
  10.  
  11. # ---- Functions ----
  12.  
  13. send_axis() {
  14. # 1. Convert axis value ($1) from device specific units
  15. # 2. Send this axis value via UDP packet
  16. echo $1
  17. }
  18.  
  19. process_line() {
  20. while read line; do
  21. axis=$(echo $line | grep "^Event:" | grep $code | \
  22. sed "s/$val_regex/$val_subst/")
  23.  
  24. if [ -n "$axis" ]; then
  25. send_axis $axis
  26. fi
  27. done
  28. }
  29.  
  30. # ---- Entry point ----
  31.  
  32. if [ $(id -u) -ne 0 ]; then
  33. echo "This script must be run from root" >&2
  34. exit 1
  35. fi
  36.  
  37. evtest $input | process_line

基于程序的解决方

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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <linux/input.h>
  6.  
  7. #define EVENT_DEVICE "/dev/input/event2"
  8. #define EVENT_TYPE EV_ABS
  9. #define EVENT_CODE_X ABS_X
  10. #define EVENT_CODE_Y ABS_Y
  11.  
  12. /* TODO: Close fd on SIGINT (Ctrl-C),if it's open */
  13.  
  14. int main(int argc,char *argv[])
  15. {
  16. struct input_event ev;
  17. int fd;
  18. char name[256] = "Unknown";
  19.  
  20. if ((getuid ()) != 0) {
  21. fprintf(stderr,"You are not root! This may not work...\n");
  22. return EXIT_SUCCESS;
  23. }
  24.  
  25. /* Open Device */
  26. fd = open(EVENT_DEVICE,O_RDONLY);
  27. if (fd == -1) {
  28. fprintf(stderr,"%s is not a vaild device\n",EVENT_DEVICE);
  29. return EXIT_FAILURE;
  30. }
  31.  
  32. /* Print Device Name */
  33. ioctl(fd,EVIOCGNAME(sizeof(name)),name);
  34. printf("Reading from:\n");
  35. printf("device file = %s\n",EVENT_DEVICE);
  36. printf("device name = %s\n",name);
  37.  
  38. for (;;) {
  39. const size_t ev_size = sizeof(struct input_event);
  40. ssize_t size;
  41.  
  42. /* TODO: use select() */
  43.  
  44. size = read(fd,&ev,ev_size);
  45. if (size < ev_size) {
  46. fprintf(stderr,"Error size when reading\n");
  47. goto err;
  48. }
  49.  
  50. if (ev.type == EVENT_TYPE && (ev.code == EVENT_CODE_X
  51. || ev.code == EVENT_CODE_Y)) {
  52. /* TODO: convert value to pixels */
  53. printf("%s = %d\n",ev.code == EVENT_CODE_X ? "X" : "Y",ev.value);
  54. }
  55. }
  56.  
  57. return EXIT_SUCCESS;
  58.  
  59. err:
  60. close(fd);
  61. return EXIT_FAILURE;
  62. }

坐标单位

首先,您需要了解下一步:

>其中是坐标原点(即[x = 0; y = 0])
>您的设备用于表示坐标的单位

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

This是您设备的驱动程序.

因此,您似乎需要将您的轴值从evtest除以65535并将其乘以设备的宽度或高度(以像素为单位).例如,如果X = 30000,并且LCD面板的宽度为1080像素,则需要执行以下操作:

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

猜你在找的Linux相关文章