ESP32 UNO - Touch Sensor

Want a button that has no moving part? Connect a touch sensor to the ESP32 Uno form board and read it with a few lines of Arduino code. A touch switch acts like a push button, so you can use it for touch lamps, tap controls and sleek panels.

By the end, you can:

  1. Wire a touch sensor to the ESP32 Uno
  2. Read the touch state with digitalRead()
  3. Catch the moment of touch and the moment of release
  4. Watch the result in the Arduino IDE Serial Monitor
ESP32 Uno touch sensor

Components You Need

1×ESP32 Uno-form Board
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×Touch Sensor
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of the Touch Sensor

By the end of this part, you know what each pin does and what the signal means.

Pinout

Sensor Pin Job
GND Ground (0V)
VCC Power. Use 3.3V with the ESP32 Uno
SIGNAL LOW when nobody touches the pad, HIGH while a finger is on it
Touch Sensor Pinout

Good to know: The module has a small chip that feels your finger through the pad. It turns that feeling into a clean HIGH or LOW signal, so you need no extra parts.

How It Works

Pad State SIGNAL Pin
Not touched LOW
Touched HIGH

Sensor and Board

The SIGNAL pin goes to one input pin of the ESP32 Uno. Your sketch reads that pin: HIGH means a touch, LOW means no touch.

ESP32 Uno Pinout

Every Uno header pin of the ESP32 Uno form board has its own GPIO number, and the code uses that number. Find D7 in the diagram below before you connect a wire.

ESP32 Uno pinout diagram

How to Connect

By the end of this part, three wires link the sensor to the board.

The wiring diagram between ESP32 Uno Touch Sensor

This image is created using Fritzing. Click to enlarge image

※ NOTE THAT:

The wiring diagram may not show the correct pin. In the demo, the buzzer goes to D6 (GPIO27) on the ESP32 Uno, not D8 as the picture may show. We will update the diagram soon. Until then, follow the wiring table and the code on this page, not the picture.

Touch Sensor Pin ESP32 Uno Pin
VCC 3.3V
GND GND
SIGNAL D7 (GPIO14)

Good to know: ESP32 Uno pins use 3.3V logic and are not 5V tolerant. Power the sensor from 3.3V, so the SIGNAL output stays at 3.3V.

WARNING

If you power the sensor from 5V, the SIGNAL pin can also output 5V when touched. That can damage GPIO14. Keep VCC on 3.3V, or add a voltage divider or level shifter on the SIGNAL wire.

How to Program the Touch Sensor

By the end of this part, you know the two calls that read the sensor.

Step 1 — Make the pin an input

Call pinMode() once in setup(). D7 is GPIO14, so that number goes in the call.

pinMode(14, INPUT);

Step 2 — Read the pin

The digitalRead() function returns HIGH or LOW.

int inputState = digitalRead(14);

※ NOTE THAT:

You can use the reading in two ways:

  • By level: do one thing while the pin is HIGH, and the opposite while it is LOW.
  • By change: act only when the pin switches from LOW to HIGH, or from HIGH to LOW.

Example with an LED. To light the LED only while a finger rests on the pad, read the level. To flip the LED each time you tap, react to the change.

Touch Sensor - ESP32 Uno Code

This part has two sketches: one prints the raw state, the other prints touch and release events.

Print the Touch State to the Serial Monitor

The sketch reads GPIO14 in every loop() pass and prints 0 or 1.

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-touch-sensor */ #define SENSOR_PIN 14 // D7 (GPIO14) is wired to the SIGNAL pin of the touch sensor void setup() { // open the serial port at 9600 baud Serial.begin(9600); // D7 (GPIO14) works as a plain digital input pinMode(SENSOR_PIN, INPUT); } void loop() { // get the current level of the sensor pin (HIGH = touched) int state = digitalRead(SENSOR_PIN); // show the level in the Serial Monitor Serial.println(state); }
Code Part What It Does
#define SENSOR_PIN 14 Names GPIO14 (header pin D7)
pinMode(SENSOR_PIN, INPUT) Turns the pin into an input
digitalRead(SENSOR_PIN) Gets HIGH (1) or LOW (0)
Serial.println(state) Prints the value on its own line

