iotdata, by Data Frontieriot
data
Block coding

Active and passive buzzers: making the robot beep and play notes

The difference between active and passive buzzers, how to tell which one you have, how to play notes with tone() on Arduino and PWM on the ESP32, minding the pin current, and what tone() does to pins 3 and 11 on the Nano.

Data Frontier Engineering· Published October 22, 2026

The buzzer is the robot's voice. It looks like the simplest part in the kit, but there are two types that look alike on the outside and work differently, and mixing one up with the other is the number one reason for "the buzzer won't sound".

Active and passive

An active buzzer has an oscillator inside. Just apply power and it beeps, always at the same pitch, usually somewhere between 2 kHz and 3 kHz. To the program, it's like an LED: pin high, it beeps; pin low, it goes quiet.

A passive buzzer is just the vibrating element. On DC voltage, it clicks once and stays silent. To make a sound, it needs a square wave, and the frequency of that wave is the note. In exchange for the extra work, it plays melodies.

How to tell which one you have

  • The definitive test: connect the buzzer to 5 V (or 3.3 V) for a moment. A continuous beep: active. Just a click: passive.
  • Visual clue: many active buzzers have a sealed bottom with a sticker on top; many passive ones show the circuit board underneath. It's not a rule, just a clue.
  • Polarity: the active one is polarized; the longer leg or the "+" marking goes to the pin.

In the block coding IDE, the buzzer card asks for the type. For an active buzzer, it switches the pin on and off; for a passive one, it generates the frequency.

Playing notes

Some reference frequencies (tuned to A = 440 Hz):

NoteFrequency
C5523 Hz
D5587 Hz
E5659 Hz
G5784 Hz
A5880 Hz

For an alert, short high-pitched sounds work best: 2,000 Hz for 100 ms gets attention without being annoying. Two rising notes sound like "it worked"; two falling ones, like "error".

On the Arduino Nano

The tone(pin, frequency, duration) function generates the square wave on any pin, and noTone(pin) silences it. Two things to keep in mind:

  • Only one tone at a time. While a tone() is playing on one pin, calling tone() on another pin has no effect.
  • tone() uses timer 2, so it interferes with PWM (analogWrite) on pins 3 and 11 while it plays. Servos driven by the Servo library are not affected, because that library uses a different timer.

On the ESP32 with MicroPython

The ESP32's PWM does the job of tone: the frequency is the note, and a 50% duty cycle gives the square wave.

from machine import Pin, PWM
import time

buzzer = PWM(Pin(23), freq=2000, duty_u16=32768)
time.sleep_ms(100)
buzzer.duty_u16(0)   # silence

Pin current

The small buzzers that come in kits draw a few tens of milliamps, close to the recommended limit for a microcontroller pin (about 20 mA on the Nano's ATmega328P). For a louder buzzer, use a transistor as a switch: the pin drives the transistor, and the transistor switches the buzzer.

On the robot arm

The arm's buzzer confirms what the operator did: a short beep when a position is recorded, two beeps at the end of the playback, a continuous tone while an object is close to the sensor. In the block coding IDE, the "Beep the buzzer" card asks for the pin, the type and the duration, and the "Play a note" card takes the note by name.