Interfacing with a touchscreen
Original Assignment
Interface the PIC with a surplus touchscreen from the LIMS lab and display (x,y) data on an LCD screen (see, e.g., C Example: Serial LCD or C Example: Parallel Interfacing with LCDs) or a PC (e.g., matlab or hyperterminal).
Spec sheet: [2] (Use the last .pdf under Reference Materials)
Overview
The goal of the project is to interface the PIC18F4520 with the 3M EX II 7720SC capacitive touchscreen. The spec sheet is located here: [3] (Use the last .pdf under Reference Materials). In addition, when a finger makes contact with the touchscreen, the X-Y coordinates will be displayed on a JHD 162A Parallel LCD (see C Example: Parallel Interfacing with LCDs).
There are many different types of touchscreen technologies. The one used below is a capacitive touchscreen. A capacitive touchscreen is usually coated in a charge storing material, such as indium tin oxide. Voltage is applied to each corner of the glass screen and electrodes are spread uniformly throughout the screen. Capacitive touchscreens are only responsive to finger touch which draw current from each side of the screen proportionally. The controller will then calculate the X-Y position of the finger from the current.
Advantages of the touchscreen are high touch resolution, high image clarity, and is not affected by dirt, grease, or moisture. However it can only be activated by the touch of something conductive, such as one's finger. [4]
On this page you will find the steps to implement the touchscreen interface on your own. This includes the code, circuit diagram, and other notes about creating the interface.
Circuit
The image on the right is the circuit schematic showing the connections between all the components. An actual picture of the circuit is also shown.
The chips required for implementing this circuit are:
1) PIC 18F4520
2) MAX232N Dual EIA-232 Driver/Receiver
3) EXII 7720SC (touchscreen controller chip)
4) JHD 162A Parallel LCD
The PIC communicates with the touchscreen through the MAX232N chip. The MAX232N chip regulates the voltage of the input(RXD pin 3) and output(TXD pin 2) of the EXII 7720SC touchscreen chip(between -5V and +5V) to make it between 0 and +5V, since this is the signal range that is accepted by the PIC.
The +5V supply voltages and ground in the circuit can be connected to PIC +5V and ground.
A 10K potentiometer is used to adjust the contrast of the LCD.
The LCD displays X and Y coordinates starting from X:0 Y:0 to about X:16383 Y:16383 (this is when all the bits of X and Y are 1: 0011 1111 1111 1111). This means the touchscreen has 14-bit resolution. The origin is at the bottom left of the touchscreen as oriented in the photo on the right.
Note: When wiring the touchscreen you have a couple of options. The first option is to buy the appropriate connecting cables for the EXII 7720SC chip to interface with a PIC. If this is not a feasible option then a second option would be to take spare rainbow ribbon cable and fashion your own connecting cable. This can be down with a wire stripper and soldering. The circuit pictured here is an example of the second option.
Experimental Notes
A vibration is felt when a finger is moved along the touchscreen. Since the finger activates the touchscreen by drawing current and acting as a capacitor, we think that the slight vibrations that are felt are due to the current being drawn through the finger.
When two fingers touch the screen at the same time, the output is the average of the two sets of coordinates. For example, if a finger is placed at X:0 Y:0 and another is placed on X: 16000 Y: 16000, the output is X: 8000 Y: 8000. We see the same behavior as we put more fingers on the screen at different locations; the output is the average of all the location coordinates. This can even be seen if only one finger is touching it; depending on how much of the finger is touching the screen, the output changes to get the center of the contact point.
The reason why a finger works to change the touchscreen output is because the finger exhibits capacitive qualities. The human body has charge that can draw current from the touchscreen. We suspect that other materials that can draw current, such as possibly a piece of fruit, might also work.
Code
The file "flex_lcd.c" is required in order for the PIC to communicate with the LCD. The code for the file can be found here: C Example: Parallel Interfacing with LCDs
The PIC first transmits a "Format Tablet" command to the touchscreen chip, which tells the touchscreen what to transmit back to the PIC. When a finger makes contact with the touchscreen, the chip sends back a 10-byte string of hex values with the X and Y coordinates embedded in the first 5 bytes. This 10-byte string is processed by the PIC, which extracts the X and Y coordinates, converts them to int16 format, and outputs the numbers to the LCD.
The format of each touch signal returned from the touchscreen controller can be found on Table 8 (page 27) of the EXII 7720SC spec sheet. The code takes bits 0-13 of the X and Y parts of the signal (X0 - X13 and Y0 - Y13) and combines them into int16 variables x_pos and y_pos, which are displayed on the LCD.
Remember to change the baud rate in the code to 9600 baud, since this is the rate used by the touchscreen chip.
/* touchscreen.c Chris Chow, Anup Tapase, Lingyu Xie Interface PIC with capacitive touchscreen and display X-Y coordinates on LCD Feb 12, 2009 */ #include <18f4520.h> #use delay(clock=40000000) #use rs232(baud=9600, UART1) // hardware UART; uses RC6/TX and RC7/RX #include "flex_lcd.c" //must include in order to output to LCD int j; int16 x_pos, y_pos; void get_screen_pos(int16& x_pos, int16& y_pos); void main() { lcd_init(); // Always call this first. //command Format Tablet: "<SOH>FT<CR>" sent to touchscreen via RC6/TX pin putc(0x01); putc(0x46); putc(0x54); putc(0x0D); while (TRUE) { //get the finger position relative to the touchscreen in 16-bit int format get_screen_pos(x_pos, y_pos); printf(lcd_putc,"\fX: %Lu\n",x_pos); //output "X: <x_pos>" to first line of LCD printf(lcd_putc,"Y: %Lu",y_pos); //output "Y: <y_pos>" to second line of LCD } } //Function adapted from Nick Marchuk's IR touchscreen code void get_screen_pos(int16& x_pos, int16& y_pos) { int i, gotD8, j; int touchscreen_rcx[20]; int pos[5]; int16 high16, low16, xtotal16, ytotal16; int temp4, total8; high16 = 0; low16 = 0; xtotal16 = 0; ytotal16 = 0; temp4 = 0; total8 = 0; //get 10 bytes from the touchscreen (each touch signal is 10 bytes) for (i=1;i<=10;++i) { touchscreen_rcx[i] = getc(); } //find the first instance of 0xD8 (start of each signal) gotD8 = 0; j = 1; while(gotD8==0) { if((touchscreen_rcx[j] == 0xD8)) { gotD8 = 1; //j is the location of 0xD8 } else { j = j+1; } if(j==9) { gotD8 = 1; //didnt find it, dont loop forever } } pos[1] = touchscreen_rcx[j+1]; //xlow, bits: 0 X6 X5 X4 X3 X2 X1 X0 (see touchscreen datasheet for FT response)) pos[2] = touchscreen_rcx[j+2]; //xhigh, bits: 0 X13 X12 X11 X10 X9 X8 X7 pos[3] = touchscreen_rcx[j+3]; //ylow, bits: 0 Y6 Y5 Y4 Y3 Y2 Y1 Y0 pos[4] = touchscreen_rcx[j+4]; //yhigh, bits: 0 Y13 Y12 Y11 Y10 Y9 Y8 Y7 //make the x temp4 = pos[2]; high16 = temp4; //make high16= 0000 0000 0X13X12X11 X10X9X8X7 low16 = pos[1]; //make low16= 0000 0000 0X6X5X4 X3X2X1X0 xtotal16 = low16|(high16<<7); //OR 00X13X12 X11X10X9X8 X7000 0000 with 0000 0000 0X6X5X4 X3X2X1X0 x_pos = xtotal16; //x_pos=00X13X12 X11X10X9X8 X7X6X5X4 X3X2X1X0 //make the y temp4 = pos[4]; high16 = temp4; //make high16= 0000 0000 0Y13Y12Y11 Y10Y9Y8Y7 low16 = pos[3]; //make low16= 0000 0000 0Y6Y5Y4 Y3Y2Y1Y0 ytotal16 = low16|(high16<<7); //OR 00Y13Y12 Y11Y10Y9Y8 Y7000 0000 with 0000 0000 0Y6Y5Y4 Y3Y2Y1Y0 y_pos = ytotal16; //x_pos=00Y13Y12 Y11Y10Y9Y8 Y7Y6Y5Y4 Y3Y2Y1Y0 }