We have a 3m microtouch display. It's connected to my Debian system via USB and recognized as human interface (hid). I am trying to access and push realtime information... if its getting touched I want to know where (x,y) and pipe it through netcat to another host.
Unfortunately I am only able to get raw data using:
cat /dev/input/event2 | hexdump
or
evtest
You get hexcode that seem nowhere documented...
Does anybody have a clue how to get that information? There must be a way to extract it from the hexcode. Unfortunately I have no idea how to interpret the hexcode. I couldn't find any source where its documented...
Is there a way the Kernel could provide me those desired information in realtime?
As a workaround, is there, maybe, a solution where the X-Server could tell me? The touchscreen behaves like a mouse in X. I actually already tried to get x,y-position of the mouse via xlib. But it was too slow and wouldn't tell me if somebody is touching or not...
evtest
sample output:
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
You can obtain parsed coordinates using evtest
tool.
If you only need single-touch coordinates: look for ABS_X
and ABS_Y
fields:
type 3 (EV_ABS), code 0 (ABS_X), value 10306
type 3 (EV_ABS), code 1 (ABS_Y), value 30625
If you need multi-touch coordinates:
ABS_MT_SLOT
represents number of fingerABS_MT_POSITION_X
and ABS_MT_POSITION_Y
-- coordinatesFinger #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
Finger #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
For example, if you need to send single-touch coordinates via network, you can use script like this:
#!/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
You can write C application that will read your event file. Obtained binary data can be easily interpreted, see section 5 in kernel documentation.
You can wait for next data portion using select()
syscall.
#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;
}
First of all you need to know next things:
[x=0;y=0]
)This information usually can be found in driver code for your device.
This is the driver for your device.
So it seems like you need to divide your axis value from evtest
by 65535 and multiply it by width or height of device (in pixels). For example, if you get X=30000, and width of your LCD panel is 1080 pixels, you need to do:
X = round((30000 / 65535) * 1080) = 494 pixels
You get hexcode that seem nowhere documented...
This is documented by the device itself, which is how the hid-multitouch
driver can interpret the USB data it receives.
You can find the information using the following commands:
$ lsusb # determine the bus & device numbers
...
Bus 001 Device 067: ID 1aad:000f KeeTouch
...
$ sudo usbhid-dump -a 1:67 -e d
001:067:002:DESCRIPTOR 1615651625.434241
05 0D 09 04 A1 01 85 03 09 22 09 00 15 00 26 FF
00 75 08 95 09 81 02 A1 00 05 0D 09 51 15 00 26
FF 00 75 08 95 01 81 02 05 0D 09 42 15 00 25 01
75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05
81 03 05 01 09 30 26 FF 7F 55 00 65 00 35 00 46
00 00 75 10 95 01 81 02 09 31 35 00 46 00 00 81
02 05 0D 09 48 15 00 26 FF 7F 75 10 95 01 81 02
09 49 15 00 26 FF 7F 75 10 95 01 81 02 C0 A1 00
05 0D 09 51 15 00 26 FF 00 75 08 95 01 81 02 05
0D 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81
02 09 47 81 02 95 05 81 03 05 01 09 30 26 FF 7F
55 00 65 00 35 00 46 00 00 75 10 95 01 81 02 09
31 35 00 46 00 00 81 02 05 0D 09 48 15 00 26 FF
7F 75 10 95 01 81 02 09 49 15 00 26 FF 7F 75 10
95 01 81 02 C0 A1 00 05 0D 09 51 15 00 26 FF 00
75 08 95 01 81 02 05 0D 09 42 15 00 25 01 75 01
95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03
05 01 09 30 26 FF 7F 55 00 65 00 35 00 46 00 00
75 10 95 01 81 02 09 31 35 00 46 00 00 81 02 05
0D 09 48 15 00 26 FF 7F 75 10 95 01 81 02 09 49
15 00 26 FF 7F 75 10 95 01 81 02 C0 A1 00 05 0D
09 51 15 00 26 FF 00 75 08 95 01 81 02 05 0D 09
42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09
47 81 02 95 05 81 03 05 01 09 30 26 FF 7F 55 00
65 00 35 00 46 00 00 75 10 95 01 81 02 09 31 35
00 46 00 00 81 02 05 0D 09 48 15 00 26 FF 7F 75
10 95 01 81 02 09 49 15 00 26 FF 7F 75 10 95 01
81 02 C0 A1 00 05 0D 09 51 15 00 26 FF 00 75 08
95 01 81 02 05 0D 09 42 15 00 25 01 75 01 95 01
81 02 09 32 81 02 09 47 81 02 95 05 81 03 05 01
09 30 26 FF 7F 55 00 65 00 35 00 46 00 00 75 10
95 01 81 02 09 31 35 00 46 00 00 81 02 05 0D 09
48 15 00 26 FF 7F 75 10 95 01 81 02 09 49 15 00
26 FF 7F 75 10 95 01 81 02 C0 A1 00 05 0D 09 54
15 00 25 1F 75 08 95 01 81 02 C0 09 55 85 FD 15
00 26 FF 00 75 08 95 01 B1 02 C0 05 0D 09 0E A1
01 85 FC 09 52 09 53 15 00 26 FF 00 75 08 95 02
B1 02 C0
001:067:001:DESCRIPTOR 1615651625.436655
05 01 09 02 A1 01 85 02 09 01 A1 00 06 00 FF 09
00 15 00 26 FF 00 75 08 95 09 81 02 05 01 09 30
09 31 15 00 26 FF 7F 75 10 95 02 81 02 05 09 19
01 29 08 15 00 25 01 95 08 75 01 81 02 C0 C0
001:067:000:DESCRIPTOR 1615651625.437001
06 00 FF 09 00 A1 01 09 00 85 01 A1 00 09 00 15
00 26 FF 00 35 00 46 FF 00 75 08 95 3F 81 02 C0
09 02 85 FE A1 00 09 06 15 00 26 FF 00 35 00 46
FF 00 75 08 95 3F B1 02 C0 C0
I use the lsusb
command to determine the bus and device numbers and pass that to the usbhid-dump
command. You can use the dump command without those numbers, but then you get a list of all your devices. Probably not what you want in most cases.
The codes in there are interpreted by the hid_parser()
command in the kernel. Only some devices may not be properly recognized and that's when you need this information.
How to interpret that data is defined by the USB consortium. At this time, it is version 1.11 and it can be found on this page for the hid type of devices.
This mainly includes Keyboards, Mice, Touchscreens, Touchpads, Joysticks, although some other types of devices support this too (your Power button, various buttons on your monitor, etc.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With