Difference between revisions of "Interfacing with a touchscreen"
Lingyu Xie (talk | contribs) m (→Overview) |
|||
(39 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
== 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: [http://solutions.3m.com/wps/portal/3M/en_US/3MTouchSystems/TS/Solutions/Electronics/EXII-Controller/] |
|||
(Use the last .pdf under Reference Materials) |
|||
== Overview == |
== Overview == |
||
[[image:touchscreen|thumb|200px|How a touchscreen works [http://www.touchscreenguide.com/]|right]] |
[[image:touchscreen|thumb|200px|How a touchscreen works [http://www.touchscreenguide.com/]|right]] |
||
Line 11: | Line 4: | ||
The goal of the project is to interface the PIC18F4520 with the 3M EX II 7720SC capacitive touchscreen. The spec sheet is located here: [http://solutions.3m.com/wps/portal/3M/en_US/3MTouchSystems/TS/Solutions/Electronics/EXII-Controller/] (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]]). |
The goal of the project is to interface the PIC18F4520 with the 3M EX II 7720SC capacitive touchscreen. The spec sheet is located here: [http://solutions.3m.com/wps/portal/3M/en_US/3MTouchSystems/TS/Solutions/Electronics/EXII-Controller/] (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 |
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. 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. [http://www.touchscreens.com/intro-touchtypes-capacitive.html] |
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. [http://www.touchscreens.com/intro-touchtypes-capacitive.html] |
||
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. |
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. If you build the circuit as displayed below and run the program through the PIC, you should be able to display on an LCD a finger's X-Y position on the touchscreen. |
||
< |
<br><br><br><br><br> |
||
== Circuit == |
== Circuit == |
||
[[image:lcd_circuit|thumb|300px|Circuit schematic of connections between PIC, LCD, MAX232 and touchscreen|right]] |
[[image:lcd_circuit|thumb|300px|Circuit schematic of connections between PIC, LCD, MAX232 and touchscreen|right]] |
||
[[image:photo_lcd_circuit|thumb|300px|Photo of circuit|right]] |
|||
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 image on the right is the circuit schematic showing the connections between all the components. An actual picture of the circuit is also shown. |
||
Line 30: | Line 24: | ||
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 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 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 +5V supply voltages and ground in the circuit can be connected to PIC +5V and ground. |
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. |
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. |
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. |
||
<br><br><br><br><br><br><br><br><br><br> |
|||
== Code == |
== 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 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. |
|||
Remmeber to change the baud rate in the code to 9600 baud, since this is the rate used by the touchscreen chip. |
|||
The format of each touch signal returned from the touchscreen controller can be found on Table 8 (page 27) of the [http://multimedia.mmm.com/mws/mediawebserver.dyn?6666660Zjcf6lVs6EVs66SBhjCOrrrrQ-| 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. |
|||
<pre> |
<pre> |
||
/* |
|||
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> |
#include <18f4520.h> |
||
#DEVICE ADC=8 |
|||
#device high_ints=TRUE |
|||
#use delay(clock=40000000) |
#use delay(clock=40000000) |
||
#use rs232(baud=9600, UART1) // hardware UART; uses RC6/TX and RC7/RX |
#use rs232(baud=9600, UART1) // hardware UART; uses RC6/TX and RC7/RX |
||
Line 78: | Line 84: | ||
} |
} |
||
// |
//Function adapted from Nick Marchuk's IR touchscreen code |
||
void get_screen_pos(int16& x_pos, int16& y_pos) |
void get_screen_pos(int16& x_pos, int16& y_pos) |
||
{ |
{ |
||
Line 141: | Line 147: | ||
} |
} |
||
</pre> |
|||
== 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 with the touchscreen is that the finger exhibits capacitive qualities. The human body has charge that can draw current from the touchscreen. When someone touches the screen some of the charge on the surface is transferred to the person creating a drop in the charge on the screen. The relative difference in charge from each of the corners of the screen is calculated and a location is the output. We suspect that other materials that can draw current, such as a piece of fruit, might also work.[http://computer.howstuffworks.com/question716.htm] |
|||
== Additional Code == |
|||
The following code was developed as an extension to this project. It uses a very similar circuit, although there is another set of rs232 pins to communicate with the computer. It is also interrupt driven on the Rx UART1 pin and uses a LIFO circular input buffer. |
|||
<pre> |
|||
//3M Touchscreen Code |
|||
//Jake Ware |
|||
//10/9/09 |
|||
#include <18f4520.h> |
|||
#use delay(clock=20000000) |
|||
#use rs232(baud=9600, STREAM=TS, UART1, PARITY=N, BITS=8, STOP=1) |
|||
#use rs232(baud=9600, STREAM=PC, XMIT=PIN_B0, RCV=PIN_B1, PARITY=N, BITS=8, STOP=1, DISABLE_INTS) |
|||
#define LED_0 PIN_D0 |
|||
#define LED_1 PIN_D1 |
|||
unsigned int16 read = 0, write = 0; |
|||
int position[10]; |
|||
int buffer[10]; |
|||
int16 x_pos, y_pos; |
|||
void compute_pos(int16& x_pos, int16& y_pos); |
|||
#INT_RDA |
|||
void rs232_handler() |
|||
{ |
|||
output_high(LED_0); |
|||
buffer[read%10] = fgetc(TS); |
|||
read++; |
|||
output_low(LED_0); |
|||
} |
|||
//Main Program |
|||
void main() |
|||
{ |
|||
//start sequence |
|||
fprintf(PC, "Program Start\r\n"); |
|||
//Set Touch Screen Controller Communication Format: "<SOH>PN812<CR>" (Parity = N, Bit = 8, Stop = 1, Baud = 9600) |
|||
fputc(0x01, TS); |
|||
fputc(0x50, TS); |
|||
fputc(0x4e, TS); |
|||
fputc(0x38, TS); |
|||
fputc(0x31, TS); |
|||
fputc(0x32, TS); |
|||
fputc(0x0D, TS); |
|||
//command Format Tablet: "<SOH>FT<CR>" sent to touchscreen via RC6/TX pin |
|||
fputc(0x01, TS); |
|||
fputc(0x46, TS); |
|||
fputc(0x54, TS); |
|||
fputc(0x0D, TS); |
|||
enable_interrupts(INT_RDA); |
|||
enable_interrupts(GLOBAL); |
|||
output_high(LED_0); |
|||
delay_ms(25); |
|||
output_low(LED_0); |
|||
while (TRUE) |
|||
{ |
|||
if(kbhit(TS)) { |
|||
output_high(LED_1); |
|||
//get the finger position relative to the touchscreen in 16-bit int format |
|||
compute_pos(x_pos, y_pos); |
|||
if(x_pos < 1024 && y_pos < 1024) { |
|||
fprintf(PC, "%Ld:%Ld\n", x_pos, y_pos); |
|||
// fprintf(PC, "\r\n%Lu||%Lu\r\n", read, write); |
|||
} |
|||
} else { |
|||
output_low(LED_1); |
|||
} |
|||
} |
|||
} |
|||
//Function adapted from Nick Marchuk's IR touchscreen code |
|||
void compute_pos(int16& x_pos, int16& y_pos) |
|||
{ |
|||
int i = 0, flag_D8 = 0, loc_D8 = 0; |
|||
int pos[5]; |
|||
int16 high = 0, low = 0, total; |
|||
// fprintf(PC, "\r\n\n//////Loop Start//////"); |
|||
while(flag_D8 == 0) |
|||
{ |
|||
//get 10 bytes from the touchscreen (each touch signal is 5 bytes) |
|||
for (i=0; i<10; i++) { |
|||
position[i] = buffer[(((read+1)%10)+i)%10]; |
|||
write++; |
|||
} |
|||
//find the first instance of 0xD8 (start of each signal) and then break out of loop |
|||
for(i=0; i<6; i++) { |
|||
if((position[i] == 0xD8)) { |
|||
loc_D8 = i; //i is the location of 0xD8 |
|||
flag_D8 = 1; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
// fprintf(PC, "\r\nloc_D8 = %d", loc_D8); |
|||
pos[0] = position[loc_D8]; |
|||
pos[1] = position[loc_D8+1]; //xlow, bits: 0 X6 X5 X4 X3 X2 X1 X0 (see touchscreen datasheet for FT response)) |
|||
pos[2] = position[loc_D8+2]; //xhigh, bits: 0 X13 X12 X11 X10 X9 X8 X7 |
|||
pos[3] = position[loc_D8+3]; //ylow, bits: 0 Y6 Y5 Y4 Y3 Y2 Y1 Y0 |
|||
pos[4] = position[loc_D8+4]; //yhigh, bits: 0 Y13 Y12 Y11 Y10 Y9 Y8 Y7 |
|||
// fprintf(PC, "\r\npos[i]=[%x, %x, %x, %x, %x]", pos[0], pos[1], pos[2], pos[3], pos[4]); |
|||
//make the x |
|||
total = 0; |
|||
high = pos[1]; //make low16= 0000 0000 0X6X5X4 X3X2X1X0 |
|||
low = pos[2]; //make high16= 0000 0000 0X13X12X11 X10X9X8X7 |
|||
total = (low << 8)|high; //OR 00X13X12 X11X10X9X8 X7000 0000 with 0000 0000 0X6X5X4 X3X2X1X0 |
|||
x_pos = total/32; //x_pos=00X13X12 X11X10X9X8 X7X6X5X4 X3X2X1X0 |
|||
/* |
|||
fprintf(PC, "\r\n\nMaking X:"); |
|||
fprintf(PC, "\r\nhigh = %Lx", high); |
|||
fprintf(PC, "\r\nlow = %Lx", low); |
|||
fprintf(PC, "\r\ntotal = %Lx", total); |
|||
*/ |
|||
//make the y |
|||
total = 0; |
|||
high = pos[3]; //make low16= 0000 0000 0Y6Y5Y4 Y3Y2Y1Y0 |
|||
low = pos[4]; //make high16= 0000 0000 0Y13Y12Y11 Y10Y9Y8Y7 |
|||
total = (low << 8)|high; //OR 00Y13Y12 Y11Y10Y9Y8 0000 0000 with 0000 0000 0Y6Y5Y4 Y3Y2Y1Y0 |
|||
y_pos = total/32; //x_pos=00Y13Y12 Y11Y10Y9Y8 Y7Y6Y5Y4 Y3Y2Y1Y0 |
|||
/* |
|||
fprintf(PC, "\r\n\nMaking Y:"); |
|||
fprintf(PC, "\r\nhigh = %Lx", high); |
|||
fprintf(PC, "\r\nlow = %Lx", low); |
|||
fprintf(PC, "\r\ntotal = %Lx", total); |
|||
*/ |
|||
} |
|||
</pre> |
</pre> |
Latest revision as of 10:10, 9 October 2009
Overview
![](/images/thumb/5/58/Touchscreen/200px-Touchscreen.jpeg)
The goal of the project is to interface the PIC18F4520 with the 3M EX II 7720SC capacitive touchscreen. The spec sheet is located here: [2] (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. 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. [3]
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. If you build the circuit as displayed below and run the program through the PIC, you should be able to display on an LCD a finger's X-Y position on the touchscreen.
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.
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 }
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 with the touchscreen is that the finger exhibits capacitive qualities. The human body has charge that can draw current from the touchscreen. When someone touches the screen some of the charge on the surface is transferred to the person creating a drop in the charge on the screen. The relative difference in charge from each of the corners of the screen is calculated and a location is the output. We suspect that other materials that can draw current, such as a piece of fruit, might also work.[4]
Additional Code
The following code was developed as an extension to this project. It uses a very similar circuit, although there is another set of rs232 pins to communicate with the computer. It is also interrupt driven on the Rx UART1 pin and uses a LIFO circular input buffer.
//3M Touchscreen Code //Jake Ware //10/9/09 #include <18f4520.h> #use delay(clock=20000000) #use rs232(baud=9600, STREAM=TS, UART1, PARITY=N, BITS=8, STOP=1) #use rs232(baud=9600, STREAM=PC, XMIT=PIN_B0, RCV=PIN_B1, PARITY=N, BITS=8, STOP=1, DISABLE_INTS) #define LED_0 PIN_D0 #define LED_1 PIN_D1 unsigned int16 read = 0, write = 0; int position[10]; int buffer[10]; int16 x_pos, y_pos; void compute_pos(int16& x_pos, int16& y_pos); #INT_RDA void rs232_handler() { output_high(LED_0); buffer[read%10] = fgetc(TS); read++; output_low(LED_0); } //Main Program void main() { //start sequence fprintf(PC, "Program Start\r\n"); //Set Touch Screen Controller Communication Format: "<SOH>PN812<CR>" (Parity = N, Bit = 8, Stop = 1, Baud = 9600) fputc(0x01, TS); fputc(0x50, TS); fputc(0x4e, TS); fputc(0x38, TS); fputc(0x31, TS); fputc(0x32, TS); fputc(0x0D, TS); //command Format Tablet: "<SOH>FT<CR>" sent to touchscreen via RC6/TX pin fputc(0x01, TS); fputc(0x46, TS); fputc(0x54, TS); fputc(0x0D, TS); enable_interrupts(INT_RDA); enable_interrupts(GLOBAL); output_high(LED_0); delay_ms(25); output_low(LED_0); while (TRUE) { if(kbhit(TS)) { output_high(LED_1); //get the finger position relative to the touchscreen in 16-bit int format compute_pos(x_pos, y_pos); if(x_pos < 1024 && y_pos < 1024) { fprintf(PC, "%Ld:%Ld\n", x_pos, y_pos); // fprintf(PC, "\r\n%Lu||%Lu\r\n", read, write); } } else { output_low(LED_1); } } } //Function adapted from Nick Marchuk's IR touchscreen code void compute_pos(int16& x_pos, int16& y_pos) { int i = 0, flag_D8 = 0, loc_D8 = 0; int pos[5]; int16 high = 0, low = 0, total; // fprintf(PC, "\r\n\n//////Loop Start//////"); while(flag_D8 == 0) { //get 10 bytes from the touchscreen (each touch signal is 5 bytes) for (i=0; i<10; i++) { position[i] = buffer[(((read+1)%10)+i)%10]; write++; } //find the first instance of 0xD8 (start of each signal) and then break out of loop for(i=0; i<6; i++) { if((position[i] == 0xD8)) { loc_D8 = i; //i is the location of 0xD8 flag_D8 = 1; break; } } } // fprintf(PC, "\r\nloc_D8 = %d", loc_D8); pos[0] = position[loc_D8]; pos[1] = position[loc_D8+1]; //xlow, bits: 0 X6 X5 X4 X3 X2 X1 X0 (see touchscreen datasheet for FT response)) pos[2] = position[loc_D8+2]; //xhigh, bits: 0 X13 X12 X11 X10 X9 X8 X7 pos[3] = position[loc_D8+3]; //ylow, bits: 0 Y6 Y5 Y4 Y3 Y2 Y1 Y0 pos[4] = position[loc_D8+4]; //yhigh, bits: 0 Y13 Y12 Y11 Y10 Y9 Y8 Y7 // fprintf(PC, "\r\npos[i]=[%x, %x, %x, %x, %x]", pos[0], pos[1], pos[2], pos[3], pos[4]); //make the x total = 0; high = pos[1]; //make low16= 0000 0000 0X6X5X4 X3X2X1X0 low = pos[2]; //make high16= 0000 0000 0X13X12X11 X10X9X8X7 total = (low << 8)|high; //OR 00X13X12 X11X10X9X8 X7000 0000 with 0000 0000 0X6X5X4 X3X2X1X0 x_pos = total/32; //x_pos=00X13X12 X11X10X9X8 X7X6X5X4 X3X2X1X0 /* fprintf(PC, "\r\n\nMaking X:"); fprintf(PC, "\r\nhigh = %Lx", high); fprintf(PC, "\r\nlow = %Lx", low); fprintf(PC, "\r\ntotal = %Lx", total); */ //make the y total = 0; high = pos[3]; //make low16= 0000 0000 0Y6Y5Y4 Y3Y2Y1Y0 low = pos[4]; //make high16= 0000 0000 0Y13Y12Y11 Y10Y9Y8Y7 total = (low << 8)|high; //OR 00Y13Y12 Y11Y10Y9Y8 0000 0000 with 0000 0000 0Y6Y5Y4 Y3Y2Y1Y0 y_pos = total/32; //x_pos=00Y13Y12 Y11Y10Y9Y8 Y7Y6Y5Y4 Y3Y2Y1Y0 /* fprintf(PC, "\r\n\nMaking Y:"); fprintf(PC, "\r\nhigh = %Lx", high); fprintf(PC, "\r\nlow = %Lx", low); fprintf(PC, "\r\ntotal = %Lx", total); */ }