Der Name ESP32 steht für eine ganze Familie unterschiedlicher Mikrocontroller, die sich je nach Modell deutlich in ihren Hardware-Funktionen unterscheiden. Während einige Varianten keine Touch-Unterstützung bieten, verfügt der ESP-WROOM-32 über integrierte kapazitive Touch-Pins, mit denen sich Berührungen direkt am Mikrocontroller erfassen lassen – ganz ohne zusätzliche Bauteile.
In diesem Beitrag verwende ich einen Wemos D1 R32, der auf dem ESP-WROOM-32 basiert und mehrere dieser Touch-Pins bereitstellt. Anhand eines einfachen Praxisbeispiels zeige ich, wie sich die Touch-Funktion nutzen lässt und wie der ESP32 ein Touchevent erkennt. Ziel ist es, die Funktionsweise verständlich zu machen und zu zeigen, wie sich dieses Feature zuverlässig in eigenen Projekten einsetzen lässt.



ℹ️ Hinweis zur ESP32-Modellwahl
Nicht alle ESP32-Varianten verfügen über kapazitive Touch-Pins. Modelle wie der ESP32-C3, ESP32-S3 oder ESP32-C2 besitzen keine integrierte Touch-Hardware. Funktionen wie touchRead() stehen ausschließlich bei ESP32-Modellen mit entsprechender Hardware zur Verfügung, etwa beim ESP-WROOM-32 oder ESP32-S2.
Wie ermittelt der ESP32 ein Touchevent?
Der ESP32 erkennt ein Touchevent nicht über einen klassischen Schalter oder Taster, sondern über eine Änderung der elektrischen Kapazität an speziellen Touch-Pins. Diese Pins sind im Mikrocontroller bereits als kapazitive Sensoren ausgelegt und benötigen keine zusätzlichen Bauteile.
Im Normalzustand besitzt ein Touch-Pin eine bestimmte Grundkapazität. Nähert sich ein Finger der angeschlossenen Fläche oder berührt sie, verändert sich diese Kapazität. Der menschliche Körper wirkt dabei wie eine zusätzliche Kapazität und koppelt das Signal schwach gegen Masse.
Der ESP32 misst diese Veränderung intern und stellt das Ergebnis als Messwert zur Verfügung, den wir im Programm mit touchRead() auslesen können.
Wichtig ist dabei:
Der ESP32 liefert keine feste „Touch / Nicht-Touch“-Information, sondern einen relativen Zahlenwert. Erst durch den Vergleich dieses Werts mit einem Referenzwert oder einem definierten Schwellwert lässt sich erkennen, ob tatsächlich eine Berührung stattgefunden hat.
Was beeinflusst das Touchevent?
Ob ein Touchevent zuverlässig erkannt wird, hängt nicht nur vom ESP32 selbst ab, sondern auch von äußeren Einflüssen. Ein besonders wichtiger – und oft übersehener – Faktor ist dabei der Mensch als Teil des Systems.
Da der ESP32 eine kapazitive Änderung misst, spielt die Kopplung des Körpers zur Erde eine entscheidende Rolle. Je besser diese Kopplung ist, desto deutlicher fällt die Veränderung des Messwerts aus. Genau hier kann bereits das Schuhwerk einen spürbaren Unterschied machen:
Isolierende Sohlen können die Kopplung zur Erde reduzieren, wodurch sich die gemessene Kapazitätsänderung abschwächt. In der Praxis zeigt sich das oft in geringeren oder weniger stabilen Touch-Werten.
Neben der Erdung des Körpers beeinflussen weitere praktische Faktoren das Ergebnis:
- die Größe der berührten Fläche
- der Abstand zwischen Touchfläche und Masse
- das Material zwischen Finger und Touchfläche
Diese Einflüsse erklären, warum identische Schaltungen in unterschiedlichen Umgebungen oder bei verschiedenen Personen leicht abweichende Touch-Werte liefern können. Für eine zuverlässige Auswertung ist es daher wichtig, diese Rahmenbedingungen bei der Wahl von Schwellwerten und bei der Kalibrierung zu berücksichtigen.
ℹ️ Praxis-Tipp
Für eine kleine Schaltung beim Osterevent im JFZ habe ich den Schwellwert nicht fest im Code hinterlegt, sondern über ein Drehpotentiometer einstellbar gemacht. So lässt sich die Empfindlichkeit des Touch-Pins direkt anpassen, ohne das Programm neu flashen zu müssen – besonders praktisch bei wechselnden Bedingungen oder unterschiedlichen Nutzern.
Welche Touch-Pins kann ich wirklich nutzen?
Der ESP-WROOM-32 stellt insgesamt zehn kapazitive Touch-Pins (T0–T9) zur Verfügung. In der Praxis bedeutet das jedoch nicht, dass jeder dieser Pins auf jedem Board uneingeschränkt nutzbar ist. Gerade bei fertigen Development-Boards wie dem Wemos D1 R32 sind einige Pins bereits vorbelegt oder übernehmen wichtige Funktionen beim Bootvorgang.


