Touch Input Without a Button
| Difficulty | Beginner |
|---|---|
| Category | Sensors |
| Supported boards | Arduino Uno R3 and compatible ATmega328P boards |
| Time needed | 35 minutes |
| Prerequisites | Making a Button Behave |
| Tested board | Not yet verified |
| Tested on | Not yet verified |
| Arduino IDE version | Not yet verified |
| Library | Not yet verified |
What it does
A TTP223 is a capacitive touch switch. The pad on the board holds a tiny electrical charge, your finger changes it, and the chip notices and drives its output pin.
Nothing moves. There is no contact to wear out, no spring, and no bounce, which is the first real reason to reach for one: everything Making a Button Behave teaches about debouncing simply does not apply here. The chip gives you a clean edge.
The second reason is that it works through a surface. The pad does not have to be exposed, so a touch control can sit behind a sheet of acrylic or a panel with nothing showing on the outside.
Before you begin
Required parts and tools
- An Arduino Uno or compatible board.
- One TTP223 touch module. This is Siratek product 2897.
- Three jumper wires, and a header strip soldered to the board if it came without one.
The Siratek part is the small red board, about a centimetre square, with the pads labelled on the underside.
Three pins
Read from the silkscreen on the back:
GND I/O VCC
I/O is the output. It is called that rather than OUT because the chip can be configured several ways, but on an Arduino it is an output from the module and an input to you.
Supply is 2 to 5.5 V, so 5V from an Uno is fine and the signal comes back at the same level.
A and B: the two solder pads
On the back of the board are two small pad pairs marked A and B. Unbridged from the factory, they give you the behaviour most people want:
- Momentary. Output goes HIGH while you touch, LOW when you let go. Like a push button.
- Active high. Touch means HIGH.
Bridging a pad with a blob of solder changes the mode:
Abridged: toggle. One touch turns the output on and it stays on. The next touch turns it off. This is a latch, in hardware, with no code at all.Bbridged: active low. The output idles HIGH and goes LOW on touch.
The toggle mode is genuinely useful. A lamp that should stay on after a tap needs no state variable, no edge detection and no debouncing: the module holds the state for you.
Bridging is permanent in practice, so decide before reaching for the iron. In software it costs three lines to do the same thing, which is usually the better answer while you are still experimenting.
Sensitivity, and what it responds to
The pad senses through a few millimetres of non-conductive material. Thin acrylic, plastic or paper work; metal does not, because it screens the field.
The sensing area can be extended by soldering a wire from the pad to a larger piece of foil or copper behind your panel. Keep that wire short. A long one acts as an antenna and picks up interference, and the usual symptom is a module that triggers on its own.
Two more things are normal and worth expecting. The chip recalibrates when it powers up, so do not have a finger on the pad at that moment or it will take your finger as the resting state. And a board sitting on a damp surface, or near mains wiring, can trigger spuriously; move it before blaming the part.
Pin reference
| Pin or label | Connect to | Purpose | Notes |
|---|---|---|---|
GND |
Uno GND |
Ground | |
I/O |
Uno D2 |
Touch output | HIGH on touch, with the pads unbridged |
VCC |
Uno 5V |
Power | 2 to 5.5 V |
Wiring steps
- Unplug the USB cable.
GNDtoGND.VCCto5V.I/OtoD2.- Plug the USB cable back in, keeping your finger off the pad while it powers up.
Software and libraries
No library is required. Use plain INPUT; the module drives the pin both ways, so an internal pull-up would work against it.
Minimal working example
// Siratek: a capacitive touch pad as an input.
const int touchPin = 2;
const int ledPin = 13;
void setup() {
pinMode(touchPin, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("Siratek: touch the pad.");
}
void loop() {
int state = digitalRead(touchPin);
digitalWrite(ledPin, state);
}
Three lines in loop(), and no debouncing anywhere. Compare that with the push button tutorial and the appeal becomes obvious.
Counting touches
Acting on the moment of a touch rather than on the state still needs edge detection, exactly as a button does. What you save is the timing.
// Siratek: counting touches, acting on the moment of contact.
const int touchPin = 2;
int lastState = LOW;
int count = 0;
void setup() {
pinMode(touchPin, INPUT);
Serial.begin(9600);
}
void loop() {
int state = digitalRead(touchPin);
if (state == HIGH && lastState == LOW) {
count++;
Serial.print("touch ");
Serial.println(count);
}
lastState = state;
}
On a mechanical button this same sketch would count one press as three or four, because the contacts bounce. Here the count is exact. That is the clearest demonstration of the difference between the two parts, and it is worth running both to see it.
Toggling in software
// Siratek: a latch in code, so the A pad can stay unbridged.
const int touchPin = 2;
const int lampPin = 8;
int lastState = LOW;
bool lampOn = false;
void setup() {
pinMode(touchPin, INPUT);
pinMode(lampPin, OUTPUT);
}
void loop() {
int state = digitalRead(touchPin);
if (state == HIGH && lastState == LOW) {
lampOn = !lampOn;
digitalWrite(lampPin, lampOn);
}
lastState = state;
}
This does in code what bridging the A pad does in hardware. Use the code version while you are deciding, and the solder version if the module ever has to work without an Arduino.
Expected result
The LED on the board and the Uno’s pin 13 both follow your finger, with no perceptible delay and no flicker on release.
The counting sketch should report exactly one touch per touch. If it reports several, something is wrong with the wiring or the module is picking up interference, because this chip does not bounce.
Troubleshooting
| Symptom | Likely cause | Check or fix |
|---|---|---|
| Always reads HIGH | Finger on the pad at power-up | Remove it and reset; the chip calibrates at startup |
| Triggers on its own | Long sense wire acting as an antenna | Shorten it, or move away from mains wiring |
| Triggers near damp or metal | Capacitance changed by surroundings | Reposition the board |
| No response at all | Power, or the wrong pin | Check VCC, GND, then I/O |
| Stays on after release | A pad bridged, so it is in toggle mode |
That is the latch; touch again, or unbridge |
| Logic inverted | B pad bridged |
Active low mode; invert the test |
| Does not work through a panel | Panel too thick, or metal | Use thinner non-conductive material |
| Works held, not tapped | Reading state rather than the edge | Use edge detection |
| Counts more than one per touch | Interference, not bounce | This chip does not bounce; check the wiring |
| Less reliable in a dry room | Static on your hand | Normal; touch the pad squarely |
Next steps
- Easier first: Making a Button Behave, to see exactly what this part saves you.
- Related products: a tactile push button for comparison, and a relay for switching something real with a touch.
- Next project: a panel with the touch pad hidden behind acrylic, so the control is invisible until it is used.
Sources and attribution
All text, wiring guidance and code in this tutorial are original Siratek work.
- TTP223 datasheet for the supply range, the power-up calibration and the
AandBconfiguration options. - The three-pin
GND I/O VCCheader and theAandBsolder pads described here were read from the Siratek product photographs for item 2897.
Sensing distance through a panel depends on the material and the pad size, and is given as a rough figure. No third-party tutorial text, diagrams, photographs or code has been reproduced here.

