Skip to main content

2.4 Piskanje buzzera

Cilj ovog primjera je napraviti malo buke. Pasivni buzzer je maleni zvučnik: nahrani ga pravokutnim signalom i vibrirat će na onoj frekvenciji koju mu pošalješ, pa jedan buzzer može odsvirati bilo koju notu koju želiš.

U ovom primjeru NULA MINI odsvira kratku skalu od osam nota u trenutku kada pokreneš skriptu.

U ovoj dokumentaciji naučit ćeš:

  • Kako spojiti pasivni buzzer na pločicu.
  • Kako PWM pretvara frekvenciju u zvuk.
  • Što duty_u16() kontrolira i zašto je 32768 broj koji treba koristiti.
  • Kako držati melodiju u listi i prolaziti kroz nju petljom.

Potreban hardver:

  • 1x Soldered NULA MINI pločica
  • 1x Breadboard
  • 1x Pasivni buzzer
  • 3x Jumper žice
  • 1x USB-C kabel
ℹ️
Za razliku od primjera s LED-icom, ovome ne treba otpornik. Buzzer sjedi direktno između IO5 i mase. Nema ga od čega štititi, jer se pin uvijek kreće samo između 0 V i 3.3 V.
⚠️
Pobrini se da u ruci držiš pasivni buzzer, a ne aktivni. Pasivni buzzer proizvodi onu frekvenciju koju mu pošalješ, a upravo se na to ovaj primjer oslanja. Aktivni buzzer sadrži vlastiti oscilator i može piskati samo na jednoj fiksnoj visini, pa bi melodija izašla kao jedan ravan ton.

Spajanje komponenti

Prati pet koraka ispod. Svaka fotografija snimljena je s istog položaja, pa je možeš usporediti s prethodnom i vidjeti točno što se promijenilo.

ℹ️
Ovaj primjer doseže samo dva pina na pločici: IO5 u redu 28 i GND u redu 30, oba na f–j strani. Tijelo pločice prekriva stupce f–i, pa su j28 i j30 rupice u koje stvarno možeš uvesti žicu.

1. Umetni NULA MINI pločicu na breadboard

ℹ️
Ovaj korak pretpostavlja da znaš kako je breadboard spojen iznutra i što su njegove naponske vodilice (power rails). Za uvod pogledaj stranicu dokumentacije Osnove breadboarda.

Utisni pločicu u jedan kraj breadboarda tako da njezina dva reda pinova sjednu s obje strane središnjeg kanala, s čipom okrenutim prema dolje.

NULA MINI pločica postavljena na breadboard
Korak 1: pločica postavljena na breadboard

2. Postavi buzzer i izvedi masu na vodilicu

Buzzer ide na f–j stranu, dobro odmaknut od pločice, s dvije nožice u redu 14 i redu 15.

Pogledaj vrh kućišta buzzera prije nego ga utisneš. Uz oznaku HWDZ nalazi se mali + unutar kružića, i nožica na toj strani kućišta je pozitivna. Ta nožica ide u red 15.

Zatim povuci jumper žicu iz j30 (GND) do plave vodilice. Ta vodilica je linija mase za ostatak primjera.

Pasivni buzzer u redovima 14 i 15, s jumper žicom iz j30 na negativnu vodilicu
Korak 2: buzzer premošćuje redove 14 i 15, i GND spojen na plavu − vodilicu
⚠️
Dvije nožice sjede u susjednim redovima, pa odvoji trenutak da provjeriš da su stvarno sletjele u dva različita reda. Ako obje nožice završe u istom redu, buzzer je kratko spojen i ostaje tih bez obzira što kod radi.

3. Spoji pozitivnu nožicu na IO5

Jedna jumper žica iz j15 (red u kojem je + nožica buzzera) dolje u j28 (IO5). To je žica koja će nositi pravokutni signal.

Jumper žica iz j15 u j28, spaja pozitivnu nožicu buzzera na IO5
Korak 3: + nožica buzzera spojena na IO5 u redu 28

4. Spoji drugu nožicu na masu

Još jedna jumper žica, iz j14 (druga nožica buzzera) do plave vodilice, koja je već vezana na GND.

Jumper žica iz j14 na negativnu vodilicu, zatvara krug
Korak 4: druga nožica buzzera spojena na plavu − vodilicu, čime se krug zatvara

Krug je sada zatvoren: IO5 → buzzer → GND. Što god IO5 radi, buzzer osjeti.

5. Spoji pločicu na računalo

Gotov krug s buzzerom napajan preko USB-C
Korak 5: gotov krug, napajan preko USB-C
ℹ️
Redovi 14 i 15 samo su redovi koje fotografije slučajno koriste. Bilo koja dva slobodna reda rade, dokle god nožice buzzera sjede u dva različita reda, IO5 doseže red s +, a drugi red doseže masu.

Kako pasivni buzzer proizvodi notu

Zvuk nije ništa više od zraka koji se potiskuje naprijed i natrag. Unutar buzzera je tanka membrana koja se pomiče kad god se napon na njoj promijeni, a pomicanje dovoljno brzo daje notu koju možeš čuti.

To je ono što PWM radi. PWM je skraćeno od Pulse Width Modulation: uključuje i isključuje pin vrlo brzo, i dopušta nam da odaberemo i koliko brzo prebacuje i koji dio vremena ostaje uključen. Broj prebacivanja u sekundi je frekvencija, mjerena u hercima, a tvoje uho tu frekvenciju čita kao visinu tona:

NotaFrekvencija (Hz)
C4262
D4294
E4330
F4349
G4392
A4440
B4494
C5523
ℹ️
Viša frekvencija daje višu visinu tona, niža frekvencija dublju. Osam vrijednosti iznad su jedna oktava C-dur skale, a to je točno melodija koju ova skripta svira.

MicroPython nema funkciju tone(). Umjesto toga stvaraš PWM objekt na pinu i onda ga pobuđuješ pomoću dva poziva:

buzzer = PWM(Pin(BUZZER_PIN))

buzzer.freq(262) # odaberi visinu tona
buzzer.duty_u16(32768) # pokreni zvuk
buzzer.duty_u16(0) # zaustavi zvuk

freq() postavlja visinu tona. duty_u16() postavlja koji dio vremena pin ostaje uključen, kao broj od 0 (uvijek isključen) do 65535 (uvijek uključen). Polovica toga, 32768, je ravnomjerno prebacivanje uključeno-isključeno, što buzzeru daje njegov najčišći ton. Pisanje 0 ostavlja pin trajno isključen, a to je tišina.

ℹ️
Stvaranje PWM objekta već zauzima pin, pa mu za razliku od običnog Pin ne postavljaš smjer. U ovom primjeru nema Pin.OUT uopće.
⚠️
Ne koristi 65535 da bi bilo glasnije. Duty od 65535 znači da je pin uključen cijelo vrijeme i nikada ne prebacuje, pa membrana unutar buzzera prestaje se pomicati i ne čuješ ništa, isto kao pri dutyju od 0. Glasnoća nije ono što ovaj broj kontrolira.

Kako je melodija pohranjena

Melodija je u stvari par lista koje putuju zajedno: koja nota i koliko traje. Skripta ih drži u dvije liste iste dužine:

  • melody drži frekvenciju svake note u hercima.
  • note_duration drži dužinu svake note, zapisanu kako je zapisuju note: 4 za četvrtinku, 2 za polovinku.

Petlja for zatim prolazi kroz obje liste jednu poziciju za drugom, svira notu i počeka njezino trajanje.

for i in range(len(melody)):
ℹ️
len(melody) je broj nota u listi, a range() broji od 0 do neposredno ispod tog broja. Tako i uzima vrijednost svake pozicije redom, a mi je koristimo da iz obje liste pročitamo odgovarajući zapis. Napisana ovako, petlja ostaje ispravna i nakon što dodaš svoju notu. Nema ekvivalenta Arduino računanju s sizeof() koje treba držati u koraku.

Kada petlja završi, otpuštamo pin:

buzzer.deinit()
ℹ️
deinit() vraća pin i ostavlja buzzer tihim zauvijek. Bez toga PWM hardver ostaje zauzet i nakon što program završi, što može ostaviti buzzer da zuji nakon što se skripta zaustavila.

Kod

# PWM je skraćeno od Pulse Width Modulation. Uključuje i isključuje pin vrlo brzo, a mi možemo odabrati i koliko brzo
# prebacuje i koji dio vremena ostaje uključen. Dovođenje tog brzog prebacivanja u buzzer je ono što ga tjera da
# proizvede zvuk, a brzina prebacivanja je ono što čujemo kao visinu tona.
from machine import Pin, PWM
import time

# Ovo je varijabla kojoj dodjeljujemo broj pina na koji smo spojili buzzer.
# NULA pločica ima logiku imenovanja pinova ovako: IO5, gdje je 5 broj koji dajemo varijabli.
BUZZER_PIN = 5

# Koristit ćemo dvije liste - jednu za frekvencije nota (u hercima) i jednu za trajanja nota.
# Frekvencija je koliko se puta u sekundi buzzer pomakne naprijed i natrag, a naše uho to čuje kao visinu
# note: što je broj veći, to je nota viša.
melody = [262, 294, 330, 349, 392, 440, 494, 523] # C4 do C5
note_duration = [4, 4, 4, 4, 4, 4, 4, 2] # Četvrtinke (posljednja je polovinka)

# Ovdje stvaramo naš PWM objekt, koji smo nazvali "buzzer". Njegovo stvaranje već zauzima pin, pa mu za razliku
# od običnog Pin ne postavljamo smjer.
buzzer = PWM(Pin(BUZZER_PIN))

# duty_u16() postavlja koji dio vremena pin ostaje uključen, kao broj od 0 (uvijek isključen) do 65535 (uvijek uključen).
# Polovica toga, 32768, je ravnomjerno prebacivanje uključeno-isključeno koje buzzeru daje njegov najčišći ton.
SOUND_ON = 32768
SOUND_OFF = 0

# Počni s tihim buzzerom, da se ne oglasi prije nego melodija počne.
buzzer.duty_u16(SOUND_OFF)

print("Playing melody...")

# Petlja for ponavlja blok koda jednom za svaki element koji joj je dan. range(len(melody)) broji od 0 do
# broja nota u našoj listi, pa "i" na kraju bude pozicija svake note redom.
for i in range(len(melody)):

# Dužine glazbenih nota zapisuju se kao razlomci: četvrtinka je četvrtina cijele note. Ovdje taj razlomak
# pretvaramo u milisekunde dijeljenjem jedne sekunde s brojem iz liste, pa 4 postaje 250 ms a 2
# postaje 500 ms.
duration = int(1000 / note_duration[i])

# freq() postavlja koliko brzo pin prebacuje, što je visina note, a duty_u16() zatim pokreće zvuk.
buzzer.freq(melody[i])
buzzer.duty_u16(SOUND_ON)

# Odsviraj notu u punoj dužini.
time.sleep_ms(duration)

# Sada zaustavljamo zvuk i čekamo malo dulje prije sljedeće note. Ta dodatna tišina sprječava note da
# se stope jedna u drugu. Slobodno eksperimentiraj s onih 0.3.
buzzer.duty_u16(SOUND_OFF)
time.sleep_ms(int(duration * 0.3))

# deinit() otpušta pin kada smo s njim gotovi, ostavljajući buzzer tihim zauvijek.
buzzer.deinit()
print("Melody finished!")

Što bi trebao vidjeti

Pritisni Run i buzzer odsvira uzlaznu skalu od osam nota, ukupno nešto manje od tri sekunde. Onda utihne.

ℹ️
To trajanje vrijedi provjeriti u odnosu na liste, jer je zbroj njih dvije. Sedam četvrtinki su po 250 ms, a završna polovinka je 500 ms, što je 2250 ms zvuka; dodatna tišina nakon svake note dodaje još 30 % na to, pa cijela melodija na pločici traje 2930 ms. Ako skratiš onih 0.3, skala ide brže a da se ijednoj noti ne promijeni visina.

U ovoj skripti nema beskonačne petlje, pa se melodija svira jednom i program završava. Da je čuješ ponovno, ponovno pritisni Run.

Shell prikazuje isto u tekstu:

Playing melody...
Melody finished!
ℹ️
Ako se obje poruke pojave, a ti ne čuješ ništa, kod je u redu a spajanje nije. Provjeri da su nožice buzzera u dva različita reda i da jumper žica s IO5 sleti u isti red kao jedna od njih.

Probaj sam: promijeni jedan od brojeva u melody i pokreni ponovno. Budući da petlja broji pomoću len(melody), možeš i dodati note u obje liste i ona će ih pokupiti bez ikakve druge promjene.


Cijeli primjer

Pogledaj cijeli kod primjera na linku ispod:

2.4_Buzzer_Beep.py

Primjer koji pokazuje kako pomoću PWM-a odsvirati jednostavnu melodiju na pasivnom buzzeru spojenom na IO5.