Erstes Praxisbeispiel: LED per Touch einschalten
Um die Touch-Funktion des ESP32 greifbar zu machen, starten wir mit einem möglichst einfachen Beispiel:
Eine LED wird eingeschaltet, sobald ein Draht am Touch-Pin berührt wird.
Der Draht dient dabei als einfache Touchfläche und macht sehr gut sichtbar, wie sensibel der kapazitive Touch reagiert – ganz ohne spezielle Elektroden oder Leiterflächen.
Aufbau der Schaltung
Für dieses Beispiel benötigen wir:
- einen Wemos D1 R32*
- eine LED* mit Vorwiderstand*
- einen Draht*, sowie
- ein 400 Pin Breadboard*
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Die LED wird klassisch an einen freien GPIO angeschlossen.
Am Touch-Pin wird lediglich ein Draht befestigt – dieser fungiert als Touchfläche und muss nicht mit Masse oder Spannung verbunden werden.
Quellcode – Touchevent am ESP32 erkennen und LED schalten
In diesem Beispiel wird ein kapazitives Touchevent über den Touch-Pin T0 (GPIO04) erkannt. Sinkt der gemessene Touch-Wert unter einen definierten Schwellwert, wird eine LED eingeschaltet. Sobald keine Berührung mehr vorliegt, erlischt die LED wieder.
Das Beispiel ist bewusst einfach gehalten und eignet sich ideal, um das Verhalten der Touch-Pins des ESP32 nachvollziehen zu können.
// GPIO-Pin, an dem die LED angeschlossen ist
#define ledPin 18
// Touch-Pin T0 des ESP32 (GPIO04)
#define touchPin 4
void setup() {
// Serielle Schnittstelle zur Ausgabe der Touch-Werte
Serial.begin(115200);
// LED-Pin als Ausgang konfigurieren
pinMode(ledPin, OUTPUT);
}
void loop() {
// Aktuellen Touch-Messwert vom Touch-Pin auslesen
int value = touchRead(touchPin);
// Messwert im seriellen Monitor ausgeben
Serial.println(value);
// Liegt der Messwert unterhalb des Schwellwerts,
// wird ein Touchevent angenommen
if (value < 200) {
digitalWrite(ledPin, HIGH); // LED einschalten
} else {
digitalWrite(ledPin, LOW); // LED ausschalten
}
// Kurze Pause zur Beruhigung der Messung
delay(50);
}
Warum ein einstellbarer Schwellwert sinnvoll ist
Die vom Touch-Pin gelieferten Messwerte sind nicht konstant, sondern bewegen sich – je nach Aufbau und Umgebung – in einem gewissen Bereich. In der Praxis liegen diese Werte häufig irgendwo zwischen 0 und 1600, können aber stark schwanken.
Wie deutlich sich ein Touchevent im Messwert bemerkbar macht, hängt unter anderem davon ab:
- wo die Touchfläche berührt wird
- wie gut der Körper gegen Erde gekoppelt ist
- ob die Finger trocken oder feucht sind
Dadurch kann es passieren, dass ein fest im Code hinterlegter Schwellwert in einer Situation zuverlässig funktioniert, in einer anderen jedoch zu früh, zu spät oder gar nicht auslöst. Besonders bei wechselnden Nutzern oder unterschiedlichen Umgebungsbedingungen ist das schnell spürbar.
Um dieses Problem zu umgehen, bietet es sich an, den Schwellwert nicht fest zu programmieren, sondern zur Laufzeit einstellbar zu machen. Eine einfache und bewährte Lösung ist der Einsatz eines Drehpotentiometers, über das sich der Schaltpunkt direkt anpassen lässt – ganz ohne den Code ändern oder neu auf den ESP32 hochladen zu müssen.
Gerade bei Workshops, Demonstrationen oder mobilen Aufbauten erlaubt diese Methode eine schnelle Feinjustierung und macht das Touch-Verhalten deutlich robuster im Alltag.

