I recently bought a number of 5″ Touch Screen LCDs for the Raspberry Pi 2 from eBay. They were cheap knock-offs of a more popular brand name product, with little documentation, and broken English (hey their English is an order or two of magnitude better than my Chinese though) where there was some. The LCD displays use a chip called a XPT2046. This is a “compatible” (or read knock off) of the ADS7846 chip found in many touch screen devices. The drivers are compatible, thankfully, so we can enable them without too much pain.
As it turns out, if you’re using a recent version of Raspbian (i.e. version 7 with a kernel version north of 4.1.7 in my case), you can actually enable these units very easily. There are, however, some serious “gotchas” that you can stumble around for hours without finding a solution.
The first thing to keep in mind is that the native resolution of the LCD is NOT full HDMI, so if you try to put it through the LCD you’ll get something like:
As it turns out, this is not broken hardware at all, but just a configuration issue. Since the native resolution of these panels is 800×480, trying to push 1080p through it doesn’t really work very well. It can keep up for a portion of the dot clock cycle (the visible portions), but not the whole thing. This is easily corrected by editing the config.txt file.
In the case of the Windows 10 IoT (Internet of Things) distribution OR Raspbian 7, simply edit the configuration file in the EFI partition to reflect the below:
hdmi_cvt 800 480 60 6 0 0 0
Getting the touch screen working on Raspbian 7 is pretty easy, as well. Windows 10 IoT doesn’t currently have a driver (stay tuned here, I may be writing one if time allows).
Just add the below additional lines to the configuration file (in /boot/config.txt when Raspbian is running):
This tells the Linux kernel (at least as of version 4.1 and later), to use the ads7846 driver over the SPI bus to read touch screen coordinates. The penirq=25 line tells the driver to use GPIO pin 25 as the interrupt for a touch screen event. The penirq_pull=2 tells the driver to turn the pullup resistor on for the SPI bus, and xohms=150 tells the driver to use a baseline of 150 ohms (not the default 400) as the resistance for the resistive touch screen input. It’s also important to note that the default speed is way too fast for the XPT2046 chip (around 2 MHz, it can handle 1MHz on a good day), so we set it to 10000 (1 MHz).
The next part will require a small amount of ingenuity on your part. You’ll need to get the file “5inch_HDMI_LCD.tar.gz” from somewhere. If you search with Google, you should be able to find it easily enough. With this file, you can extract the archive file “xinput-calibrator_0.7.5-1_armhf.deb”. Install it with “dpkg -i xinput-calibrator_0.7.5-1_armhf.deb“.
This installs the graphical touch screen calibration tool for the 5″ LCD. Since we want to provide at least a baseline calibration, we add a directory at /etc/X11/xorg.conf.d and create a file named 99-calibration in that directory. The contents (as an example) would be:
MatchProduct “ADS7846 Touchscreen”
Option “Calibration” “129 3955 191 3946”
If you want to calibrate your display manually, you can simply log into the Raspberry Pi 2 on the console and issue the normal startx command. Then SSH into the Raspberry Pi 2, and run the command “DISPLAY=:0 xinput_calibrator”. You should get a screen that tells you to press the stylus to the crosshair. Once you’ve hit all four crosshairs, you are presented with a chunk of text that looks strikingly like the above 99-calibration file contents. Replace the /etc/X11/xorg.conf.d/99-calibration file’s contents with the output of the xinput_calibrator command and you should be in good shape.
Here’s what it looks like when things are happy-happy joy-joy:
A side note: The Windows 10 IoT distribution is rapidly becoming one of my favorite platforms to develop quick one-off applications on an Internet and GPIO enabled platform. It would be wonderful to have a Windows 10 IoT driver for the cheap XPT2046 based touch-screen controllers. I’m planning on writing a driver for this purpose if time permits (those who know me are laughing right now), so check back occasionally.
Hope this helps those of you who were facing the same issues I was. Feel free to comment or correct me on things if I made a mistake. 🙂
Awesome help! I got the screen working, however I cant get the touch portion to work. When it try to run display=:0 xinput_calibrator it states no calibratable devices found 🙁
Any help would be greatly appreciated!
Couldn’t get touch response to work until I changed penirq to 22 (instead of 25) in my /boot/config.txt
Excellent Work! i have the same display and it work now thanks!
But in my case the touchscreen seem to be “noisy”, the cursor is bit flicker and unstable under the pen.
Tried to play with xhoms in config.txt but whitout success.. any idea?
woot thanks a lot for the guide! been searching everywhere to activate the touchscreen!
however I’m using OpenElec atm and unable to go beyond editing config.txt. at least the touchscreen is responsive now, albeit it only remove my mouse cursor 😛
Great guide! I was able to get the screen to output correctly but having issues with touchscreen; not sure if its the actual unit or something i’m doing right. seems like touch does not register for me was there a particular distribution you used or possibly a certain driver you installed?
I have same screen.
Can you let me know if your driver for windows iot is compled. Do you have a release date for that ?
Thank you sir! Your instructions work perfectly on my xpt2046 screen with raspberry pi 2 model B+ running Debian Jessie. Awesome!
Wow, this is in every recpset what I needed to know.
Thank you! This post has been hugely helpful!
I can only add that xinput-calibrator is in Raspbian repository, so no need to hunt it down in the unruly lands of Internet.
Thank you very much, all works perfectly, the only and the best tutorial there is 🙂
Thank you very much sir.I was referring several articles to configure this for 2 weeks now.But with your guide I did it with less than hour.My gratitude!!
I thought I’d let you know your guide is being discussed at http://raspberrypi.stackexchange.com/q/41191/39319. I’m trying to follow your guide after striking out with http://www.circuitbasics.com/setup-lcd-touchscreen-raspberry-pi/
I have three simple questions:
1. Am I supposed to do something before this guide (e.g. enable SPI)? This guide doesn’t seem complete but I don’t know what it lacks (or assumes I have done already). Are you just explaining the gotchas?
2. We’re talking SPI over the GPIO pins, right? There are several mentions of HDMI in the post. Were the screens you’re using connecting via the HDMI port? If so then I’m really lost!
3. What do you mean by “the configuration file in the EFI partition”? Is that /boot/config.txt which you mention a bit later?
great work man.
BTW how looks windows driver? 🙂
Someone else beat me to the punch on this :-).
How did you get the screen working in windows 10 IOT?
I have a screen with the same controller but with a diferent screen… i have edited the config.txt but nothing is displayed on the screen …
I didn’t get the touch screen portion working with Windows 10 IoT. However, someone else did!
Hi, I’m thinking of buying this (or a similar) display.
Amazon is selling it under the “Makibes” brand: http://www.amazon.co.uk/Makibes-800%C3%97480-Resolution-Raspberry-Model/dp/B00YE0UPFW/
Some research led me to discover this is in fact a Waveshare LCD: http://www.waveshare.com/product/5inch-hdmi-lcd.htm
The waveshare site has two versions of the 5″ model available, one that connects the touch interface using the GPIO ports, and one that uses a micro-usb connection. On the rear side of the GPIO version, the “XPT2046” marking is visible, whereas on the microusb touch version it simply says “usb touch” on the back side. By counting the chips on the rear side, I’d say they look quite different, but who knows what’s placed on the top side of the board, under the LCD…
My question is whether the GPIO version (yours) works in Android on the Pi?
If not, any ideas if the microUSB touch would work better on Windows/Raspbian/Android?
An intlgeilent answer – no BS – which makes a pleasant change
Thank you for the information you provided.
I think I have the same screen and so far I only tested the display through HDMI cable (I have other settings on that matter).
I would be interested in wiring for getting the touch thing working. Is it as simple as wiring the MISO/MOSI/CLK and CS pins?
Hi Alex, I think it uses one additional GPIO pin (25) for select/clocking of some sort. I don’t have it in front of my right now, so I can’t say for certain. However, the data sheet for the touch screen controller should be here:
That seems to indicate that as long as you pipe in VCC/GND and the SPI bus connections, you’re in good shape. Give it a shot and let me know how it works :-).
Thanks for the post, the instructions worked perfectly for me.
I’m always glad to help! 🙂
Thank you for your valuable information. I am planning to us the Touch Screen with my Amateur Radio set up.
Glad to help. ’73s my friend 🙂
Hi, have you the pinout of this LCD? I want to connect this lcd to the RPI gpio with a cable. thanks a lot.
It should be a pretty simple thing to pass in terms of the 40 pin connector, and the HDMI. As long as you match them pin-for-pin, it should work just fine. 🙂
I tried the the procedure that your suggested and it worked. I downloaded the file from the below link.
Thank you for the file link! That looks like the right stuff!
Thanks for publishing this it helped me get my touchscreen working and calibrated!
FYI now you can run the following to setup xinput_calibrator:
sudo apt-get install xinput-calibrator
Awesome! Thank you for the information! 🙂
This is the most detailed review and step by step guide of how to install and properly use the XPT2046 touch screens. I am very thankfull for your efforts.
Having said that, i have one question. Besides the GPIO pin 25 and power pins, do you know what other pins the specific lcd screen and XPT2046 driver are occuping?. I am building a mobile rpi 3 and i ll use the pico ups (from pimodules) to power it. So i need to know which pins the lcd uses and which pins are free for the ups module.
Keep going with the good work.
Thanks for the complement, I’m glad I could help. I think that the other pins that are in use are either the SPI or I2C pins for communicating with the touch screen. Both of those are “shareable”, however. Since they are buses you can use many components on the bus as long as their address and chip select pins are different. Many I2C components don’t even need a chip select line, but rather, they react when data arrives that is addressed to them. (Much like ethernet in a network of computers.) The PicoUPS is a great find, by the way, I had to build my own RasPi UPS recently from a set of 18650 batteries, a 2S1P battery box, a charge regulator, and a buck/boost converter. Buying one is much easier in terms of time and engineering effort :-).
How fast is this thing? How quickly can it update a full screen change?
Is this good enough to use with a Raspberry Pi 3 to play games on or is it going to be terrible?
Did I just buy another useless display? That’s my question.
It’s quite fast. I suspect that you can push 30-60 frame/second since it’s using the HDMI interface on the Raspberry Pi 2/3. The touch screen is much less demanding in terms of updates, and even at 100 Khz (I2C speed in many cases), it will still update 20,000 times a second. That’s usually good enough for my reflexes :-).
Without the typos:
I wish I had found your blog sooner, I would have wasted a few less hours trying to get my 5 inch screen to work with a post 3.1 kernel raspian.
The key point is the compatibility with the ADS7846: instead of trying to use another driver, or to recompile a kernel with another driver, just use the one mentioned here.
I feel your pain! I too spend far too many hours fighting with lovely electronics that are poorly documented :-). Glad I could help you.
I am struggling to find the “5inch_HDMI_LCD.tar.gz”.
Found a similar one at waveshare. But not sure if its the one.
I have the display resolution adjusted and is working without touch.
How can I turn off the poer delivery from Pi?
Is there a way to dim the display using config.txt ?
Too many questions 🙂
I had a very jittery touch screen cursor and nearly impossible to calibrate on a RPi 3. Making the changes to speed and pullup fixed the problem.
Thanks for your time in documenting this setup
Always glad to help. 🙂
I got the 5″ HDMI touch lcd but I need this to work on Qualcom’s 805 snapdragon to work. the board is made by Inforce Computing and have the android 4.4.4 and 5.02. Please help me with getting this to work on that. Will you?
Hi Laszlo, the project you mention is a bit more complex than a simple bit of code to get it working. The unit I wrote about is specifically designed for the Raspberry Pi 2, and not for the board you are working with. There should be a LCD for the board you are using, but I’m not sure where to get it. Sorry I can’t be more help.
Thanks for the great post. I too have this very screen. I was able to calibrate it in the x environment, but once I load into retropie or kodi I loose all the calibration and I am unable to use the touchscreen. It seems to know when I touch the screen because the mouse cursor will disappear but still no movement. Are you aware of any non-x environment touch screen calibration drivers that work with retropie? In short, I want to run Kodi through retropie using the this awesome touchscreen but having all sorts of trouble!
Thank you, thank you, thank you.
Hi Neil, Sorry for the extreme lag, but I’ve been starting a new company, among other family things. I think this problem has been solved here: http://forum.kodi.tv/showthread.php?tid=222880
Apparently, Kodi has a different location that it keeps the calibration settings. If you see the segment of the above thread on evtest, it should point you in the right direction for getting Kodi working correctly.
Hello to all
I am trying in all ways to operate the touch screen with a Raspberry 3 Model B version 2 , but nothing to do none of it , I own 2 display the same I tried other things but nothing .
Someone who has solved could post the sequence . Thank you
Hello! Sorry, I haven’t tried it on the Pi 3, yet. When I do I’ll post how to get it working. Thanks!
Important: the file ’99-calibration’ in the ‘/etc/X11/xorg.conf.d’ directory needs to have a .conf extension in order to get read by the X window system on startup.
So the full, correct path to the file should be ‘/etc/X11/xorg.conf.d/99-calibration.conf’.
Great article, saved me lots of time. Thanks!
Hi Phork, I’m nearly ready to throw my 5″ touch LCD through the window…
Despite the reading of your great article i’m meeting a curious issue, the boot start normally but the screen becomes just like rubbish..
Could you please have a look at this video and if possible suggest a solution ?
Thanks in advance
I reinstall Raspbian 7 from the scratch and I finally succeed in using this touch screen, the only thing I’m missing now is a virtual keyboard, no doubt I will find a solution …
Thanks again for your good work !
Excellent! I’m glad you’ve got it working correctly. It’s a lovely screen :-).
Hello Jean-Marie, I’m not sure exactly what’s happening with your module, but it looks like there is something else trying to claim the SPI bus after X11 starts and is altering the registers on the LCD controller. I would try removing anything else that is trying to load in the X11 configuration (perhaps the touch screen controller?) and see if the visual artifacts go away. If they do disappear, you could have an address conflict on the SPI bus, or something more subtle. These are just guesses, mind you, and the actual problem could even be bad hardware (although it seems to boot just fine, and then lose coherence).
I’d like to join those who’ve thanked you and commented this was the best tutorial for getting this LCD tft working on our Raspberry Pi’s. To note, I have a Pi 3 B and had to remove the ‘6’ from this line in /boot/config.txt:
hdmi_cvt 800 480 60 6 0 0 0 = this is from above and didn’t change my screen size, leaving me about 1.5″ of black on the right side of my screen.
hdmi_cvt 800 480 60 0 0 0 = this did the trick to get full use.
Thanks again, and good luck with the new company!
Couldn’t get my touch response to work until I changed penirq to 22 (instead of 25) in /boot/config.txt