The Serial Monitor shows a stream of 0 and 1 values that follows your finger.

Upload and Test

  1. First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
  2. Build the circuit by following the wiring table above.
  3. Plug in the USB Type-C cable between the ESP32 Uno and your computer.
  4. Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
  5. Copy the code above into Arduino IDE.
  6. Click Upload and wait until it finishes.
  7. Start the Serial Monitor at 9600 baud.
  8. Touch the pad, hold for a moment, then lift your finger.
  9. Pro tip: Many modules have a small LED that lights when you touch the pad. If that LED reacts but the Serial Monitor stays at 0, check the SIGNAL wire.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
0 0 0 1 1 1 1 0 0 0
Ln 11, Col 1
ESP32 Dev Module on COM15
2

Detect Touch and Release

This sketch keeps the previous reading and compares it with the new one. It prints one message for each touch and one for each release.

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-touch-sensor */ #define SENSOR_PIN 14 // D7 (GPIO14) is wired to the SIGNAL pin of the touch sensor int touch_state; // level read from the sensor in this loop pass int prev_touch_state = LOW; // level seen in the pass before void setup() { // open the serial port at 9600 baud Serial.begin(9600); // D7 (GPIO14) works as a plain digital input pinMode(SENSOR_PIN, INPUT); } void loop() { // get the current level of the sensor pin touch_state = digitalRead(SENSOR_PIN); if(prev_touch_state == LOW && touch_state == HIGH) Serial.println("The sensor is touched"); else if(prev_touch_state == HIGH && touch_state == LOW) Serial.println("The sensor is is released"); // remember this level for the next pass prev_touch_state = touch_state; }
Code Part What It Does
touch_state Newest reading of the pin
prev_touch_state Reading from the pass before
LOW then HIGH Prints "The sensor is touched"
HIGH then LOW Prints "The sensor is is released"

You get one line per event instead of a long stream of numbers.

Upload and Test

  1. Copy the code into Arduino IDE.
  2. Click Upload to send it to the ESP32 Uno.
  3. Put a finger on the pad and keep it there.
  4. Read the Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
The sensor is touched
Ln 11, Col 1
ESP32 Dev Module on COM15
2
  1. Lift your finger.
  2. Read the Serial Monitor again.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
The sensor is touched The sensor is is released
Ln 11, Col 1
ESP32 Dev Module on COM15
2
  1. Pro tip: Use the event style when one tap must trigger one action, such as flipping a relay or changing a song.

Video Tutorial

See the ESP32 Uno build in action in the video below.

