Thursday, April 21, 2011

Interfacing Touch Screen with microcontroller

Please Read : This article was posted by me a long time ago, I am not able to monitor the comments regularly. So, if you need my help regarding any article, please write to me at dmehta17@gmail.com . I will try to answer the queries as quickly as possible.  Also, please don't ask me for the code for any other controller except LPC2148, because I only have code for that controller. For any other controller, you will have to develop the code on your own based on the algorithm explained here. If you've created such code, I request you to share it with me via e-mail. I will publish it here with full credits to its original author.

--------------------------------------------------------------------------------------------------------------

I've always wanted to add something new to my projects. That's why in the 7th semester, when I saw a touch screen just lying in my college, I decided to go for it. Touch screens add an X-factor to otherwise ordinary projects. They are fun to use and more important, their applications are endless. In this article, I will explain how to interface a 4-wire resistive touch screen with microrocntrollers.

Resistive Touch Screens
Of all the kinds of touch screens available, Resistive touch screens are easy to interface, cheap and they have fair sensitivity.Resistive Touch screens are simply transducers. This touch screen has a resistive layers in both X and Y directions. According to the position of the touch, Their X channel and Y channel resistance changes. So, what we have to do is we have to determine the X and Y Channel resistance to get the position of the touch in terms of X and Y co-ordinates.
Here is an Image of simple resistive touch screen. 
 How To Interface Touch Screen with Microcontroller
To Interface Resistive touch screen with a microcontroller, you will need a microcontroller with inbuilt Analog-to-Digital converter having two or more channels. This is needed because, the touch screen will provide data in terms of an analog voltage on two different pins, using which, we have to determine position of the touch. Also, ADC input pins of the microcontroller should be configurable as General Purpose I/O (GPIO). As shown, in the figure, the touch screen has total of 4 wires coming out. Pin configuration is shown in the fig. To read the position of the touch, we have to first read touch position sequentially i.e. first read X position and then read the Y position. To do this, connect X1 and Y2 pins of touch screen to ADC multiplexed GPIO pins of the controller. And connect X2 and Y1 pins of touch screen to simple GPIO pins of the microcontroller.  


 
 
  
Now first, we have to read X position of the touch, for that, u have to program the pin X1 as Logic high (+5v or +3.3v in some cases) and configure pin X2 as logic low (GND). Now, as I told earlier, touch screen contains a resistive layer in both direction. So, when we apply +5v and GND to its pins, it will create a voltage gradient in X direction. Voltage on the X channel will vary according to the X position of the touch. We have to measure this voltage to determine the X position.For that, configure Y2 as ADC input and configure Y1 to high impedance state (in most controller, configuring Y1 as "Input" will work). Then read the value from the ADC. It will give the relative value of the touch. For example, if you have an 8-bit ADC in the controller, when you touch near the right most end, it will give you a value of 255 and when you touch near the left most end, it will give you a value near 0. After reading X position, you will have to read the Y position. For that, configure Y2 as Logic High, Y2 as Logic Low, and X1 as ADC input and X2 as High Impedance state. After that, whole procedure is the same. 


This way, you can interface touch screens with microcontrollers and add something new to your projects. I made a "Touch Screen Calculator" using the LPC2148 microcontroller. Below is the video of the Touch screen Calculator in action. If you need any help regarding this or have any suggestion/feedback, then write a comment here or mail me at dmehta17@gmail.com or you can connect with me on facebook at "http://www.facebook.com/damehta"


 


Here is the 'C' code I've created for reading X and Y positions from the touch screen. The code is for Phillips LPC2148 controller.I've crated two functions : "xcoordinate" and "ycoordinate".When called, functions wait for a touch and when touch screen is touched, returns X and Y co-ordinate respectively.

int xcoordinate(void)
{
 int x;
 PINSEL0 = (PINSEL0 & 0x3FFF3FF0) | 0x00000005; // Configure pins for touch screen
 PINSEL1 = (PINSEL1 & 0xC3FFFFFF) | 0x10000000;
 IO0DIR =  (IO0DIR &  0xDFFF7F7F) | 0x00008080;

 IO0SET = IO0SET | 0x00000080;     // Set pin to '1'
 IO0CLR = IO0CLR | 0x00008000;    // Set pin to '0'

 AD0CR = ( AD0CR & 0xFFD00000 ) | 0x00200208 ;  // Start the ADC

 while(1)
 {
   delayms(10);
   AD0CR = ( AD0CR & 0xF8FFFFFF ) | 0x01000000 ;

 xchkadc:

   x = AD0DR3 & 0x80000000 ;

   if(x == 0x80000000)  // Check if A-D conversion is complete
    {
     
      x = 0x00000000;
      x = AD0DR3 & 0x0000FFC0;
      x = x >> 6;
      x = x & 0x000003FF;
      if(x <= 10)
      {
        goto xexit;
      }
     
      AD0CR = AD0CR & 0xF8FFFFFF;
      return x;     // return the value of touch in x direction
     
    }

   goto xchkadc;

  xexit:  
  AD0CR = AD0CR & 0xF8FFFFFF;  
  }
  return 0;
}

int ycoordinate(void)
{
 int y;

 PINSEL0 = (PINSEL0 & 0x3FFF3FF0) | 0xC0000005;    // Configure pins for touch screen
 PINSEL1 = (PINSEL1 & 0xC3FFFFFF) | 0x00000000;

 IO0DIR = (IO0DIR & 0x9FFFFF7F) | 0x60000000;

 IO0SET = IO0SET | 0x40000000;    //// Set pin to '1'
 IO0CLR = IO0CLR | 0x20000000;    //// Set pin to '0'

 AD1CR = (AD1CR & 0xF0D00000) | 0x00200220 ;    //// Start the ADC

 while(1)
 {

  delayms(10);
  AD1CR = ( AD1CR & 0xF8FFFFFF ) | 0x01000000 ;

   ychkadc:

   y = AD1DR5 & 0x80000000 ;

   if(y == 0x80000000)    // Check if A-D conversion is complete
    {
     
      y = 0x00000000;
      y = AD1DR5 & 0x0000FFC0;
      y = y >> 6;
      y = y & 0x000003FF;
      if(y <= 10)
      {
        goto yexit1;
      }
     
      AD1CR = AD1CR & 0xF8FFFFFF;
      return y;            // return the value of touch in y direction
     
    }

   goto ychkadc;

   yexit1:
  
    AD1CR = AD1CR & 0xF8FFFFFF;
  }

 return 0;
}