The TTP223 turns a small copper pad into a button with no moving parts. Powered from 3V3, its I/O pin goes HIGH while you touch it, and the Pico W reads it on GP16.
This script uses a pin interrupt so even a quick tap is caught, and toggles the on-board LED on each touch — a touch light switch in a dozen lines.
Wiring
| Raspberry Pi Pico W | TTP223 capacitive touch module | Wire | Notes |
|---|---|---|---|
| 3V3 | VCC | red | 3V3 is pin 36. I/O swings to VCC, so 3.3 V keeps it Pico-safe. |
| GND | GND | black | |
| GP16 | I/O | yellow | GP16 is physical pin 21. |
2.0–5.5 V part, 3.3 V board. I/O drives to the supply voltage, so power it from 3.3 V on ESP32 and Pico and from 5 V on Uno. It runs happily at either.
Board quirks
- By default I/O is HIGH while touched. Solder pad A changes it to active-LOW; pad B makes the module itself toggle on each touch.
- The interrupt handler only counts; the main loop prints and toggles the LED. Keep IRQ handlers this short in MicroPython — no printing or allocating inside them.
- The TTP223 calibrates itself at power-up. Don’t touch the pad while you plug in, or it treats your finger as “not touched”.
- It works through 1–2 mm of plastic or glass, so you can hide it behind a project box lid.
Code
# TTP223 capacitive touch button on a Raspberry Pi Pico W (MicroPython).
# Wiring: VCC -> 3V3 (pin 36), GND -> GND, I/O -> GP16 (pin 21).
# Default module setting: I/O goes HIGH while touched. Each touch toggles the on-board LED,
# and an interrupt counts touches without missing short taps.
from machine import Pin
import time
touch = Pin(16, Pin.IN)
led = Pin("LED", Pin.OUT)
touches = 0
last_ms = 0
def on_touch(pin):
global touches, last_ms
now = time.ticks_ms()
if time.ticks_diff(now, last_ms) > 150: # ignore re-triggers within 150 ms
touches += 1
last_ms = now
touch.irq(trigger=Pin.IRQ_RISING, handler=on_touch)
print("TTP223 on GP16 - touch the pad")
seen = 0
while True:
if touches != seen:
seen = touches
led.toggle()
print("Touch #{} LED {}".format(seen, "on" if led.value() else "off"))
time.sleep_ms(20)# TTP223 capacitive touch button on a Raspberry Pi Pico W (MicroPython).
# Wiring: VCC -> 3V3 (pin 36), GND -> GND, I/O -> GP16 (pin 21).
# Default module setting: I/O goes HIGH while touched. Each touch toggles the on-board LED,
# and an interrupt counts touches without missing short taps.
from machine import Pin
import time
touch = Pin(16, Pin.IN)
led = Pin("LED", Pin.OUT)
touches = 0
last_ms = 0
def on_touch(pin):
global touches, last_ms
now = time.ticks_ms()
if time.ticks_diff(now, last_ms) > 150: # ignore re-triggers within 150 ms
touches += 1
last_ms = now
touch.irq(trigger=Pin.IRQ_RISING, handler=on_touch)
print("TTP223 on GP16 - touch the pad")
seen = 0
while True:
if touches != seen:
seen = touches
led.toggle()
print("Touch #{} LED {}".format(seen, "on" if led.value() else "off"))
time.sleep_ms(20)Expected serial output
TTP223 on GP16 - touch the pad
Touch #1 LED on
Touch #2 LED off
Touch #3 LED onTTP223 on GP16 - touch the pad Touch #1 LED on Touch #2 LED off Touch #3 LED on
Common errors
LED toggles twice per touch
Pad B is bridged (module toggle mode) or the touch is bouncing. Leave A and B open, and keep the 150 ms lock-out in the handler.
Always touched after power-up
A finger or metal was near the pad while it calibrated. Power-cycle with nothing touching it.