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; } }