Touch Keyboard
Works with
Any CircuitPython board with I2C and native USB — Trinket M0, Feather, ItsyBitsy, Circuit Playground
Turn everyday objects into keys. With an MPR121 capacitive touch sensor, a few pieces of aluminum foil, and a handful of lines of CircuitPython, you can build a keyboard that types letters, fires shortcuts, or plays notes — all by touching a banana.
What you'll build
A USB HID keyboard driven by 12 capacitive touch pads. Each pad is mapped to a key. Touch a pad, a keypress fires. The pads can be foil, fruit, wire, or anything conductive. Your computer sees it as a real keyboard — no driver installation needed.
What you'll need
| Part | Notes |
|---|---|
| CircuitPython board with native USB | Trinket M0, ItsyBitsy M0/M4, Feather M0/M4, Circuit Playground Express/Bluefruit |
| Adafruit MPR121 12-key capacitive touch breakout | Product page |
| Conductive pads | Aluminum foil strips, alligator clips, fruit, bare wire |
| Alligator clip cables or hookup wire | For connecting pads to the MPR121 |
| USB cable | Data-capable, not charge-only |
Wiring
The MPR121 talks over I2C. Connect it to your board's SDA and SCL pins, then clip or wire your conductive pads to pins 0–11.
graph LR
subgraph Board
B_3V3["3.3V"]
B_GND["GND"]
B_SDA["SDA"]
B_SCL["SCL"]
end
subgraph MPR121["MPR121 Breakout"]
M_VIN["VIN"]
M_GND["GND"]
M_SDA["SDA"]
M_SCL["SCL"]
M_0["Pin 0"]
M_1["Pin 1"]
M_2["Pin 2"]
M_3["Pin 3"]
end
subgraph Pads
P0["Foil pad A"]
P1["Foil pad B"]
P2["Foil pad C"]
P3["Foil pad D"]
end
B_3V3 --> M_VIN
B_GND --> M_GND
B_SDA --- M_SDA
B_SCL --- M_SCL
M_0 --- P0
M_1 --- P1
M_2 --- P2
M_3 --- P3
Note
The default I2C address for the MPR121 is 0x5A. If you need multiple MPR121 boards on the same bus, tie the ADDR pin high or to SDA/SCL to change the address.
The code
import board
import busio
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
import adafruit_mpr121
# Set up I2C and the MPR121
i2c = busio.I2C(board.SCL, board.SDA)
mpr121 = adafruit_mpr121.MPR121(i2c)
# Set up the USB HID keyboard
kbd = Keyboard(usb_hid.devices)
# Map each touch pad (0-11) to a keycode
KEY_MAP = {
0: Keycode.A,
1: Keycode.B,
2: Keycode.C,
3: Keycode.D,
4: Keycode.E,
5: Keycode.F,
6: Keycode.G,
7: Keycode.H,
8: Keycode.I,
9: Keycode.J,
10: Keycode.K,
11: Keycode.L,
}
# Track which pads were touched last loop
last_touched = mpr121.touched_pins
while True:
current_touched = mpr121.touched_pins
for i in range(12):
# Pad just pressed
if current_touched[i] and not last_touched[i]:
if i in KEY_MAP:
kbd.press(KEY_MAP[i])
# Pad just released
if not current_touched[i] and last_touched[i]:
if i in KEY_MAP:
kbd.release(KEY_MAP[i])
last_touched = current_touched
Swap any Keycode.A for Keycode.CONTROL, Keycode.SPACE, or a media key to build shortcuts instead of letters.
How it works
The MPR121 measures the capacitance at each of its 12 pins many times per second. When you touch a pad, your body adds capacitance to that pin and the reading changes. The chip compares that change against a configurable threshold and sets a touch flag. Your code reads those flags over I2C — you never have to sample raw capacitance yourself.
The adafruit_hid library makes your board pretend to be a USB keyboard at the hardware level. When you call kbd.press(), the board sends a standard USB HID report to your computer, which responds exactly as it would to a physical keypress. No special software needed on the host side.
The loop tracks which pads were touched on the last iteration and compares to the current state. A keypress fires on the transition from not-touched to touched; a release fires on the reverse transition. This prevents the keyboard from auto-repeating while you hold a pad.
Installing the libraries
Download the CircuitPython Library Bundle that matches your CircuitPython version. Copy these to the lib/ folder on your CIRCUITPY drive:
adafruit_mpr121.mpyadafruit_hid/(entire folder)adafruit_bus_device/(entire folder)
Remix it
Remix idea
Instead of typing letters, map each pad to a MIDI note number and send MIDI messages over USB. Build a playable instrument out of fruit. See MIDI Foot Pedal for the MIDI output pattern.
Remix idea
Add a NeoPixel strip and light up a different color for each pad you touch. Instant visual feedback and it looks great in a dark room. See First NeoPixel to get NeoPixels running first.
Remix idea
Wire all 12 pads to labeled keys and put them in a laser-cut or 3D-printed enclosure. You now have a custom macropad for your desk. See Customizing USB to give it a custom name and VID/PID.
Go deeper
- MPR121 sensor reference
- USB HID reference
- Adafruit MPR121 CircuitPython tutorial — Credit: Adafruit Learning System