# ================================================
# π΅ Playing Music with a Passive Buzzer on Pico π΅
# ================================================
# π What is a Passive Buzzer?
# - A passive buzzer is a sound-producing device.
# - It requires a PWM (Pulse Width Modulated) signal to produce sound.
# - Unlike an active buzzer, it cannot produce sound on its own.
# - Common uses: alarms, beeps, simple melodies.
# π Components Used:
# - Raspberry Pi Pico
# - Passive Buzzer
# - Jumper Wires
# - Wokwi Online Simulator
# π Circuit Connections:
# - Buzzer Signal Pin β GPIO15 (Pin 20 on Pico)
# - Buzzer Ground Pin β GND (Pin 38 on Pico)
# β
How It Works:
# - PWM is used to generate frequencies (tones).
# - Each musical note has a specific frequency in Hz.
# - `duty_u16(1000)` sets the loudness. `0` turns the buzzer off.
# - Sleep determines how long the note plays.
# ================================================
# π΅ Sample code π΅
# ================================================
'''
# π Import the Speaker class from the picozero library
# This allows us to control a passive buzzer easily
from picozero import Speaker
# π Import the sleep function to create delays between actions
from time import sleep
# π Create a Speaker object connected to GPIO pin 10
# This tells the Raspberry Pi Pico where the buzzer is connected
# β
Speaker(pin) is an easy way to play sound without worrying about frequencies or PWM.
speaker = Speaker(10)
# π This loop runs forever as long as the board is powered
# It will continuously turn the buzzer ON and OFF every second
while True:
speaker.on() # π Turn the buzzer ON (sound plays)
# β
sleep(seconds) pauses the program for a given amount of time
sleep(1) # β³ Wait for 1 second
speaker.off() # π Turn the buzzer OFF (silence)
sleep(1) # β³ Wait for 1 second
# β
This setup creates a 1-second beep, 1-second pause pattern β a simple buzzer blink!
'''
# π§ TASK 1:
# You are given a passive buzzer connected to GPIO pin 10.
# Write a Python program that:
# β
Uses the `Speaker` class from `picozero`
# β
Defines a melody as a list of (frequency in Hz, duration in seconds)
# β
Plays the melody continuously in a loop
# HINTS:
# - Use `speaker.play(note)` to play a tone
# - Use `sleep(duration)` to hold the note
# - Use `speaker.off()` and a short pause to separate the notes
'''
######## Answwer 1 ###########
# π Import Speaker class to control a passive buzzer easily
from picozero import Speaker
# π Import sleep to introduce pauses (note duration and gaps)
from time import sleep
# π Create a Speaker object on GPIO pin 10
# This connects the buzzer to the correct pin on the Raspberry Pi Pico
speaker = Speaker(10)
# π΅ Define the melody to play
# Each item in the list is a tuple: (frequency in Hz, duration in seconds)
# For example, (784, 0.3) means play 784 Hz tone for 0.3 seconds
melody = [
(784, 0.3), (880, 0.3), (988, 0.3), (784, 0.3), (784, 0.3),
(784, 0.3), (880, 0.3), (988, 0.3), (784, 0.3), (988, 0.3),
(880, 0.3), (784, 0.3), (784, 0.3), (784, 0.3), (880, 0.3),
(988, 0.3), (784, 0.3), (880, 0.3), (988, 0.3), (784, 0.3)
]
# π Loop forever to keep playing the melody
while True:
# βΆοΈ Loop through each (note, duration) pair in the melody
for note, duration in melody:
speaker.play(note) # π Play the tone at given frequency
sleep(duration) # β±οΈ Hold the tone for the specified time
speaker.off() # π Stop the sound before the next note
sleep(0.05) # π Short pause between notes for clarity
'''
# π§ TASK 2:
# You are given a passive buzzer connected to GPIO pin 10 on the Raspberry Pi Pico.
# Write a program that:
# β
Uses PWM to generate sound frequencies through the buzzer
# β
Plays 8 musical notes from the C major scale (C4 to C5)
# β
Each note should play for 0.5 seconds with a small volume (low duty cycle)
# β
Once all notes are played, turn off the buzzer
#
# HINTS:
# - Use the PWM class to control the buzzer
# - Store the note frequencies in a list
# - Use a for-loop to play each note one at a time
# - Use sleep() to control how long each note is played
'''
# β
Answer 2
# π΅ This program plays 8 musical notes from C4 to C5 (doβreβmiβfaβsoβlaβtiβdo)
# π Import required modules
# Pin and PWM are used to send signals to the buzzer
# sleep is used to control how long the sound lasts
from machine import Pin, PWM
from time import sleep
# π Create a PWM object for the buzzer connected to GPIO pin 10
# PWM allows us to generate specific sound frequencies
buzzer = PWM(Pin(10))
# πΆ Define a list of note frequencies (in Hertz)
# These frequencies correspond to notes from the C major scale (C4 to C5)
# C4 = 262 Hz, D = 294 Hz, E = 330 Hz, F = 349 Hz, G = 392 Hz, A = 440 Hz, B = 494 Hz, C5 = 523 Hz
notes = [262, 294, 330, 349, 392, 440, 494, 523]
# π Loop through each frequency in the list and play it
for note in notes:
buzzer.freq(note) # Set the frequency of the buzzer (play a note)
buzzer.duty_u16(1000) # Set the volume (duty cycle); 1000 is a low volume
sleep(0.5) # Wait 0.5 seconds while the note plays
# π After all notes have been played, turn the buzzer off
buzzer.duty_u16(0) # Set duty to 0 to stop sound completely
'''
# π§ TASK 3:
# Now, design and implement a more complex music player with the following features:
#
# β
Create a melody as a list of (frequency, duration) pairs
# β
After playing the melody forward, reverse it and play it backward
# β
Repeat this pattern 3 times
# β
Add a short pause (0.25 seconds) between repetitions
# β
BONUS: Gradually increase the playback speed (shorter sleep time each loop)
#
# HINTS:
# - Use a list of tuples to define (note, duration)
# - Use slicing to reverse the melody: melody[::-1]
# - Use a for-loop to repeat the process multiple times
# - Adjust the sleep time dynamically in each repetition
'''
# β
Task 3 Answers
# π΅ Plays a melody forward and backward repeatedly with increasing tempo
from machine import Pin, PWM
from time import sleep
# π Initialize passive buzzer on GPIO 10 using PWM
buzzer = PWM(Pin(10))
# πΆ Define a melody using (frequency, duration) tuples
# These frequencies represent a simple musical pattern in C major scale
melody = [
(262, 0.4), # C4
(294, 0.4), # D4
(330, 0.4), # E4
(349, 0.4), # F4
(392, 0.4), # G4
(440, 0.4), # A4
(494, 0.4), # B4
(523, 0.4) # C5
]
# π Repeat the play-and-reverse pattern 3 times
for i in range(3):
print(f"π Round {i+1}: playing forward and reverse...")
# π΅ Play melody forward
for note, duration in melody:
buzzer.freq(note)
buzzer.duty_u16(1000) # Low volume
sleep(duration)
buzzer.duty_u16(0) # Turn off between notes
sleep(0.05)
# π΅ Play melody in reverse
for note, duration in melody[::-1]:
buzzer.freq(note)
buzzer.duty_u16(1000)
sleep(duration)
buzzer.duty_u16(0)
sleep(0.05)
# β±οΈ Small pause before the next round
sleep(0.25)
# π― BONUS: Increase tempo by reducing all durations slightly
melody = [(freq, max(0.1, dur - 0.05)) for freq, dur in melody]
# π After all repetitions, turn off buzzer
buzzer.duty_u16(0)
'''