Turn an Arduino and a simple piezo buzzer into a programmable musical instrument that can play any melody at any tempo.
Creates precise musical notes by rapidly toggling a pin on and off at specific speeds. Play "You Are My Sunshine" at 115 BPM, or compose your own melodies using a 12-note chromatic scale. This project demonstrates how to transform basic digital signals into music by understanding the physics of sound.
Demo Songs Included:
- Simple 4-note pattern (120 BPM)
- "You Are My Sunshine" - complete melody with 78 notes (115 BPM)
The code generates sound by exploiting a simple principle: sound is just rapid vibration.
- Calculate the frequency: Each musical note has a specific frequency (e.g., middle A = 440 Hz)
- Toggle the pin: Turn the buzzer on and off 440 times per second to create that note
- Sustain for duration: Keep toggling for the exact length of time the note should play
- Repeat: Move to the next note in your melody
The result? A $2 piezo buzzer becomes a programmable musical instrument capable of playing any song.
- How speakers actually work: Rapidly vibrating a membrane creates sound waves - toggle it 440 times per second, get an A note
- The three properties of any sound: Amplitude (volume), Frequency (pitch), and Phase (timing offset)
- Why some components work and others don't: Passive buzzers let you control frequency directly; active buzzers have a fixed internal tone
- Microseconds vs milliseconds: Audio needs microsecond precision (1/1,000,000 second) to create accurate pitches, while note durations use milliseconds
- The math behind music: Converting "440 Hz" into exact timing: each vibration takes 2,272 microseconds (half on, half off)
- Non-blocking timing: Playing a sustained note while tracking its duration using timestamps instead of simple delays
- Musical scales in memory: Storing the 12-note chromatic scale (A, A#, B, C...) as an array of frequencies starting from A=440 Hz
- Tempo control: Converting BPM (beats per minute) to milliseconds per beat for rhythmic playback
- Octaves: Doubling the frequency raises a note by one octave (e.g., A=440 Hz → A=880 Hz)
- From physics to music: Why A=440 Hz became the universal concert pitch standard
While debugging why one buzzer sounded "scratchy," I accidentally discovered:
- Amplitude Modulation (AM): The same technique AM radio uses to broadcast - and why my active buzzer created distorted tones
- How radios tune to stations: LC circuits create resonance at specific frequencies, filtering everything else out
- Why analogWrite() doesn't work: PWM is fixed at ~490 Hz, perfect for LED brightness but terrible for variable-pitch audio
arduino_sound_engineering/
├── play_notes_on_passive_buzzer/
│ └── play_notes_on_passive_buzzer.ino # Basic note player with manual composition
└── play_you_are_my_sunshine_on_passive_buzzer/
└── play_you_are_my_sunshine_on_passive_buzzer.ino # Advanced song player with MusicNote struct
Version 1 (play_notes_on_passive_buzzer): Basic building blocks
- Individual note playback with
playNote(note, duration, octave) - Manual timing and delays between notes
- Good for learning and experimenting
Version 2 (play_you_are_my_sunshine_on_passive_buzzer): Structured composition
MusicNotestruct bundles note + duration + octave togetherplaySong()function plays an entire melody from an array- Complete implementation of "You Are My Sunshine"
- Cleaner, more maintainable code for complex songs
What You Need:
- Arduino (any model with digital pins)
- Passive piezo buzzer (NOT an active buzzer)
- 2 jumper wires
Wiring:
- Buzzer positive (+) → Arduino Pin 9
- Buzzer negative (-) → Arduino GND
✨ 12-Note Chromatic Scale: Play any note from A to G# with sharps/flats
🎵 BPM-Based Timing: Musical tempo control using beats per minute
🎹 Octave Support: Shift notes up or down across octaves
⏸️ Rest Support: Silent pauses between notes for rhythm
📊 Serial Debugging: Real-time logging of note name, frequency, octave, and duration
🎼 Song Arrays: Store entire melodies as data structures
Started with: "Make a buzzer beep"
Ended with: Understanding wave physics, signal processing, and why your car radio can pick one station out of hundreds
A seemingly simple project that opened doors to acoustics, electronics, radio theory, and the beautiful intersection of math and music. What began as toggling a pin HIGH and LOW became a deep dive into how sound works at a fundamental level - from the vibration of air molecules to the mathematical relationships that make music sound "right" to our ears.
- Make
playNote()acceptMusicNotestruct directly - Add volume control through varying duty cycles
- Implement more complex note timing (dotted notes, triplets)
- Create a music notation parser (convert sheet music to code)
- Add multiple voice/harmony support
- Build a web interface to compose songs visually
From basic electronics to the physics of sound - one beep at a time. 🔊