Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

TTP223 touch sensor with ESP32 DevKit V1 — and the built-in touch pins

Wire a TTP223 touch module to an ESP32 DevKit V1 at 3.3 V on GPIO4 as a toggle switch, and compare it with the ESP32’s own touchRead() pads.

Arduino C++Verified — core esp32 3.3.12, 3 Nov 2026Compile-only

Community draft — report a mistake

The TTP223 turns a small copper pad into a clean digital touch button, and it runs happily at 3.3 V — so on the ESP32 DevKit V1 it needs just three wires and any input pin. The sketch uses each touch to toggle a virtual light, the usual job for these modules in switch-board projects.

The DevKit V1 also has capacitive touch built into the chip, so the sketch reads a bare coin or foil pad on GPIO33 at the same time. Compare the two: the TTP223 works through a plastic panel with no tuning, while the built-in pins cost nothing but need a threshold.

Wiring

ESP32 DevKit V1Only the pins used are shown · 3.3 V logicTTP223 capacitive touch moduleGNDD43V3VCCI/OGND
Also needed: Optional: a coin or foil pad on a short wire to D33 for the built-in touch demo.
Every connection
ESP32 DevKit V1TTP223 capacitive touch moduleWireNotes
3V3VCCredI/O swings to VCC, so 3V3 keeps it at a safe 3.3 V. Not VIN.
D4I/OyellowHIGH while touched with the default A/B pads open.
GNDGNDblack

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

  • The ESP32 already has 10 capacitive touch channels. On the DevKit V1 header: D4 (T0), D2 (T2), D15 (T3), D13 (T4), D12 (T5), D14 (T6), D27 (T7), D33 (T8), D32 (T9). A coin on a wire to one of them plus touchRead() often replaces the TTP223 entirely.
  • On the original ESP32 a touched pad reads lower (e.g. 60 → 15). The threshold in the sketch is a starting point — print the raw values with and without a finger and set it between them.
  • Why still use a TTP223? It works through 2–3 mm of plastic or glass with a stable threshold, ignores long-wire noise and doesn’t need tuning — handy behind an enclosure panel.
  • Solder pad A makes the output active-LOW; pad B makes it toggle on each touch. The sketch assumes both open (momentary, active-HIGH).
  • The TTP223 calibrates itself at power-up — don’t touch the pad while the ESP32 boots, or it treats your finger as “nothing”.

Code

ttp223-esp32.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// TTP223 touch module on an ESP32 DevKit V1 — plus the ESP32's own touch sensor for comparison.
// TTP223: VCC → 3V3, I/O → D4 (GPIO4), GND → GND. Each touch toggles a virtual light.
// Optional: a coin or a square of foil on a wire to D33 (TOUCH8) — no module needed.

constexpr uint8_t TTP_PIN = 4;
constexpr uint8_t TOUCH_PAD = 33;       // GPIO33 = TOUCH8
constexpr uint16_t TOUCH_THRESHOLD = 30; // ESP32 readings DROP when touched; tune for your pad

bool lightOn = false;
bool lastTtp = LOW;

void setup() {
  Serial.begin(115200);
  pinMode(TTP_PIN, INPUT);  // the TTP223 drives its output actively, no pull needed
  Serial.println("TTP223 on GPIO4, built-in touch pad on GPIO33");
}

void loop() {
  bool ttp = digitalRead(TTP_PIN);  // HIGH while touched (default jumper setting)
  if (ttp == HIGH && lastTtp == LOW) {
    lightOn = !lightOn;
    Serial.printf("TTP223 touched → light %s\n", lightOn ? "ON" : "OFF");
  }
  lastTtp = ttp;

  static uint32_t lastPrint = 0;
  if (millis() - lastPrint >= 1000) {
    lastPrint = millis();
    uint16_t raw = touchRead(TOUCH_PAD);
    Serial.printf("Built-in pad GPIO33: %u %s\n", raw, raw < TOUCH_THRESHOLD ? "(touched)" : "");
  }
  delay(20);
}

Expected serial output

Serial Monitor · 115200Output
TTP223 on GPIO4, built-in touch pad on GPIO33
Built-in pad GPIO33: 64
TTP223 touched → light ON
Built-in pad GPIO33: 12 (touched)
TTP223 touched → light OFF

Common errors

Output stuck HIGH (or stuck LOW after power-up)

The module calibrated with a finger or metal near the pad. Power-cycle it with nothing touching it, and keep it away from the ESP32’s antenna end.

Built-in touch pad says “touched” all the time

Threshold too high for your wire length. Print the untouched value and set TOUCH_THRESHOLD to about two-thirds of it.

Touch on D2 or D15 stops the board from booting

Those are strapping pins. Use D4, D13, D27, D32 or D33 for touch pads.

↑↓ to move · Enter to open