In the demo, each of two touch sensors starts a song on a buzzer, while two LEDs blink to the beat. It uses this code:

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-touch-sensor */ // --- Pin assignments --- #define BUZZER_PIN 27 // D6 (GPIO27) buzzer #define TOUCH_1_PIN 26 // D2 (GPIO26) touch sensor 1, starts Happy Birthday #define TOUCH_2_PIN 25 // D3 (GPIO25) touch sensor 2, starts Jingle Bells #define LED_A_PIN 17 // D4 (GPIO17) first LED (lit when LOW) #define LED_B_PIN 16 // D5 (GPIO16) second LED (lit when LOW) // --- Note pitches in Hz --- #define NOTE_C4 262 #define NOTE_D4 294 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_G4 392 #define NOTE_A4 440 #define NOTE_A5 880 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_D5 587 #define NOTE_E5 659 // --- Song 1: Happy Birthday --- const int happyBirthdayMelody[] = { NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4, NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_G4, NOTE_F4, NOTE_C4, NOTE_C4, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_E4, NOTE_D4, NOTE_B4, NOTE_B4, NOTE_A4, NOTE_F4, NOTE_G4, NOTE_F4 }; const int happyBirthdayDurations[] = { 8, 8, 4, 4, 4, 2, 8, 8, 4, 4, 4, 2, 8, 8, 4, 4, 4, 4, 4, 8, 8, 4, 4, 4, 2 }; const int happyBirthdayLength = sizeof(happyBirthdayMelody) / sizeof(happyBirthdayMelody[0]); // --- Song 2: Jingle Bells --- const int jingleBellsMelody[] = { NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_G4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_F4, NOTE_F4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_E4, NOTE_D4, NOTE_G4 }; const int jingleBellsDurations[] = { 4, 4, 2, 4, 4, 2, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4, 4, 4, 8, 8, 4, 4, 4, 4, 2 }; const int jingleBellsLength = sizeof(jingleBellsMelody) / sizeof(jingleBellsMelody[0]); // --- Function declarations --- void playSong(const int melody[], const int durations[], int songLength); void updateLeds(int noteIndex, bool isQuietNote); void turnOffBothLeds(); /** * @brief Sets up the pins and the serial port once at start. */ void setup() { Serial.begin(115200); pinMode(TOUCH_1_PIN, INPUT); pinMode(TOUCH_2_PIN, INPUT); pinMode(BUZZER_PIN, OUTPUT); pinMode(LED_A_PIN, OUTPUT); pinMode(LED_B_PIN, OUTPUT); // these LEDs light on LOW, so HIGH keeps them dark at start turnOffBothLeds(); Serial.println(F("Active-Low LED Music Box Jukebox Ready.")); } /** * @brief Polls both touch sensors and starts a song when one is touched. */ void loop() { if (digitalRead(TOUCH_1_PIN) == HIGH) { Serial.println(F("Touch 1 detected: Playing Happy Birthday...")); playSong(happyBirthdayMelody, happyBirthdayDurations, happyBirthdayLength); } else if (digitalRead(TOUCH_2_PIN) == HIGH) { Serial.println(F("Touch 2 detected: Playing Jingle Bells...")); playSong(jingleBellsMelody, jingleBellsDurations, jingleBellsLength); } } /** * @brief Plays every note of a song while the LEDs flash in step. * @param melody List of note pitches. * @param durations List of matching note lengths. * @param songLength How many notes the song has. */ void playSong(const int melody[], const int durations[], int songLength) { for (int thisNote = 0; thisNote < songLength; thisNote++) { bool isQuietNote = (melody[thisNote] == 0); int noteDuration = 1000 / durations[thisNote]; // flash the LEDs for this note updateLeds(thisNote, isQuietNote); tone(BUZZER_PIN, melody[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); noTone(BUZZER_PIN); turnOffBothLeds(); // HIGH on both pins switches the LEDs off } Serial.println(F("Song finished. LEDs reset to standby (HIGH).")); } /** * @brief Picks which LED lights for a note (LOW = on, HIGH = off). * @param noteIndex Position of the note in the song. * @param isQuietNote True when the note is a silent rest. */ void updateLeds(int noteIndex, bool isQuietNote) { if (isQuietNote) { turnOffBothLeds(); return; } // the two LEDs take turns if (noteIndex % 2 == 0) { digitalWrite(LED_A_PIN, LOW); // LED A on digitalWrite(LED_B_PIN, HIGH); // LED B off } else { digitalWrite(LED_A_PIN, HIGH); // LED A off digitalWrite(LED_B_PIN, LOW); // LED B on } } /** * @brief Sets both LED pins HIGH so both LEDs go dark. */ void turnOffBothLeds() { digitalWrite(LED_A_PIN, HIGH); digitalWrite(LED_B_PIN, HIGH); }
Part Uno Pin
Touch sensor 1 (Happy Birthday) D2 (GPIO26)
Touch sensor 2 (Jingle Bells) D3 (GPIO25)
LED A D4 (GPIO17)
LED B D5 (GPIO16)
Buzzer D6 (GPIO27)

ESP32 Uno vs UNO R4 for This Project

By the end of this part, you know what changes when you move this touch project from the UNO R4 to the ESP32 Uno.

