ESP32 S3 - Motion Sensor - Piezo Buzzer

This tutorial shows you how to connect an HC-SR501 motion sensor and a piezo buzzer to an ESP32 S3 board and program it to react to movement with sound. You will build two practical projects: one that plays a simple tone when motion is detected, and another that plays a full melody triggered by movement.

What you'll build:

  1. A motion-triggered simple sound alert using the ESP32 S3 and HC-SR501 sensor
  2. A motion-triggered melody player using a passive piezo buzzer
  3. Automatic sound stop when no motion is detected
  4. A foundation for real-world security and notification systems

Overview of Piezo Buzzer and Motion Sensor

The HC-SR501 is a passive infrared (PIR) motion sensor that detects movement by measuring infrared radiation emitted from warm bodies such as humans or animals. The piezo buzzer converts electrical signals into audible tones, making it an ideal output device for motion-triggered alerts. Together, these two components form the core of many practical security and notification systems.

We have specific tutorials about piezo buzzer and motion sensor. Each tutorial contains detailed information and step-by-step instructions about hardware pinout, working principle, wiring connection to ESP32 S3, and ESP32 S3 code. Learn more about them at the following links:

Key Specifications

  • HC-SR501 operating voltage: 5V–20V DC
  • HC-SR501 detection range: up to 7 meters (adjustable)
  • HC-SR501 detection angle: up to 120°
  • Active piezo buzzer voltage: 3–24V DC
  • Passive piezo buzzer: requires PWM signal to produce tones and melodies

Please note that this tutorial uses a 3–5V buzzer, but you can adapt it for a 12V buzzer. You can learn more about buzzer options in the ESP32 S3 - Buzzer tutorial.

Wiring Diagram

Connect the HC-SR501 motion sensor and piezo buzzer to your ESP32 S3 following the diagrams below, making sure to observe proper polarity for both components.

The wiring diagram with power supply from USB cable

The wiring diagram between ESP32 S3 Motion Sensor Piezo Buzzer

This image is created using Fritzing. Click to enlarge image

Loose wires are a common cause of strange bugs. To do that, mount the ESP32 S3 on a Screw Terminal Block for ESP32 S3. This is how it looks with the screw terminal board:

The wiring diagram between ESP32 S3 Motion Sensor Piezo Buzzer Screw Terminal

This image is created using Fritzing. Click to enlarge image

Here is the same circuit with a GPIO Breakout Board for ESP32 S3, which breaks out every GPIO to pin headers:

The wiring diagram between ESP32 S3 Motion Sensor Piezo Buzzer GPIO Breakout Board

This image is created using Fritzing. Click to enlarge image

The wiring diagram with power supply from 5V adapter

The wiring diagram between ESP32 S3 Motion Sensor Piezo Buzzer  5V power adapter

This image is created using Fritzing. Click to enlarge image

Jumper wires can come loose when you move the project. The ESP32 S3 fits a Screw Terminal Block for ESP32 S3, which turns every pin into a screw terminal. See the diagram below for the screw terminal version.

The wiring diagram between ESP32 S3 Motion Sensor Piezo Buzzer  5V power adapter Screw Terminal

This image is created using Fritzing. Click to enlarge image

Another choice is a GPIO Breakout Board for ESP32 S3. Each GPIO has a signal pin with 3.3V and GND pins next to it, as shown below:

The wiring diagram between ESP32 S3 Motion Sensor Piezo Buzzer  5V power adapter GPIO Breakout Board

This image is created using Fritzing. Click to enlarge image

Safety Notes

The HC-SR501 sensor requires 5V–20V on its VCC pin, while the ESP32 S3 GPIO pins operate at 3.3V logic levels. The sensor's output signal is typically 3.3V, which is compatible with ESP32 S3 inputs. Always double-check that the buzzer's positive terminal connects to the designated GPIO pin and the negative terminal connects to GND to avoid reversed polarity.

Initial Setting

Detection Range Adjuster Fully screw it in the clockwise direction.
Time Delay Adjuster Fully screw it in the anti-clockwise direction.
Repeat Trigger Selector Put jumper like the below image.
ESP32 S3 motion sensor initial setting

ESP32 S3 Code - Simple Sound

The following code programs the ESP32 S3 to monitor the HC-SR501 motion sensor and immediately activate the piezo buzzer whenever motion is detected. When no motion is present, the buzzer remains silent, creating a straightforward audible alert system. Upload this sketch to your ESP32 S3 and test it by moving your hand in front of the sensor.

