Touch screen become more and more popular. There are a few different technologies around (some of them allow multi-touch), this article deals with the 4-wire resistive touch technology. There are a couple of different screens in different sizes available and I decided to try out SparkFun's 4.3" PSP Touch Screen for $24. It is a good compromise between size and price and it is easy to connect to a bread board with SparkFun's 4.3" PSP Touch Screen Connector Breakout for $4.
SparkFun has also a great USB Touchscreen Mouse tutorial. Practical Arduino has a Touch Control Panel project.
![]() |
![]() |
| PSP Touch Screen Connector | ATmega168 | Arduino Pin # | Pin Configuration for Reading | ||||
| Pin # | Electrode | Breakout | Port # | Analog | Digital | Read X | Read Y |
| 1 | Top | Y1 | PC0 | 0 | 14 | Input: not used | Output: 1 (5V) |
| 2 | Right | X2 | PC1 | 1 | 15 | Output: 1 (5V) | Input: not used |
| 3 | Bottom | Y2 | PC2 | 2 | 16 | Input: used | Output: 0 (GND) |
| 4 | Left | X1 | PC3 | 3 | 17 | Output: 0 (GND) | Input: used |
All the code be downloaded from here.
The Arduino code is pretty easy. It sets the pin configuration for reading x and reads the voltage and then sets the configuration for reading y and reads the voltage. I found that it is important to wait for 1ms between setting up the configuration and the actual read:
/**
* TouchScreen_test
*
* Read position from a 4-wire resistive touch screen. More information at:
* https://larsi.org/electronics/TouchScreen/
*/
// the 4.3" PSP Touch Screen with Sparkfun's connector is connected like this
#define PIN_Y1 14 // analog input 0
#define PIN_X2 15 // analog input 1
#define PIN_Y2 16 // analog input 2
#define PIN_X1 17 // analog input 3
#define PIN_READX 2 // analog input 2
#define PIN_READY 3 // analog input 3
// stores the position from the touchscreen
int posX = 0;
int posY = 0;
void setup()
{
Serial.begin(115200);
}
void loop()
{
// configuration for reading the x value
pinMode(PIN_Y1, INPUT);
pinMode(PIN_Y2, INPUT);
pinMode(PIN_X1, OUTPUT);
digitalWrite(PIN_X1, LOW);
pinMode(PIN_X2, OUTPUT);
digitalWrite(PIN_X2, HIGH);
delay(1); // let things settle
posX = analogRead(PIN_READX); // read the X value
// configuration for reading the y value
pinMode(PIN_X1, INPUT);
pinMode(PIN_X2, INPUT);
pinMode(PIN_Y2, OUTPUT);
digitalWrite(PIN_Y2, LOW);
pinMode(PIN_Y1, OUTPUT);
digitalWrite(PIN_Y1, HIGH);
delay(1); // let things settle
posY = analogRead(PIN_READY); // read the Y value
// send position out over serial port
Serial.print(posX);
Serial.print(",");
Serial.println(posY);
delay(18); // wait 18ms (total 20ms)
}
The Processing code is just a simple demo. It reads the positions from the serial port and keps the last 256 vualues in a ring buffer. The draw() function just draws a circle for all the positions in the buffer.
/**
* TouchScreen_test
*
* visualize the position returned from the Arduino interface
*/
import processing.serial.*;
Serial port;
static final private int LINE_FEED = 10;
static final private int COUNT = 256;
// setup vals from serial
int[] posX = new int[COUNT];
int[] posY = new int[COUNT];
int index = 0;
void setup()
{
size(960, 540, P2D);
background(0);
ellipseMode(CENTER);
println("Available serial ports:");
println(Serial.list());
port = new Serial(this, Serial.list()[1], 115200);
// clear and wait for linefeed
port.clear();
port.bufferUntil(LINE_FEED);
}
void draw()
{
background(0xFFFFFFFF);
fill(0xFF336699);
stroke(0xFF000000);
for (int i = 0; i < COUNT; i++)
ellipse(map(posX[i], 0, 1023, 0, width - 1), map(posY[i], 0, 1023, height - 1, 0), 10, 10);
}
// handle serial data
void serialEvent(Serial p)
{
String data = trim(p.readStringUntil(LINE_FEED));
if (data != null) {
String[] data_split = split(data, ',');
posX[index] = int(data_split[0]);
posY[index] = int(data_split[1]);
index = (index + 1) % COUNT;
}
}