How to get Coordinates of Touchscreen Rawdata using Linux
Console-based solution
You can obtain parsed coordinates using evtest
tool.
If you only need single-touch coordinates: look for
ABS_X
andABS_Y
fields:type 3 (EV_ABS), code 0 (ABS_X), value 10306
type 3 (EV_ABS), code 1 (ABS_Y), value 30625If you need multi-touch coordinates:
ABS_MT_SLOT
represents number of fingerABS_MT_POSITION_X
andABS_MT_POSITION_Y
-- coordinates
Finger #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 30609Finger #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
Program-based solution
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;
}
Coordinates units
First of all you need to know next things:
- where is coordinates origin point (i.e.
[x=0;y=0]
) - which units your device is using for representing coordinates
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
Get coordinates from USB 2.0 TouchScreen Monitor under ubuntu.
in general you can get the coordinates using the evtest
tool, that reads input events i.e. in /dev/input/event
see How to get Coordinates of Touchscreen Rawdata using Linux <- very good answer
Despite this other ways to get the data depend on your touchscreen (reading/writing /dev/ttySx ,...). Touch screens are in general implemented as USB HID devices or emulating a serial connection
(https://wiki.ubuntu.com/Touchscreen)
Checking for touchscreen connectivity
When encountering a new device, the first order of business is to
determine how the touchscreen is connected to your computer. If the
touchscreen produces no events out of the box, check to see if it's an
USB device or not:
lsusb
USB connection
Check the output for any reference to a touchscreen. If your
touchscreen has an USB interface, and it isn't working, then you may
need to blacklist the usbtouchscreen driver for it to work:
sudo modprobe -r usbtouchscreen
If your touchscreen begins to produce events, then you can permanently
blacklist the usbtouchscreen driver:
echo "blacklist usbtouchscreen" | sudo tee -a
/etc/modprobe.d/blacklist.confSome touchscreens might already have good or perfect calibrations,
otherwise you'll need to continue to the calibration section.Serial connection
If there is no reference to a touchscreen device in your
lsusb
output,
the connection is most likely through one of your serial ports. The
actual IRQ mapping varies between manufacturers. In the case of
Itronix devices, the default is/dev/ttyS3
. A simple way to check for
connections is to check each one for events:
screen /dev/ttyS0
Touch anywhere on your screen to check for any character output. If
nothing happens, quit screen by pressingCtrl+A
and then the\
key
to quit. Continue with/dev/ttyS1
, etc. until you get a response. Once
you've determined the device, we can try a few different drivers. In
the case of Itronix (and most other devices using the Touchkit
driver), the correct driver istouchit213
.
sudo inputattach --touchit213 /dev/ttyS3
Will work for most touchkit screens. The calibration or one or more
axes may be swapped, but if the calibration is approximate then it's
probably the correct driver. PressCtrl+C
to try a new mode.
inputattach supports any of the following modes, which includes
external touchscreens which may attach through a physical serial port:
- --h3600ts -ipaq Ipaq h3600 touchscreend
- --elotouch -elo ELO touchscreen, 10-byte mode
- --elo4002 -elo6b ELO touchscreen, 6-byte mode
- --elo271-140 -elo4b ELO touchscreen, 4-byte mode
- --elo261-280 -elo3b ELO Touchscreen, 3-byte mode
- --mtouch -mtouch MicroTouch (3M) touchscreen
- --touchit213 -t213 Sahara Touch-iT213 Tablet PC
- --touchright -tr Touchright serial touchscreen
- --touchwin -tw Touchwindow serial touchscreen
- --penmount -pm Penmount touchscreen
- --fujitsu -fjt Fujitsu serial touchscreen
If your device is built into a laptop, you'll have the best luck with
the mtouch, touchright, touchwin, or touchit213 drivers. Likewise,
non-Elo external touchscreens will most likely use touchit213. If your
device is a tablet with stylus-only input, fujitsu is a popular maker
of embedded tablet devices.To attach the touchscreen at startup, edit your /etc/rc.local to look
like the following:
/usr/bin/inputattach --daemon --always -t213 /dev/ttyS3 exit 0
Replace
-t213
with your appropriate driver and/dev/ttyS3
with the
correct device.Again, don't worry if the calibration isn't perfect, or if an axis is
inverted or reversed - this will be addressed in the calibration
section.
https://wiki.ubuntu.com/Touchscreen
How to read hardware-level event information from touchscreen?
I went ahead and tested the monitor with a laptop that had Linux kernel 4.4.0, and it worked right away, so it seems that it's definitely the kernel. I don't know if there are any touchscreens that WILL work with kernel 2.6.32, but the ones based on the Quanta display definitely don't work.
Related Topics
How to Sort Files Numerically from Linux Command Line
Sort Across Multiple Files in Linux
Not Authorized for Query on Admin.System.Namespaces on Mongodb
Why Is There No Directx API for Linux
What Happens to Other Processes When a Docker Container's Pid1 Exits
How to Find or Calculate a Linux Process's Page Table Size and Other Kernel Accounting
Why Is My Bash Script Adding <Feff> to the Beginning of Files
The Return Code from 'Grep' Is Not as Expected on Linux
Setting Limit to Total Physical Memory Available in Linux
Difference Between Patch and Diff Files
Remove Log Files Using Cron Job
How to Close a Netcat Connection After a Certain Character Is Returned in the Response
@Reboot Is Not Working in Cron
Error: Ld.So: Object Ld_Preload Cannot Be Preloaded: Ignored
How to Run a Command in a Chroot Jail Not as Root and Without Sudo