Touch screens are a great way to provide an intuitive and powerful interface for your project. Resistive touch screens, while not as versatile as capacitive touch, are extremely simple and cheap.
Furthermore, they're not as quirky as capacitive touch screens, like the one on your phone. Because capacitive touch screens use the conductivity of your blood to tell where your finger is, they won't work well if there is other conductive stuff touching them. I keep my phone in a water-proof case, but when it rains, the screen gets wet and can't tell the difference between my finger and the water! Resistive touch screens use pressure, instead of conductivity, so they're not susceptible to this problem.
In this project, I'm going to show you how to get a 4-wire resistive touch screen up and running, using my DP32.
Let's get started!
For more things that I've done, you can check out my profile page!
For more info from Digilent or the Digilent Makerspace, check out the Digilent blog!
While you're there, consider signing up for the Digilent newsletter!
Step 1: What You'll Need
This tutorial is pretty minimal. The only things you'll need are:
- A 4-wire, resistive touch screen.
- A marker of some sort.
- A stylus of some sort.
- A microcontroller of some sort. (I'm using the DP32, as usual.)
Step 2: How It Works
Before we get into this tutorial, it's helpful to know some of the theory behind resistive touch screens.
This style of touch screen uses two conductive layers, separated by a layer of air*. The top layer is flexible, so when your finger touches the screen, it bends down to make contact with the bottom layer.
Along two sides of both layers is a metal strip. One layer will have it's strips along the top and bottom, while the other has it along the right and left. We can use these contacts to charge one layer, while the other is used as a sensor.
Check out the first picture above. By raising the right-hand contact to a high voltage, and bringing the other side low, we create a voltage gradient across the bottom layer. Then, we can connect the top layer to an analog sensor on our board. By measuring the voltage, we know how far along the X axis our contact point is!
In the second picture, we change our inputs and outputs, so that we create a voltage gradient along the Y axis, and use the bottom layer as the sensor.
* For the curious, they're kept separate by very small, non-conductive spacers.
Step 3: Wiring
My wiring for this project is as follows:
- Pin 1, upper layer, right side: pin 0/RB5
- Pin 2, lower layer, top side: pin 1/RB7
- Pin 3, upper layer, left side: pin 6/RB13/A0
- Pin 4, lower layer, bottom side: pin 7/RB14/A1
This way, both layers have one analog pin and one digital pin connected to them. Let's say I wanted to set a gradiant across the bottom layer, and use the top layer to read. In that case, I would set both Pin 1 and Pin 7/A1 to digital outputs. Then I would set Pin 1 high, and Pin 7 low. That creates our gradient.
In order to use the top layer to read, I would set both Pin 0 and Pin 7/A1 to input pins, and use Pin 7/A1 to read the voltage of the top layer.
But wait, if I'm only using Pin 7/A1 to read, why do I need to set Pin 0 to input as well? I had to figure this out the hard way. If you leave Pin 0 as a digital output, it'll be tied to either ground or VDD. That creates some very strange readings for Pin 7/A1.
Conversely, when you're using the bottom layer to read, you need to remember to set both Pin 0 and Pin 6/A0 to inputs for the same reason.
Step 4: The Calibration Sketch
Go ahead download the sketch attached to this step. We're going to use this to calibrate our touch screen!
The code is pretty simple. All it does is measure the X and Y voltage (using the methods explained previously) and output those measurements directly to serial. That will let us customize an equation to calibrate our touch screen!
Step 5: Taking Calibration Measurements
After uploading the calibration sketch, open serial monitor.
Use your stylus to touch one of the corners of the screen, then press button 1 on the DP32. You should see a pair of numbers appear on the first line of the serial monitor, these are the X and Y measurements of your stylus' position.
Do this for every corner, and you will get something like the last picture in this step. We will use these measurements to figure out which corner of the screen is the origin, and how we can convert these measurements into something more useful.
Step 6: Marking Your Axis
If, while you take your measurements, you pay attention to which corner gives you the smallest values, you can mark that on your board. I used a permanent marker because my board still has its protective covering on (plus you can remove permanent ink with dry erase ink).
I should also point out that your X and Y won't always be ordered correctly by the measurement sketch. In my case, my Y measurement happened to be the first number, and my X was the second. Keep that in mind while taking your measurements, as you may need to switch their order later (like I did).
Step 7: Quadrilateral Correction Method
I took those measurements and put them into a graph. Notice how the box created by each corner isn't actually square? Our calibration equations will not only square off the points we get, but also scale them to our touch-screen's actual size.
To understand, let's look at the second picture in this step. We're going to start by correcting the Y axis. To do this, we create two linear functions (f1 and f2) based off the lower and upper pair of points (respectively). We use these to find a third function for the vertical distance between them.
Thus, our correction for our Y axis becomes
Y_correct = [Y_measured - f1(X_measured)] / f3(X_measured)
Now, check out the third picture in this step. When we make a correction equation for the X axis, those equations are functions of Y, but they're essentially the same concept with the axis flipped.
This is a very simple correction method, but it makes some assumptions so it won't be as accurate as a more complex method. In the future I'd like to make a tutorial that uses a more accurate method, but for now this will do.
I won't go through the algebra for this step because it's so basic, but I will go through my example calculations for f_1 through f_3.
I'm going to use the following notation:
- a: slope
- b: offset
- a_1: slope for function 1
- a_2: slope for function 2
And the calculations for my points go like this:
- f_1(x) = a_1*x + b_1
- a_1 = (219 - 200) / (913 - 80) = 0.02281
- b_1 = 200 - 80 * a_1 = 198.2
- a_2 = (910 - 903) / (915 - 68) = 0.008264
- b_2 = 903 - 68 * a_2 = 902.4
- a_3 = a_2 - a_1 = -0.01455
- b_3 = b_2 - b_1 = 704.2
Which give me these functions:
- f_1(x) = 0.02281*x + 198.2
- f_3(x) = -0.01455*x + 704.2
(Note that we don't need f_3 at this point. We only needed it to find f_3.)
Finally, we can plug those functions into our correction equation for the Y axis!
- Y_correct = [Y_measured - (0.02281*X_measured + 198.2)] / [0.01455*X_measured + 704.2]
And the correction equation for our X axis turns out to be:
- X_correct = [X_measured - (-0.01707*Y_measured + 83.41)] / [0.01996*Y_measured + 829.0]
- a_4 = -0.01707
- b_4 = 83.41
- a_6 = 0.01996
- b_6 = 829.0
Keep in mind, of course, that your values will be different from mine.
Step 8: The Corrected_Read Sketch
Download and open the Corrected_Read sketch attached to this step. Up at the top is a section of code defining some constants for each of your "a" and "b" values. You can see in the picture that I've highlighted them. Go ahead and change these to your values.
Below that, you can also see two constants: C_x and C_y. These are the width and height of your touch panel, in the x and y directions! Mine just happened to be about 12.5 cm by 16.5 cm. You should measure your screen, and change these values to match! You can even use inches if you want.
Step 9: Test It Out!
Upload the code to your board and try it out!
When you press button 1 on the DP32, the code will send the corrected coordinates to your serial monitor, just like before, only this time they should be scaled to your touch screen!
I should warn you though, because we used such a simple correction method, there will be some error. I've gotten error as large as a full centimeter in the middle of the screen!
In the future, I hope to put out a tutorial that uses a more complex correction algorithm, but for any application that doesn't need extreme precision, this should do!