Item Arduino UNO R4 ESP32 Uno
Logic voltage 5V 3.3V
Sensor power 5V or 3.3V 3.3V
Sensor pin in code 7 14 (D7 is GPIO14)
Demo buzzer pin 8 27 (D6 is GPIO27)
Arduino IDE board Arduino UNO R4 WiFi ESP32 Dev Module
USB chip none needed CH340 driver
Wireless WiFi on R4 WiFi only WiFi and Bluetooth

The sensor wires stay on the same header positions as the UNO R4. Only the demo buzzer moves to D6 (GPIO27), because D8 (GPIO12) is a boot pin on the ESP32 Uno. Just power the sensor from 3.3V and write GPIO numbers in code.

Go Wireless: Touch Alerts on Your Phone

By the end of this part, you have an idea to show the touch state on a phone.

The ESP32 Uno has WiFi and Bluetooth. You can send the touch state to a web page or a phone app, so a tap on the pad shows up as a message on your screen. This works well for a doorbell pad or a "someone is here" alert.

Troubleshooting

Problem Possible Cause Solution
No COM port in Arduino IDE CH340 driver missing or a charge-only cable Install the CH340 driver and use a USB cable that carries data
Failed to connect or Waiting for download Board is not in upload mode Hold the BOOT button when the upload starts
Serial Monitor shows 0 all the time SIGNAL wire loose or sensor has no power Check VCC on 3.3V, GND and the wire to D7 (GPIO14)
Serial Monitor shows 1 all the time SIGNAL wire is on a wrong pin or the pad is touched at power-on Move the wire to D7 and do not touch the pad while the board starts
Garbage text in Serial Monitor Wrong baud rate Set the baud rate to 9600
Value flickers 0 and 1 Wire loose or noise from long wires Use short jumper wires and press them in firmly
Sensor gets warm or board resets 5V on the SIGNAL line or short circuit Power the sensor from 3.3V and check the wiring
Code does not compile Wrong board selected Choose ESP32 Dev Module

FAQ

How does a capacitive touch sensor work?

The chip on the module senses the small change in capacitance when your finger comes near the pad. It then switches the SIGNAL pin to HIGH. When the finger leaves, the pin goes back to LOW.

Should I use 3.3V or 5V for the sensor?

Use 3.3V. The module works at 3.3V, and the SIGNAL output then matches the 3.3V logic of the ESP32 Uno. A 5V output is not safe for the board pins.

Can I use another pin than D7?

Yes. Any normal digital pin works. Change the number in #define SENSOR_PIN. Stay away from D0, D1 (USB serial) and the strapping pins.

Do I need a pull-up resistor?

No. The module drives the SIGNAL line itself, both HIGH and LOW. That is why the sketch uses plain INPUT.

Can I use A2 to A5 for the sensor?

Yes, because the sensor only gives a signal. Those pins are input only, which is fine here. They have no internal pull-up, but this sensor does not need one.

How do I use two touch sensors?

Give each sensor its own pin, like in the video demo with D2 (GPIO26) and D3 (GPIO25). Read each pin with its own digitalRead() call.

Does the ESP32 Uno have built-in touch pins?

The chip has capacitive touch inputs, but they are not on the Uno headers of this board. This tutorial uses an external touch module on a normal digital pin, which is simpler.

Do I have to rewrite the UNO R4 sketch?

Only the pin number changes. D7 is GPIO14, so the code uses 14 instead of 7. The logic is the same.

Can I show the touch state on my phone with the ESP32 Uno?

Yes. The ESP32 Uno has WiFi and Bluetooth. See the Go Wireless section for web and Bluetooth monitor tutorials.

What if my project needs more pins than the Uno headers give?

The board has a few extra holes near the power header: GPIO32 and GPIO33 (I/O, PWM, analog on ADC1, so they also work while WiFi is on) and GPIO15 (I/O, PWM, analog on ADC2). Solder pin headers on them first, then use the GPIO number in your sketch. For a touch sensor, GPIO32 or GPIO33 is the best choice. Two warnings: (1) GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC position) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code, so use GPIO32 and GPIO33 first. (2) Never use the six holes under the digital header (SD0-SD3, CMD, CLK = GPIO6-GPIO11). They are wired to the flash chip, and using them crashes the board.

Learn More

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!