Some months ago I found a cheap 7″ LCD screen with a resistive touch-panel. Searching the internet gave me some hope that the screen would work perfectly with my RaspberryPi. And alas, it did. Under XWindows, which I wasn’t going to use on the project I had in mind when buying the touch-display. So the search began and lastet. There’s lots of information out there about eGalax-touchscreens, most of it stating that one needs to compile a custom kernel, hack into some outdated driver software and so on.
After some investigation it became clear that the information available is mostly outdated, as the newer Raspbian images do recognize the touchscreen without compiling a custom kernel. So I started on my own and tried to get the screen working not with XWindows, but directly with the framebuffer.The touchscreen is sold by German company “Pollin“, it is called “LS-7T” and came rather cheap (they did increase the pricetag lately, though). They do have a 8″ version of it now.
If you look at the pictures you’ll recognize that this is the bare screen and PCB, connected by very sensitive connections. That is why I decided on building a stand for the screen and PCB before starting with anything else. In fact I nearly fried the PCB at first when powering it up on my workbench where a sheet of aluminium foil slid under the PCB… The material of choice for quickly made stands and housings in my office space is Lego. So here are some pictures of the touchscreen stand to give you an idea:
Preparation and first check
In this blog post I assume you are using an up-to-date raspbian image, I tested everything in here with the image from 2014-12-24. Connect the touch panel’s USB connector to the Raspberry and connect an HDMI cable. I found it safer to have the screen connected to power before switching the Raspberry on. Oh, and yes, despite the information in the technical data, the screen runs just fine with a 5 V power supply! Boot up the Raspberry and let’s see if the screen gets recognized correctly:
dmesg | grep usb
should give some output like this (lots of output omitted intentionally!):
[ 2.567877] usb 1-1.3: new low-speed USB device number 4 using dwc_otg [ 2.694277] usb 1-1.3: New USB device found, idVendor=0eef, idProduct=0001 [ 2.698823] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 2.701964] usb 1-1.3: Product: Touch [ 2.711510] usb 1-1.3: Manufacturer: eGalax Inc. [ 2.740816] input: eGalax Inc. Touch as /devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0/0003:0EEF:0001.0001/input/input0 [ 2.749476] input: eGalax Inc. Touch as /devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0/0003:0EEF:0001.0001/input/input1 [ 2.764460] hid-generic 0003:0EEF:0001.0001: input,hidraw0: USB HID v1.12 Pointer [eGalax Inc. Touch] on usb-bcm2708_usb-1.3/input0 [ 3.007947] usb 1-1.5: new low-speed USB device number 5 using dwc_otg [ 3.147537] usb 1-1.5: New USB device found, idVendor=1a2c, idProduct=0021 [ 3.151538] usb 1-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 3.155157] usb 1-1.5: Product: USB Keykoard [ 3.167865] usb 1-1.5: Manufacturer: USB [ 3.207912] input: USB USB Keykoard as /devices/platform/bcm2708_usb/usb1/1-1/1-1.5/1-1.5:1.0/0003:1A2C:0021.0002/input/input2 [ 3.217428] hid-generic 0003:1A2C:0021.0002: input,hidraw1: USB HID v1.10 Keyboard [USB USB Keykoard] on usb-bcm2708_usb-1.5/input0 [ 13.237702] hid-generic 0003:1A2C:0021.0003: usb_submit_urb(ctrl) failed: -1 [ 13.247748] input: USB USB Keykoard as /devices/platform/bcm2708_usb/usb1/1-1/1-1.5/1-1.5:1.1/0003:1A2C:0021.0003/input/input3 [ 13.257327] hid-generic 0003:1A2C:0021.0003: input,hidraw2: USB HID v1.10 Device [USB USB Keykoard] on usb-bcm2708_usb-1.5/input1
As you can see the touchscreen is detected an recognized as an “eGalax Inc.” touchscreen and is assigned some input events and devices. Let’s see where those input devices are linked to:
ls -al /dev/input/by-id
and voilà, linked to event1 is the touch-event of the screen:
drwxr-xr-x 2 root root 120 Jan 1 1970 . drwxr-xr-x 4 root root 240 Jan 1 1970 .. lrwxrwxrwx 1 root root 9 Jan 1 1970 usb-eGalax_Inc._Touch-event-mouse -> ../event1 lrwxrwxrwx 1 root root 6 Jan 1 1970 usb-eGalax_Inc._Touch-mouse -> ../js0 lrwxrwxrwx 1 root root 9 Jan 1 1970 usb-USB_USB_Keykoard-event-if01 -> ../event3 lrwxrwxrwx 1 root root 9 Jan 1 1970 usb-USB_USB_Keykoard-event-kbd -> ../event2
For reasons I have not yet figured out, if at any time the touch-event-mouse gets assigned ../event0 (that is event zero) the touch events are no longer recognized in framebuffer/console mode. Funnily enough, und XWindows everything still works.
Install tools and packages needed
To make the eGalax touchdevice work with Raspbian we need to compile, make and install an updated version of tslib. Prior to doing this, there are some packages needed. Make sure you did an sudo apt-get update and sudo apt-get upgrade first. Then type:
sudo apt-get install git automake libtool
Now it is best to change to the home directory and create a directory where the things we download next will be saved to. I called mine “Downloads”. Change into that directory and with
git clone git://github.com/kergoth/tslib.git cd tslib
we get the sources for an updated version of tslib that includes support for the eGalax touchscreen. In numerous blogs you may read something about pulling a patch from git://github.com/Vodalys/tslib.git but that is no longer necessary. This patch has long been included in the sources we cloned from git://github.com/kergoth/tslib.git.
With the next couple of instructions we are going to configure, make and install our own version of tslib. The compiled libraries automatically go to /usr/local/lib and the binaries to /usr/local/bin. It would be possible to define other paths (check the man pages of the configure tool). I am later going to copy (yes, copy) the files manually into the “correct” directories. This was the only way I was able to make the self-compiled libts work, no idea why…
It would be best to issue the following commands one after the other and checking the output for errors. Be patient, the process of configuring and building will take a while.
./autogen.sh ./configure make sudo make install
Congratulations! There should now be some new library files in /usr/local/lib. Do a quick
ls -al /usr/local/lib/libts*
to check. And while you’re at it, check for the binaries, too:
ls -al /usr/local/bin/ts*
You should see some files listed after executing each command. Now make sure there is no other libts installed in the system (there should be none, but it is better to check this beforehand). The commands
cd /usr/lib/arm-linux-gnueabihf/ ls -al libts* ls -al ts*
should not list any files. If you get some files listed create a backup directory in your home directory and move all the files to the backup directory. The following commands assume you are still in the directory /usr/lib/arm-linux-gnueabihf/:
mkdir /home/pi/uslib_backup sudo mv ./libts* /home/pi/lib_backup sudo mv ./ts0 /home/pi/lib_backup/
Now we are going to move the newly created library files and the “ts”-folder to the default library location:
cd /usr/local/lib sudo mv libts* /usr/lib/arm-linux-gnueabihf/ sudo mv ./ts /usr/lib/arm-linux-gnueabihf/
Next we need to create some symbolic links inside the /usr/lib/arm-linux-gnueabihf/ directory:
UPDATE: I had a typo in the ln -s line below. it has been corrected. It’s _not_ libts-0.0.ts.0, it needs to be libts-0.0.so.0!
cd /usr/lib/arm-linux-gnueabihf/ sudo ln -s libts-1.0.so.0 libts-0.0.so.0
Let’s check if all the links and files are there. Doing a
ls -al libts*
should give an output like this:
lrwxrwxrwx 1 root root 14 Jan 23 16:59 libts-0.0.so.0 -> libts-1.0.so.0 lrwxrwxrwx 1 root staff 18 Jan 23 16:17 libts-1.0.so.0 -> libts-1.0.so.0.0.0 -rwxr-xr-x 1 root staff 10721 Jan 23 16:17 libts-1.0.so.0.0.0 -rwxr-xr-x 1 root staff 930 Jan 23 16:17 libts.la lrwxrwxrwx 1 root staff 18 Jan 23 16:17 libts.so -> libts-1.0.so.0.0.0
Adjusting some boot parameters
Before trying to reboot it is a good thing to change /boot/config.txt slightly, so that video output goes through HDMI even if the screen is not auto-detected. And while being there, let’s change some values to make the screen more readable:
# For more options and information see # http://www.raspberrypi.org/documentation/configuration/config-txt.md # Some settings may impact device functionality. See link above for details # uncomment if you get no picture on HDMI for a default "safe" mode #hdmi_safe=1 # uncomment this if your display has a black border of unused pixels visible # and your display can output without overscan #disable_overscan=1 # uncomment the following to adjust overscan. Use positive numbers if console # goes off screen, and negative if there is too much border #overscan_left=16 #overscan_right=16 #overscan_top=16 #overscan_bottom=16 # uncomment to force a console size. By default it will be display's size minus # overscan. framebuffer_width=1024 framebuffer_height=600 hdmi_cvt=1024 600 60 3 0 0 0 # uncomment if hdmi display is not detected and composite is being output hdmi_force_hotplug=1 # uncomment to force a specific HDMI mode (this will force VGA) hdmi_group=2 hdmi_mode=87 # uncomment to force a HDMI mode rather than DVI. This can make audio work in # DMT (computer monitor) modes #hdmi_drive=2 # uncomment to increase signal to HDMI, if you have interference, blanking, or # no display #config_hdmi_boost=4 # uncomment for composite PAL #sdtv_mode=2 #uncomment to overclock the arm. 700 MHz is the default. #arm_freq=800
Now reboot and keep your finger crossed…
Final tweaks for libts
The touchscreen library needs some environment variables and a configuration file to work with. I am not going to add the whole set of environment variables into my .profile, instead I create a new file that is going to set those. After everything is working I just add a line to .profile that calls the file. This way I am able to quickly change variables without the need to fiddle with .profile every time.
The file I created is called touchvars and resides in my home directory. These are the entries:
export TSLIB_FBDEVICE=/dev/fb0 export TSLIB_CONSOLEDEVICE=none export TSLIB_TSDEVICE=/dev/input/by-id/`ls /dev/input/by-id/ | grep "Touch-event"` #export TSLIB_TSEVENTTYPE=INPUT export TSLIB_CONFFILE=/etc/ts.conf export TSLIB_CALIBFILE=/etc/pointercal export TSLIB_PLUGINDIR=/usr/lib/arm-linux-gnueabihf/ts export SDL_MOUSEDRV=TSLIB export SDL_MOUSEDEV=$TSLIB_TSDEVICE
Take a closer look at the third line. This line sets the variable for the touch-device. We could have hardcoded the event number but that may go wrong if you add other USB-devices that may be recognized by the kernel and get an event number that once has been the touchscreen’s event number. The part in the backwards apostrophe gets interpreted during execution, thus assuring that it will always fill in the correct event number.
To call this file and set the environment variables just enter
at the command prompt (replace touchvars with your filename). To have the variables set at login just add the above line to your .profile file.
The second file to be dealt with is the ts.conf file. It is referenced by the TSLIB_CONFFILE variable. As we did compile and build the library ourselves, this file most likely is located at /usr/local/etc/ts.conf. or we could just use the find-command to search the location:
sudo find / -name ts.conf
The file contents should look like this:
# Uncomment if you wish to use the linux input layer event interface module_raw input #module_raw galax # Uncomment if you're using a Sharp Zaurus SL-5500/SL-5000d # module_raw collie # Uncomment if you're using a Sharp Zaurus SL-C700/C750/C760/C860 # module_raw corgi # Uncomment if you're using a device with a UCB1200/1300/1400 TS interface # module_raw ucb1x00 # Uncomment if you're using an HP iPaq h3600 or similar # module_raw h3600 # Uncomment if you're using a Hitachi Webpad # module_raw mk712 # Uncomment if you're using an IBM Arctic II # module_raw arctic2 module pthres pmin=1 module variance delta=30 module dejitter delta=100 module linear
For reasons I do not understand libts does not work if the (allegedly) correct module_raw galax is uncommented. So the situation is as follows: The default libts without eGalax-support does not work with the touchscreen, the version with the eGalax-plugin works but one does not need to select the eGalax-plugin as the input module. If somebody is able to shed some light on this, please feel free to comment on this blog entry.
Calibrating and testing the touchscreen
Another important file is the calibration file, where the mapping between the touch coordinates and the actual screen coordinates is saved. This file is called pointercal and should be placed in /etc. To create the file just call
from the command prompt. The environment variables mentioned above need to be set first, you can check this with the printenv command. If, for any reason, the pointercal file is not created there most likely is a permission issue (the ts_calibrate binary can’t write the file in the location specified by TSLIB_CALIBFILE). There are two possible solutions: point TSLIB_CALIBFILE to a location you have writing permissions to or, second solution: temporarily point TSLIB_CALIBFILE to your home directory, run ts_calibrate and then copy or move the created pointercal file to /etc/.
That should be it. You now may run
and check if everything had been working out. Remember: If touch events do not get detected, check if the touch-event-Mouse is assigned event0. If that is the case, simply unplug the USB connector, wait a few seconds and replug the UBS connection. This works for me…
The above picture shows the output from ts_test. Touch coordinates are displayed and the draw function works.
and, of course, Adafruit’s excellent resources and learning system at https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi