Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ResistiveTouchScreen

A lightweight, fast library for reading standard 4-wire resistive touch panels using nothing more than the standard Arduino Framework pin functions.

The library is designed to be portable across Arduino Framework compatible platforms while still providing enough configurability to achieve fast, reliable touch detection.

The library returns raw touch coordinates, allowing the application (or a higher-level UI library such as InputEventsTouchUI) to perform its own calibration and mapping.

Features

  • Supports standard 4-wire resistive touch panels
  • Uses only standard Arduino pin functions
  • Configurable for virtually any Arduino-compatible board/display combination
  • Works when either the positive or negative touch panel pins are the analogue-capable pair
  • Median filtering for improved noise immunity
  • Configurable sample count
  • Configurable GPIO settling delay - crucial for accurate analog reads
  • Optional X and Y axis mirroring
  • Touch detection using a configurable threshold to suit any board, screen or wiring
  • Minimal RAM usage
  • No display or graphics dependencies
  • Works with 10 or 12bit ADCs (12bit useful for mapping to higher resolution displays)

The library does not report 'pressure' - the TouchPoint_s.z is populated with either 0 or 1 to denoted 'touched'.

This is a deliberate design choice as most applications simply need to know where the display was touched, not how hard. Reading pressure requires two more analogRead()s and some processor intensive maths - a cost not worth bearing unless you are writing a drawing app where perhaps pressure equates to pen width. If you are doing this, then pull requests are welcome!

If pressure is ever included, it will be optional to ensure performance can be maintained.

On an Arduino UNO, Adafruit's TouchScreen will return a touch point in ~800μs. With exactly the same parameters (2 samples, no settling delay), this library will return a touch point in ~610μs. That can be further tuned with accurate and repeatable results down to ~325μs - on an UNO.

With an Adafruit 1770 display connected to a Teensy 4.1, the time is down to ~70μs (15μs settling, single sample).

Repeatable results at 100ms interval on an UNO (with a nice 4D Systems touch panel):

X:      553     Y:      592     Z:      1       μs:     324
X:      553     Y:      592     Z:      1       μs:     324
X:      553     Y:      592     Z:      1       μs:     324
X:      553     Y:      592     Z:      1       μs:     328

Teensy 4.1 with Adafruit 1770 display:

X:      632     Y:      546     Z:      1       μs:     67
X:      633     Y:      546     Z:      1       μs:     67
X:      633     Y:      546     Z:      1       μs:     67
X:      633     Y:      546     Z:      1       μs:     67

I've been asked, so:

"Why use the ResistiveTouchScreen library rather than Adafruit's TouchScreen?"

Lady Ada's library has become the defacto standard and I have used it for many years - primarily on Adafruit displays (I encourage you to support her by buying her products).

However, The Adafruit TouchScreen is written for Adafruit products (as it should be), is limited to 10bit ADCs and has no configuration or tuning opportunities.

For example, the X & Y are always flipped to suit the hardware (this behaviour can be replicated in ResistiveTouchScreen with mirrorX() and mirrorY()) and the pin settling is only applied (non-optionally) to ARM processoers. Sampling is baked in at 2 samples.

The Adafruit library does provide Z pressure, but that comes at a cost and is not needed by the majority of applications.

SUPPORT

Feedback and bug reports are welcome or if you have any questions, drop by for a chat on Discord Discord Logo

INSTALLATION

Arduino IDE

Install the ResistiveTouchScreen library via the Arduino IDE Libary Manager.

PlatformIO

Add the following to your platformio.ini file:

lib_deps = 
	stutchbury/ResistiveTouchScreen@^1.1.1

Basic Usage

Where XP, YP, XN & YN are your X+, Y+, X- & Y- pins respectively:

#include <ResistiveTouchScreen.h>

ResistiveTouchScreen rts(XP, YP, XM, YM);

void setup() {
    Serial.begin(9600);
    delay(1000);
}

void loop() {
    // Get the touch point
    TouchPoint_s tp = rts.getTouchPoint();
    // Print to serial if higher than the touched threshold
    if ( tp.z > 0 ) {
        Serial.print("X:\t");
        Serial.print(tp.x);
        Serial.print("\tY:\t");
        Serial.print(tp.y);
        Serial.print("\tZ:\t");
        Serial.println(tp.z);
    }
    delay(100); //Don't scroll too fast! (for the example only - don't use delay() in your sketches)
}

There are four examples - for basic use, configuration parameters, tuning and threshold.

Configuration

Methods for configuring and adapting to different hardware. These allow wiring errors or constraints to be fixed in software.

Touch threshold

Set the threshold above which screen will be deemed touched.

The minimum returned X or Y value for most displays is usually greater than 100, so this is the default.

  • If the TouchPoint_s.z always returns 1 then you need to increase the threshold.
  • if the lower value edges of the touch panel do not respond to touch, you need to lower the threshold.

rts.setThreshold(105);

Analogue input selection

Use X- and Y- to analogRead() the resistance values rather than X+ and Y+.

Pass either true or false

Useful if your routing conflicts or dual use of the four pins means the X+ and Y+ can't do analog (looking at you, EastRising)

rts.useNegativeReadPins(bool); Will configure both X & Y pins (default true).

rts.useNegativeReadPins(bool, bool); Will configure X & Y pins individually.

Axis mirroring

Mirror either axis to suit panel orientation.

Pass either true or false

rts.mirrorX(); rts.mirrorY();

Tuning

Methods for tuning performance for different boards and display combinations.

Our goal here is consistency of read - ie repeatablility. When you press and hold a single point on the touch panel (with a touch pen or finger nail) the resulting X & Y coordinates should change as little as possible.

It turns out that the settling time yields better results than multiple samples. The price of a few microseconds delay before a single read is lower than taking more than one sample. The two layers of the touch panel have some inherant capacitance so we must wait for that to settle before reading.

GPIO settling time

Set the the number of micros seconds to wait between setting pin mode and analogRead()ing. Default is 20μs (microseconds)

Different MCUs, boards and screens (or combinations of) will require different settings. Higher values are likely to be required on cheaper touch panels.

Usually in the range 0 to 50μs.

Hint: Ensure number of samples to 1 and tune this parameter first.

rts.setPinSettlingUs(20);

Number of samples

Set the number of analogRead() samples to take.

Default is 1, maximum is 5.

rts.setNumSamples(2);

Increasing the sample count improves noise rejection at the expense of read speed.

Design philosophy

This library deliberately only returns raw ADC values for X & Y rather than calibrated display coordinates.

Touch to display calibration, rotation and mapping are application-specific concerns and are better handled by the graphics or UI framework.

The InputEventsTouchUI provides all this functionality and more!

Licence

GPL v2

Further Reading

If you'd like to know how resistive touch panels work, this is a very helpful resource from Infineon: Interface to Four-Wire Resistive Touchscreen - I used it extensively for this library

About

A fast, tuneable Arduino Framework TouchScreen library for 4 wire resistive touch panels

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages