Arduino Buzzer Sound Generation Project (Wokwi Simulation) – Beginner to Advanced

Buzzer Sound Generation using Arduino Uno | MakeMindz
🔊 Lesson 6 · Sound & Output

Buzzer Sound Generation
using Arduino Uno

Play 10 awesome sound modes — sirens, alarms, and melodies — with just a piezo buzzer and one button. No music knowledge needed!

🟢 Beginner ⚡ Arduino Uno 🔔 Piezo Buzzer 🎵 tone() Function ⚡ Interrupts ⏱ 45 min
Run Free Simulation on Wokwi

🔊 Project Overview

In this project, a piezo buzzer on Pin 8 generates different sounds each time you press a push button on Pin 2. An LED on Pin 13 blinks to show which mode is active — the number of blinks = the mode number.

💡

Key concept: We use hardware interrupts so the button works instantly — even while a long melody is playing. This is a real embedded systems technique used in professional products!

🛒 Components Required

🟦
Arduino Uno
× 1
🔔
Piezo Buzzer
× 1
🟢
Push Button
× 1
💡
LED (Red)
× 1
🟫
220Ω Resistor
× 1
🔌
Jumper Wires
× 7+

🌐

No hardware yet? Run the full simulation instantly on Wokwi — all components are virtual and the buzzer actually plays sound in your browser!

🔧 Circuit Connections

ComponentArduino PinWire Color
Buzzer (+)Pin 8Green
Buzzer (−)GNDBlack
Push ButtonPin 2Blue
Button other legGNDBlack
LED Anode (+)Pin 13 via 220ΩRed
LED Cathode (−)GNDBlack
STEP 01
Connect the Buzzer

Buzzer positive (+) leg → Pin 8. Negative (−) leg → GND. The buzzer generates sound when Arduino sends a square wave signal.

STEP 02
Connect the Push Button

One leg → Pin 2, other leg → GND. We use INPUT_PULLUP in code — so no external resistor is needed!

STEP 03
Connect the LED

LED longer leg (+) → 220Ω resistorPin 13. Shorter leg (−) → GND. The LED blinks to show the current sound mode number.

🎵 10 Sound Modes

Press the button to cycle through all 10 modes. The LED blinks once for Mode 0, twice for Mode 1, and so on — so you always know which mode is active!

MODE 0
🔔
Simple Beeps
● 1 blink
MODE 1
🚨
Alarm Sound
●● 2 blinks
MODE 2
🚓
Police Siren
●●● 3 blinks
MODE 3
🚑
Ambulance
●●●● 4 blinks
MODE 4
🔔
Door Bell
●●●●● 5 blinks
MODE 5
🎂
Happy Birthday
6 blinks
MODE 6
Twinkle Star
7 blinks
MODE 7
🍄
Mario Theme
8 blinks
MODE 8
🌌
Star Wars
9 blinks
MODE 9
📱
Nokia Ringtone
10 blinks

🎼 How tone() Works

The tone(pin, frequency) function sends a square wave to the buzzer pin. The frequency in Hz determines the pitch of the sound:

500 Hz
Low pitch
1000 Hz
Medium pitch
1500 Hz
High pitch

Musical Note Frequencies (defined in code)

NOTE_C4 = 262

Middle C — the most common starting note for melodies

NOTE_G4 = 392

G above middle C — used in Happy Birthday, Twinkle

NOTE_A4 = 440

Concert A — the international tuning reference frequency

REST = 0

Silence between notes — passes 0 to tone() to pause

noTone(pin)

Stops sound immediately — called between notes for clean gaps

Interrupt Programming

Why use interrupts instead of reading the button in loop()?

When playing a melody, the Arduino is busy running delay() for each note. Without interrupts, button presses would be missed! An interrupt "pauses" the main code instantly when the button is pressed — then resumes exactly where it left off.

attachInterrupt()

Registers a function to run instantly when the button pin falls LOW

FALLING

Triggers when the pin goes from HIGH to LOW — i.e., button is pressed down

