Difference between revisions of "Interfacing with a touchscreen"

From Mech
Jump to navigationJump to search
Line 36: Line 36:


== Code ==
== Code ==
<pre>
#include <18f4520.h>
#DEVICE ADC=8
#device high_ints=TRUE
#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
}
}


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
}


</pre>


== Further Reading ==
== Further Reading ==

Revision as of 22:18, 9 February 2009

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: [1] (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: [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 capactive 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. Capactive 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. [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.

Circuit

Circuit schematic of connections between PIC, LCD, MAX232 and touchscreen

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 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.

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

#include <18f4520.h>
#DEVICE ADC=8
#device high_ints=TRUE
#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
   }
}


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
}


Further Reading