The TTP223 Touch Button: a Lamp With Touch Control and Dimming
A TTP223 module that costs pennies turns any surface — wood, plastic, glass — into a button. We set up the A and B jumpers, tell a short tap from a hold, and change the LED brightness smoothly with PWM.
About the project
The TTP223 is a ready-made capacitive button: the chip calibrates itself, filters noise and outputs an ordinary digital signal. Unlike the ESP32 touch pins it works with any board, including an Arduino or an ESP32-C3, which have no touch inputs at all. It also works through 2–3 mm of plastic or wood — perfect for a switch hidden inside an enclosure.
What you need
- ESP32 DevKit (or an Arduino)
- A TTP223 module
- An LED and a 220 Ω resistor (or a MOSFET and an LED strip for a real lamp)
Wiring
| Module | ESP32 |
|---|---|
| VCC | 3V3 |
| I/O (SIG) | GPIO4 |
| GND | GND |
| LED | GPIO25 → 220 Ω → anode, cathode → GND |
The A and B jumpers
On the back of the module there are two pads you can bridge with a drop of solder:
| A | B | Output behaviour |
|---|---|---|
| open | open | HIGH while a finger is on the pad (default) |
| open | closed | every touch toggles HIGH ↔ LOW |
| closed | — | the same, inverted (active LOW) |
A dimmable lamp needs the default mode: the sketch tells a short tap from a hold itself. In the simulator these jumpers are in the module properties.
Code
// Touch lamp: tap to switch on/off, hold to change the brightness
const int TOUCH_PIN = 4; // TTP223 I/O (default mode, active HIGH)
const int LAMP_PIN = 25;
bool lampOn = false;
int brightness = 180;
int step = 5;
unsigned long touchedAt = 0;
bool wasTouched = false;
bool dimming = false;
void apply() {
ledcWrite(LAMP_PIN, lampOn ? brightness : 0);
}
void setup() {
Serial.begin(115200);
pinMode(TOUCH_PIN, INPUT);
ledcAttach(LAMP_PIN, 5000, 8); // 5 kHz PWM, 8 bits
apply();
}
void loop() {
bool touched = digitalRead(TOUCH_PIN) == HIGH;
unsigned long now = millis();
if (touched && !wasTouched) { // a finger just touched
touchedAt = now;
dimming = false;
}
if (touched && now - touchedAt > 600) { // held: change the brightness smoothly
dimming = true;
lampOn = true;
brightness += step;
if (brightness >= 255 || brightness <= 10) step = -step;
brightness = constrain(brightness, 10, 255);
apply();
}
if (!touched && wasTouched && !dimming) { // a short tap: toggle
lampOn = !lampOn;
apply();
Serial.println(lampOn ? "Lamp ON" : "Lamp OFF");
}
wasTouched = touched;
delay(20);
}
Press the module in the simulator with the mouse and let go — the lamp toggles. Hold for more than 0.6 s and the brightness starts "breathing" up and down; let go at the level you want.
Good to know
- Calibration at power-up. For about 0.5 s after power is applied the TTP223 memorises the "empty" level. If a finger is on the pad at that moment, the button works backwards or not at all until the next restart.
- Enclosure thickness. Through 2–3 mm of plastic the module works as is. For thicker material solder a 0–50 pF capacitor onto the Cs pads — more capacitance means lower sensitivity.
- Heavy loads. The TTP223 output gives a few milliamps; switch an LED strip through a logic-level MOSFET (IRLZ44N, AO3400), and a 230 V lamp through a relay or a solid-state relay.