/* * This ESP32 S3 code was developed by newbiely.com * * This ESP32 S3 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3/esp32-s3-motion-sensor-piezo-buzzer */ /* * This ESP32-S3 code is created by esp32io.com * * This ESP32-S3 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-s3-motion-sensor-piezo-buzzer */ #define MOTION_SENSOR_PIN 42 // ESP32-S3 pin GPIO42 connected to the OUTPUT pin of motion sensor #define BUZZER_PIN 41 // ESP32-S3 pin GPIO41 connected to Buzzer's pin int motionStateCurrent = LOW; // current state of motion sensor's pin int motionStatePrevious = LOW; // previous state of motion sensor's pin void setup() { Serial.begin(9600); // initialize serial pinMode(MOTION_SENSOR_PIN, INPUT); // set ESP32-S3 pin to input mode pinMode(BUZZER_PIN, OUTPUT); // set ESP32-S3 pin to output mode } void loop() { motionStatePrevious = motionStateCurrent; // store old state motionStateCurrent = digitalRead(MOTION_SENSOR_PIN); // read new state if (motionStatePrevious == LOW && motionStateCurrent == HIGH) { // pin state change: LOW -> HIGH Serial.println("Motion detected!, making sound"); digitalWrite(BUZZER_PIN, HIGH); // turn on } else if (motionStatePrevious == HIGH && motionStateCurrent == LOW) { // pin state change: HIGH -> LOW Serial.println("Motion stopped!, stops making sound"); digitalWrite(BUZZER_PIN, LOW); // turn off } }

Detailed Instructions

  1. New to ESP32 S3? Complete our Getting Started with ESP32 S3 guide first.
  2. Do the wiring as shown in the diagram above.
  3. Connect the ESP32 S3 board to your PC via a USB Type-C cable.
  4. Open Arduino IDE on your PC.
  5. Select the right ESP32 S3 board and COM port.
  6. Copy the above code and paste it to Arduino IDE.
  7. Compile and upload the code to the ESP32 S3 board by clicking the Upload button in Arduino IDE.
  8. Move your hand in front of the sensor.
  9. Listen to the piezo buzzer's sound.
  10. Pro Tip: Adjust the HC-SR501's sensitivity and delay potentiometers to fine-tune detection range and how long the buzzer sounds after motion stops.

Line-by-line Code Explanation

The above ESP32 S3 code contains line-by-line explanation. Please read the comments in the code!

ESP32 S3 Code - Melody

The following code extends the project by playing a full musical melody through a passive piezo buzzer whenever the HC-SR501 detects motion. This approach uses PWM frequency control to generate distinct musical notes, and playback stops automatically when no motion is detected. Follow the steps below to set up the pitches header file required by this sketch.

/* * This ESP32 S3 code was developed by newbiely.com * * This ESP32 S3 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3/esp32-s3-motion-sensor-piezo-buzzer */ /* * This ESP32-S3 code is created by esp32io.com * * This ESP32-S3 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-s3-motion-sensor-piezo-buzzer */ #include "pitches.h" #define MOTION_SENSOR_PIN 42 // ESP32-S3 pin GPIO42 connected to the OUTPUT pin of motion sensor #define BUZZER_PIN 41 // ESP32-S3 pin GPIO41 connected to Buzzer's pin // notes in the melody: int melody[] = { NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_G5, NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, NOTE_F5, NOTE_F5, NOTE_F5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_D5, NOTE_D5, NOTE_E5, NOTE_D5, NOTE_G5 }; // note durations: 4 = quarter note, 8 = eighth note, etc, also called tempo: int noteDurations[] = { 8, 8, 4, 8, 8, 4, 8, 8, 8, 8, 2, 8, 8, 8, 8, 8, 8, 8, 16, 16, 8, 8, 8, 8, 4, 4 }; void setup() { Serial.begin(9600); // initialize serial pinMode(MOTION_SENSOR_PIN, INPUT); // set ESP32-S3 pin to input mode } void loop() { int motionState = digitalRead(MOTION_SENSOR_PIN); // read new state if (motionState == HIGH) { Serial.println("The motion is detected"); buzzer(); } } void buzzer() { // iterate over the notes of the melody: int size = sizeof(noteDurations) / sizeof(int); for (int thisNote = 0; thisNote < size; thisNote++) { // to calculate the note duration, take one second divided by the note type. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. int noteDuration = 1000 / noteDurations[thisNote]; tone(BUZZER_PIN, melody[thisNote], noteDuration); // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); // stop the tone playing: noTone(BUZZER_PIN); } }

Detailed Instructions

  1. New to ESP32 S3? Complete our Getting Started with ESP32 S3 guide first.
  2. Copy the above code and paste it to Arduino IDE.
  3. Create the pitches.h file in Arduino IDE by:
  • Either click on the button just below the serial monitor icon and choose New Tab, or use Ctrl+Shift+N keys.
Arduino IDE 2 adds file
  • Give the file's name pitches.h and click the OK button.
Arduino IDE 2 adds file pitches.h
  • Copy the below code and paste it to the created pitches.h file.