Quellcode – Touchevent mit einstellbarem Schwellwert per Drehpotentiometer
In diesem erweiterten Beispiel wird der Schwellwert für das Touchevent nicht fest im Code hinterlegt, sondern über ein Drehpotentiometer zur Laufzeit eingestellt. Der aktuelle Potentiometerwert wird über einen analogen Eingang ausgelesen und auf den erwarteten Wertebereich des Touch-Pins abgebildet.
Auf diese Weise lässt sich der Schaltpunkt flexibel an unterschiedliche Bedingungen anpassen, ohne das Programm neu auf den ESP32 hochladen zu müssen. Besonders bei wechselnden Nutzern oder variierenden Umgebungen sorgt dieser Ansatz für ein deutlich robusteres Touch-Verhalten.
// GPIO-Pin, an dem die LED angeschlossen ist
#define ledPin 18
// Touch-Pin T0 des ESP32 (GPIO04)
#define touchPin 4
// Analoger Eingang für das Drehpotentiometer
#define rotaryResistorPin 35
// Erwarteter Wertebereich des Touch-Pins
// (abhängig vom Aufbau und der Touchfläche)
const int TOUCH_MIN_VALUE = 0;
const int TOUCH_MAX_VALUE = 1600;
// Wertebereich des ADC beim ESP32 (12 Bit)
const int ANALOG_MIN_VALUE = 0;
const int ANALOG_MAX_VALUE = 4096;
// Variablen für Mess- und Vergleichswerte
int touchValue; // aktueller Touch-Messwert
int resistorValue; // Rohwert des Potentiometers
int value; // gemappter Schwellwert für das Touchevent
void setup() {
// Serielle Schnittstelle zur Ausgabe der Messwerte
Serial.begin(115200);
// LED-Pin als Ausgang konfigurieren
pinMode(ledPin, OUTPUT);
}
void loop() {
// Aktuellen Touch-Wert vom Touch-Pin auslesen
touchValue = touchRead(touchPin);
// Aktuellen ADC-Wert des Drehpotentiometers auslesen
resistorValue = analogRead(rotaryResistorPin);
// Touch-Messwert im seriellen Monitor ausgeben
Serial.print("Touch-Value: ");
Serial.println(touchValue);
// Rohwert des Potentiometers ausgeben
Serial.print("Resistor-Value: ");
Serial.println(resistorValue);
// Potentiometer-Wert auf den gültigen Touch-Bereich abbilden
value = map(
resistorValue,
ANALOG_MIN_VALUE,
ANALOG_MAX_VALUE,
TOUCH_MIN_VALUE,
TOUCH_MAX_VALUE
);
// Gemappten Schwellwert ausgeben
Serial.print("mapped-Value: ");
Serial.println(value);
// Vergleich: Liegt der Touch-Wert unterhalb des eingestellten Schwellwerts,
// wird ein Touchevent angenommen
if (touchValue < value) {
digitalWrite(ledPin, HIGH); // LED einschalten
} else {
digitalWrite(ledPin, LOW); // LED ausschalten
}
// Kurze Pause zur Stabilisierung der Messwerte
delay(50);
}
Praxisbeispiel: Tonhöhe per Touch steuern
In diesem Beispiel steuert der kapazitive Touch-Pin T0 (GPIO04) direkt die Frequenz eines Buzzers. Je nachdem, wie stark bzw. wo du die Touchfläche berührst (z. B. Draht/Kupferfläche), verändert sich der Touch-Messwert – und damit die Tonhöhe. So entsteht ein einfacher „Touch-Synth“, der sofort hörbares Feedback liefert.
Quellcode – Touch steuert Tonhöhe und LED-Helligkeit
In diesem Beispiel wird der Touch-Pin T0 (GPIO04) nicht nur als einfacher Schalter genutzt, sondern als stufenloser Eingabewert. Der aktuell gemessene Touch-Wert wird im Loop ausgelesen, kurz geglättet und anschließend auf zwei Ausgaben abgebildet:
Zum einen steuert er die Frequenz des Buzzers (Tonhöhe), zum anderen die PWM-Helligkeit der LED am GPIO18.
Damit das Ergebnis sauber und angenehm wirkt, wird der Touch-Wert vor der Auswertung geglättet. So werden kurze Schwankungen reduziert, die sonst zu hörbarem „Zittern“ beim Ton oder zu Flackern bei der LED führen würden. Das sorgt insgesamt für ein deutlich stabileres Verhalten, besonders wenn du den Draht nur leicht berührst oder dich langsam annäherst.
#define TOUCH_PIN 4 // T0 (GPIO04)
#define BUZZER_PIN 19 // Passiver Buzzer
#define LED_PIN 18 // LED mit Vorwiderstand
// Frequenzbereich für den Buzzer
const int FREQ_MIN = 150;
const int FREQ_MAX = 2500;
// Erwarteter Touch-Bereich (ggf. anpassen!)
const int TOUCH_MIN = 0;
const int TOUCH_MAX = 1600;
// PWM Auflösung (8 Bit → 0..255)
const int PWM_RESOLUTION = 8;
// Geglätteter Touch-Wert
int smoothedTouch = TOUCH_MAX;
void setup() {
Serial.begin(115200);
// PWM für Buzzer initialisieren
ledcAttach(BUZZER_PIN, FREQ_MIN, PWM_RESOLUTION);
ledcWrite(BUZZER_PIN, 128); // 50 % Duty (Signal aktiv)
// PWM für LED initialisieren
ledcAttach(LED_PIN, 1000, PWM_RESOLUTION); // 1 kHz für LED
ledcWrite(LED_PIN, 0); // LED aus
Serial.println("Touch steuert Tonhoehe und LED-Helligkeit");
}
void loop() {
// Touch-Wert auslesen
int touchValue = touchRead(TOUCH_PIN);
// Touch-Wert glätten (verhindert Flackern / Tonzittern)
smoothedTouch = (smoothedTouch * 9 + touchValue) / 10;
// ------------------------
// Tonhoehe berechnen
// ------------------------
int freq = map(
smoothedTouch,
TOUCH_MIN,
TOUCH_MAX,
FREQ_MAX,
FREQ_MIN
);
freq = constrain(freq, FREQ_MIN, FREQ_MAX);
// Ton setzen
ledcWriteTone(BUZZER_PIN, freq);
// ------------------------
// LED-Helligkeit berechnen
// ------------------------
int brightness = map(
smoothedTouch,
TOUCH_MIN,
TOUCH_MAX,
255, // hell bei starkem Touch
0 // dunkel bei keinem Touch
);
brightness = constrain(brightness, 0, 255);
// LED dimmen
ledcWrite(LED_PIN, brightness);
// Debug-Ausgabe
Serial.print("Touch: ");
Serial.print(touchValue);
Serial.print(" | Freq: ");
Serial.print(freq);
Serial.print(" | LED: ");
Serial.println(brightness);
delay(30);
}
Fazit
Der kapazitive Touch des ESP32 ist ein mächtiges Feature, das sich mit wenig Aufwand in eigene Projekte integrieren lässt. Anstatt Berührungen nur als Ein/Aus-Signal zu verwenden, kann der Touch-Wert auch als stufenloser Eingabewert genutzt werden – etwa zur Steuerung von Helligkeit, Tonhöhe oder anderen Parametern.
Gerade in Kombination mit einfachen Maßnahmen wie Glättung oder einem einstellbaren Schwellwert entsteht so eine robuste und intuitive Eingabemöglichkeit, ganz ohne zusätzliche Sensorik. Wichtig ist dabei, die Eigenheiten der Touch-Pins zu kennen und die Wahl des ESP32-Modells sowie der verwendeten Pins bewusst zu treffen.
Letzte Aktualisierung am: 02. Februar 2026


1 thought on “Kapazitiver Touch mit dem ESP32 – so einfach geht’s”