Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

Day 6 of 30 · about 30 minutes

Buzzers and tone(): build a doorbell

Today you build: A push-button doorbell that plays ding-dong

  • Read 4 min
  • Spot active vs passive 2 min
  • Wire the buzzer 5 min
  • Upload & test 4 min
  • Try it 15 min

Community draft — report a mistake

Week one was all light. Today the board makes sound, using the button you wired on day 3.

Active or passive buzzer?

Kits in India usually include both, and they look almost the same:

  • Active buzzer — has its own oscillator inside. Give it 5 V and it beeps at one fixed pitch. Usually has a sticker on top and a sealed bottom.
  • Passive buzzer — just a tiny speaker. It stays silent until you feed it a changing signal, so you choose the pitch. Usually the green circuit board shows underneath.

Today needs a passive buzzer. If yours only clicks or plays the same note whatever the code says, it’s an active one — swap it.

Wiring

  • Buzzer: + leg through a 100 Ω resistor to pin 8, other leg to GND. The resistor keeps the current well inside the pin’s limit. (A passive buzzer module with three pins goes S → pin 8, + → 5V, − → GND.)
  • Button: same as day 3 — one leg to pin 2, the diagonal leg to GND.

How tone() works

tone(pin, frequency, duration) switches the pin on and off frequency times per second. 659 times a second sounds like the note E; 523 sounds like C. The third number is how long to play, in milliseconds.

The catch: tone() returns immediately and plays in the background. If you call it twice in a row, the second note replaces the first before you hear it. That’s why each note is followed by a delay() slightly longer than the note.

The while loop at the end waits for you to let go of the button, so one press rings once instead of repeating like a siren.

Try it

  • Look up note frequencies (A4 is 440 Hz) and play the first line of a song you know.
  • Use noTone(8) to stop a tone early.
  • tone() borrows one of the Uno’s hardware timers, which stops PWM on pins 3 and 11 while a tone plays. Remember that when a project dims an LED and beeps at the same time.

You’re done when…

  • Each press plays a clear two-note ding-dong and prints Ding-dong! once in the Serial Monitor (9600 baud).
  • Holding the button down rings once, not over and over.
  • Your buzzer is a passive one: changing NOTE_E5 to 440 changes the pitch you hear.
  • You can play the first line of a tune of your choice.

Tomorrow you’ll get rid of delay() so the board can do two things at once.

Today's code

Verified — core avr 1.8.8, 3 Nov 2026Compile-only
lesson-tone.inoArduino C++Open in PlaygroundOpen in Playground
// Day 6 — Buzzers and tone() (Arduino Uno / Nano)
// Passive buzzer: + through a 100 ohm resistor to pin 8, - to GND.
// Push button between pin 2 and GND (INPUT_PULLUP, as on day 3).
// Press the button and the buzzer plays a two-note "ding-dong".

const int BUZZER_PIN = 8;
const int BUTTON_PIN = 2;

// Note frequencies in hertz (vibrations per second).
const int NOTE_E5 = 659;
const int NOTE_C5 = 523;

void setup() {
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(BUZZER_PIN, OUTPUT);
  Serial.println(F("Doorbell ready. Press the button."));
}

void loop() {
  if (digitalRead(BUTTON_PIN) == LOW) {          // LOW = pressed
    Serial.println(F("Ding-dong!"));
    tone(BUZZER_PIN, NOTE_E5, 400);              // 659 Hz for 400 ms...
    delay(450);                                  // ...tone() returns at once, so wait here
    tone(BUZZER_PIN, NOTE_C5, 600);
    delay(650);
    while (digitalRead(BUTTON_PIN) == LOW) delay(10);  // one ring per press, not a siren
  }
}

↑↓ to move · Enter to open