/************************************************* * Public Constants *************************************************/ #define NOTE_B0 31 #define NOTE_C1 33 #define NOTE_CS1 35 #define NOTE_D1 37 #define NOTE_DS1 39 #define NOTE_E1 41 #define NOTE_F1 44 #define NOTE_FS1 46 #define NOTE_G1 49 #define NOTE_GS1 52 #define NOTE_A1 55 #define NOTE_AS1 58 #define NOTE_B1 62 #define NOTE_C2 65 #define NOTE_CS2 69 #define NOTE_D2 73 #define NOTE_DS2 78 #define NOTE_E2 82 #define NOTE_F2 87 #define NOTE_FS2 93 #define NOTE_G2 98 #define NOTE_GS2 104 #define NOTE_A2 110 #define NOTE_AS2 117 #define NOTE_B2 123 #define NOTE_C3 131 #define NOTE_CS3 139 #define NOTE_D3 147 #define NOTE_DS3 156 #define NOTE_E3 165 #define NOTE_F3 175 #define NOTE_FS3 185 #define NOTE_G3 196 #define NOTE_GS3 208 #define NOTE_A3 220 #define NOTE_AS3 233 #define NOTE_B3 247 #define NOTE_C4 262 #define NOTE_CS4 277 #define NOTE_D4 294 #define NOTE_DS4 311 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_FS4 370 #define NOTE_G4 392 #define NOTE_GS4 415 #define NOTE_A4 440 #define NOTE_AS4 466 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_CS5 554 #define NOTE_D5 587 #define NOTE_DS5 622 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_FS5 740 #define NOTE_G5 784 #define NOTE_GS5 831 #define NOTE_A5 880 #define NOTE_AS5 932 #define NOTE_B5 988 #define NOTE_C6 1047 #define NOTE_CS6 1109 #define NOTE_D6 1175 #define NOTE_DS6 1245 #define NOTE_E6 1319 #define NOTE_F6 1397 #define NOTE_FS6 1480 #define NOTE_G6 1568 #define NOTE_GS6 1661 #define NOTE_A6 1760 #define NOTE_AS6 1865 #define NOTE_B6 1976 #define NOTE_C7 2093 #define NOTE_CS7 2217 #define NOTE_D7 2349 #define NOTE_DS7 2489 #define NOTE_E7 2637 #define NOTE_F7 2794 #define NOTE_FS7 2960 #define NOTE_G7 3136 #define NOTE_GS7 3322 #define NOTE_A7 3520 #define NOTE_AS7 3729 #define NOTE_B7 3951 #define NOTE_C8 4186 #define NOTE_CS8 4435 #define NOTE_D8 4699 #define NOTE_DS8 4978
  1. Compile and upload the code to the ESP32 S3 board by clicking the Upload button in Arduino IDE.
  2. Move your hand in front of the sensor.
  3. Listen to the piezo buzzer's melody.
  4. Pro Tip: Try swapping the melody array with your own note sequence in the sketch to personalize the alert tune.

Line-by-line Code Explanation

The above ESP32 S3 code contains line-by-line explanation. Please read the comments in the code!

※ NOTE THAT:

The above code uses the delay() function. This blocks other code during melody playback. To avoid blocking other code, use the ezBuzzer library instead. This library is designed for the buzzer to beep or play a melody without blocking other code.

Serial Monitor Output

Open the Serial Monitor in Arduino IDE (set baud rate to 9600) after uploading the code. You should see output similar to the following readings, with timestamps reflecting the moments motion is detected and cleared.

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
2026-06-16 08:12:03 - Motion detected — buzzer ON 2026-06-16 08:12:07 - No motion — buzzer OFF 2026-06-16 08:12:45 - Motion detected — buzzer ON 2026-06-16 08:12:52 - No motion — buzzer OFF
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

Applications

Motion-triggered buzzer systems built with the ESP32 S3 are practical and versatile components for a wide range of real-world projects across home, office, and industrial environments.

  1. Home Security Alert: Sound an alarm when an intruder enters a room or restricted area.
  2. Doorbell System: Automatically beep when someone approaches a door or entrance.
  3. Child Safety Monitor: Alert parents when a child enters a hazardous area such as a staircase or pool zone.
  4. Retail Customer Greeter: Play a welcome tone when a customer walks into a shop.
  5. Wildlife Detection: Trigger a buzzer when animals approach a garden or protected area.
  6. Office Occupancy Indicator: Sound an alert when someone enters an unoccupied meeting room.

Video Tutorial

Watch the step-by-step video walkthrough for this ESP32 S3 project below.

Challenges

These challenges are designed to push your understanding of the ESP32 S3, motion sensing, and buzzer control beyond the basics presented in this tutorial.

  1. Beginner: Modify the code so the buzzer beeps three times (short pulses) instead of sounding continuously when motion is detected.
  2. Intermediate: Add an LED indicator alongside the buzzer so both light and sound activate together when motion is detected, and both turn off when motion stops.
  3. Advanced: Implement a time-based mute feature using the ESP32 S3's internal clock so the buzzer is disabled during nighttime hours (e.g., 10 PM to 7 AM) even when motion is detected.

※ 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!