Read the idle value, then set the threshold below it. A fixed number from a tutorial may not suit your wiring.
What the message means
The touch value falls when a finger is near. Long wires, a nearby supply or moisture shift the idle value and trigger false touches.
Fix it in this order
- Print the touch reading with no finger on the pad, and with a finger.
- Set the threshold between the two values.
- Keep the wire to the pad short and away from motor or Wi-Fi antenna areas.
- Average a few readings and require a short hold time.
- Re-measure after you change the case or the wiring.
- Use a button if the environment is noisy or wet.
Why it happens
An ESP32 touch pin reads a value that falls when you touch it. The baseline varies with the wire length, the board and the environment, so a fixed threshold copied from an example can trigger by itself or never trigger.
Print the untouched and touched values, set the threshold between them, keep the wire short, and keep it away from signal lines.
If you see this, do this
| You see | Do this |
|---|---|
| Triggers at random | Noise or threshold too high. |
| Never triggers | Threshold too low. |
Related
Last reviewed: November 2026. These are the usual causes and the order that finds them fastest. Test on your own board; clones and cables differ.
Why this happens
The ESP32 touch sensor measures how long a pad takes to charge. A finger adds capacitance, so on the classic ESP32 the reading falls when you touch it. On the S2 and S3 the raw value goes up on touch, so the direction of your comparison must match your chip. The size of the idle number depends on wire length, nearby metal, case, moisture and the board itself.
That is why a threshold copied from an example may not fit. A long wire raises the idle capacitance and the readings, and noise from Wi-Fi or switching supplies moves the baseline from moment to moment.
How to confirm the cause
- Print touchRead() with nothing near the pad, then touched, then with your hand close.
- Note a few readings of each case, and take the lowest idle and the highest touched.
- Set the threshold between them, not at one of the values.
- Repeat with the final case and wiring, since both change the numbers.
Worked example
The code measures the idle value at start-up and sets a threshold two thirds of it. Illustrative arithmetic: idle 60 and touched 15 would sit midway near 37, so a threshold of 40 would work.
const int PAD = 4; // T0 on the classic ESP32
int threshold;
void setup() {
Serial.begin(115200);
long sum = 0;
for (int i = 0; i < 50; i++) { sum += touchRead(PAD); delay(10); }
int idle = sum / 50;
threshold = idle * 2 / 3; // tune using your touched value
}
void loop() {
bool touched = touchRead(PAD) < threshold;
Serial.println(touched);
delay(50);
}Common mistakes
- Using a pin that is a boot strapping pin, such as GPIO0 or GPIO2, for a touch pad.
- Putting the wire near the Wi-Fi antenna or a motor.
- Using the classic comparison on an S2 or S3 chip.
- Reading only once, without a short hold time.
If this did not fix it
- Check the ground: a floating battery-powered board behaves differently from one connected to a laptop.
- Check for moisture or dirt on the pad.
- Check the supply for noise.
- Consider a dedicated capacitive touch module.