volatile

Tells the compiler this variable can change from an ISR — prevents optimization bugs

Debouncing (200ms)

Ignores extra triggers from mechanical button bounce — ensures one press = one mode change

🎵 Hear It in Your Browser — Free!

The Wokwi simulation plays actual buzzer sounds through your speakers. Click the button in the simulation to switch between all 10 modes!

Open Wokwi Simulation

🗺️ Wokwi Diagram.json

Paste this into the diagram.json tab in your Wokwi project to instantly recreate the full circuit — all components placed and wired for you.

💡

How to use: Open Wokwi → New Project → Arduino Uno → click the diagram.json tab → select all → paste this code → Save.

DIAGRAM.JSON · WOKWI
{
  "version": 1,
  "author": "MakeMindz",
  "editor": "wokwi",
  "parts": [
    {
      "type": "wokwi-arduino-uno",
      "id": "uno",
      "top": 211.8,
      "left": -144.6,
      "attrs": {}
    },
    {
      "type": "wokwi-buzzer",
      "id": "buzzer1",
      "top": 127.2,
      "left": 117,
      "attrs": { "volume": "0.8" }
    },
    {
      "type": "wokwi-led",
      "id": "led1",
      "top": 100,
      "left": 250,
      "attrs": { "color": "red" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r1",
      "top": 110,
      "left": 180,
      "attrs": { "value": "220" }
    },
    {
      "type": "wokwi-pushbutton",
      "id": "btn1",
      "top": 200,
      "left": 50,
      "attrs": { "color": "green" }
    }
  ],
  "connections": [
    [ "uno:8",      "buzzer1:1", "green", [ "v0" ] ],
    [ "buzzer1:2",  "uno:GND.1", "black", [ "v0" ] ],
    [ "uno:13",     "r1:1",      "red",   [ "v0" ] ],
    [ "r1:2",       "led1:A",    "red",   [ "v0" ] ],
    [ "led1:C",     "uno:GND.2", "black", [ "v0" ] ],
    [ "btn1:1.l",   "uno:2",     "blue",  [ "v0" ] ],
    [ "btn1:2.r",   "uno:GND.3", "black", [ "v0" ] ]
  ],
  "dependencies": {}
}

What Each Connection Does

uno:8 → buzzer1:1

Pin 8 drives the buzzer positive terminal — tone() sends the square wave here

buzzer1:2 → GND

Buzzer negative terminal returns to ground to complete the circuit

uno:13 → r1 → led1:A

Pin 13 drives LED through 220Ω resistor to limit current and protect the LED

btn1:1.l → uno:2

Button input to Pin 2 (interrupt-capable pin). INPUT_PULLUP keeps it HIGH until pressed

btn1:2.r → GND

Button other leg to GND — pressing pulls Pin 2 LOW, triggering the FALLING interrupt

💻 Full Arduino Code

Copy the complete code below. No extra libraries needed — tone() is built into Arduino!

ARDUINO · C++
/*
 * Buzzer Sound Generation - 10 Sound Modes
 * MakeMindz Summer Class | makemindz.com
 * Simulation: https://wokwi.com/projects/459575761446808577
 * Press button ANYTIME to change modes!
 */

// ── Pin Definitions ────────────────────
const int buzzerPin = 8;
const int buttonPin = 2;
const int ledPin    = 13;

// ── State Variables ────────────────────
volatile int soundMode  = 0;   // volatile = changed by interrupt
bool modeChanged = true;

// ── Musical Note Frequencies ───────────
#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_B4  494
#define NOTE_C5  523
#define NOTE_D5  587
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_G5  784
#define REST     0

void setup() {
  pinMode(buzzerPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP); // No external resistor needed!
  pinMode(ledPin, OUTPUT);
  
  // Attach interrupt — instant button response
  attachInterrupt(digitalPinToInterrupt(buttonPin), buttonPressed, FALLING);
  
  Serial.begin(9600);
  Serial.println("Buzzer Sound System Ready! Press button to change modes.");
  
  playStartupSound();
}

void loop() {
  if (modeChanged) {
    noTone(buzzerPin);
    showMode();
    modeChanged = false;
  }
  
  switch(soundMode) {
    case 0: simpleBeeps();       break;
    case 1: alarmSound();        break;
    case 2: policeSiren();       break;
    case 3: ambulanceSiren();    break;
    case 4: doorBell();           break;
    case 5: playHappyBirthday(); break;
    case 6: playTwinkleTwinkle(); break;
    case 7: playMarioTheme();    break;
    case 8: playStarWars();      break;
    case 9: playNokiaRingtone(); break;
  }
  delay(100);
}

// ── Interrupt Service Routine ──────────
void buttonPressed() {
  static unsigned long lastTime = 0;
  unsigned long now = millis();
  if (now - lastTime > 200) { // 200ms debounce
    soundMode = (soundMode + 1) % 10;
    modeChanged = true;
  }
  lastTime = now;
}

// ── LED Mode Indicator ─────────────────
void showMode() {
  delay(500);
  for(int i = 0; i <= soundMode; i++) {
    digitalWrite(ledPin, HIGH);
    tone(buzzerPin, 1000, 50);
    delay(150);
    digitalWrite(ledPin, LOW);
    delay(150);
  }
  delay(500);
}

// ── Mode 0: Simple Beeps ───────────────
void simpleBeeps() {
  digitalWrite(ledPin, HIGH);
  tone(buzzerPin, 1000, 200);
  delay(200);
  digitalWrite(ledPin, LOW);
  delay(800);
}

// ── Mode 1: Alarm ──────────────────────
void alarmSound() {
  for(int i = 0; i < 2; i++) {
    digitalWrite(ledPin, HIGH);
    tone(buzzerPin, 1000, 300); delay(300);
    digitalWrite(ledPin, LOW);
    tone(buzzerPin, 500, 300);  delay(300);
  }
  delay(400);
}

// ── Mode 2: Police Siren (sweep) ───────
void policeSiren() {
  for(int f = 500; f < 1500; f += 100) {
    tone(buzzerPin, f, 20);
    digitalWrite(ledPin, HIGH); delay(20);
  }
  for(int f = 1500; f > 500; f -= 100) {
    tone(buzzerPin, f, 20);
    digitalWrite(ledPin, LOW); delay(20);
  }
}

// ── Mode 3: Ambulance ─────────────────
void ambulanceSiren() {
  for(int i = 0; i < 3; i++) {
    digitalWrite(ledPin, HIGH);
    tone(buzzerPin, 600, 150); delay(150);
    digitalWrite(ledPin, LOW);
    tone(buzzerPin, 800, 150); delay(150);
  }
  delay(300);
}

// ── Mode 4: Door Bell ─────────────────
void doorBell() {
  digitalWrite(ledPin, HIGH);
  tone(buzzerPin, 1000, 200); delay(200);
  tone(buzzerPin, 800, 400);  delay(400);
  digitalWrite(ledPin, LOW);
  delay(1000);
}

// ── Helper: Play Melody Array ─────────
void playMelody(int* melody, int* durations, int count) {
  for (int i = 0; i < count; i++) {
    int dur = 1000 / durations[i];
    if (melody[i] == REST) { delay(dur); }
    else {
      digitalWrite(ledPin, HIGH);
      tone(buzzerPin, melody[i], dur);
      delay(dur * 1.2);
      digitalWrite(ledPin, LOW);
      noTone(buzzerPin);
    }
    delay(50);
  }
  delay(1000);
}

// ── Mode 5: Happy Birthday ────────────
void playHappyBirthday() {
  int m[] = {NOTE_C4,NOTE_C4,NOTE_D4,NOTE_C4,NOTE_F4,NOTE_E4,
              NOTE_C4,NOTE_C4,NOTE_D4,NOTE_C4,NOTE_G4,NOTE_F4};
  int d[] = {8,8,4,4,4,2,8,8,4,4,4,2};
  playMelody(m, d, 12);
}

// ── Mode 6: Twinkle Twinkle ───────────
void playTwinkleTwinkle() {
  int m[] = {NOTE_C4,NOTE_C4,NOTE_G4,NOTE_G4,NOTE_A4,NOTE_A4,NOTE_G4,
              NOTE_F4,NOTE_F4,NOTE_E4,NOTE_E4,NOTE_D4,NOTE_D4,NOTE_C4};
  int d[] = {4,4,4,4,4,4,2,4,4,4,4,4,4,2};
  playMelody(m, d, 14);
}

// ── Mode 7: Mario Theme ───────────────
void playMarioTheme() {
  int m[] = {NOTE_E5,NOTE_E5,REST,NOTE_E5,REST,NOTE_C5,NOTE_E5,NOTE_G5};
  int d[] = {8,8,8,8,8,8,8,4};
  playMelody(m, d, 8);
}

// ── Mode 8: Star Wars ─────────────────
void playStarWars() {
  int m[] = {NOTE_A4,NOTE_A4,NOTE_A4,NOTE_F4,NOTE_C5,
              NOTE_A4,NOTE_F4,NOTE_C5,NOTE_A4};
  int d[] = {8,8,8,6,16,8,6,16,4};
  playMelody(m, d, 9);
}

// ── Mode 9: Nokia Ringtone ────────────
void playNokiaRingtone() {
  int m[] = {NOTE_E5,NOTE_D5,NOTE_F4,NOTE_G4,
              NOTE_C5,NOTE_B4,NOTE_D4,NOTE_E4};
  int d[] = {8,8,4,4,8,8,4,4};
  playMelody(m, d, 8);
}

// ── Startup Sound ─────────────────────
void playStartupSound() {
  for(int f = 200; f < 1000; f += 100) {
    tone(buzzerPin, f, 50);
    digitalWrite(ledPin, HIGH); delay(50);
    digitalWrite(ledPin, LOW);  delay(50);
  }
}

🎓 What You Learn

Digital output control
tone() & noTone()
Frequency & pitch basics
Hardware interrupts
Debouncing logic
Playing melodies
volatile keyword
INPUT_PULLUP mode

🚀 Real-World Applications

🔥
Fire Alarms
🏠
Smart Home Alerts
🏫
School Exhibitions
📡
IoT Notifications
⏱️
Timer Alerts
🔒
Security Systems
🤖
Robot Feedback
🎮
Sound Effects

🌐 Why Use Wokwi Simulator?

🖥️
No hardware needed
🔊
Plays real sound in browser
Instant testing
🐛
Easy debugging
🎓
Perfect for learners
🆓
Completely free

Frequently Asked Questions

It generates a square wave at a specific frequency on a digital pin. The piezo buzzer vibrates at that frequency, producing sound. Higher frequency = higher pitch. Use noTone(pin) to stop it.
When playing a melody, the loop() is blocked by delay() calls. An interrupt runs instantly when the button is pressed, no matter what the main code is doing. This makes the button feel responsive.
Mechanical buttons "bounce" — they make and break contact many times in milliseconds. Without debouncing, one button press could register 5–10 times. We ignore presses within 200ms of the last one to fix this.
volatile tells the compiler that the variable soundMode can change from outside the normal program flow (from an interrupt). Without it, the compiler might "optimize" the code incorrectly and miss the change.
Yes! Look up the note frequencies for your song, store them in a melody[] array with matching durations[], then call playMelody(m, d, count). The helper function does the rest!

📚 Full MakeMindz Course Map

🎉 Conclusion

The Buzzer Sound Generation project is a fantastic way to learn Arduino sound control, interrupt programming, and frequency-based melody composition.

You learned how tone() generates pitches, how interrupts respond instantly to button presses, and how melody arrays can encode real songs. Try the simulation, then build your own sound mode!

Comments

try for free