Skip to main content

7.2 Mini piano

Ovaj projekt pretvara četiri tipke i pasivni buzzer u mali piano. Svaka tipka dobiva svoju notu, a držanje pritisnutom svira tu notu dokle god tamo držiš prst.

Ništa ovdje nije novo. Tipke se čitaju točno kao u 2.1 Brojač pritisaka tipke, a buzzer se pobuđuje točno kao u 2.4 Piskanje buzzera. Projektom ga čini razmjer: četiri ulaza i jedan izlaz na breadboardu odjednom, i prvi sklop u ovom kitu koji koristi pinove na obje strane pločice.

U ovoj dokumentaciji naučit ćeš:

  • Kako spojiti četiri tipke odjednom, svaku na svoj pin
  • Kako spojiti dvije plave vodilice u jednu dijeljenu masu
  • Kako tone() pretvara broj u visinu tona, a noTone() ga zaustavlja
  • Zašto else if lanac znači da se u jednom trenutku može svirati samo jedna nota

Potreban hardver:

  • 1x Soldered NULA MINI pločica
  • 1x Breadboard
  • 4x Tipke
  • 1x Pasivni buzzer
  • 12x Jumper žice
  • 1x USB-C kabel
ℹ️
Ovom primjeru ne trebaju otpornici uopće. Ni za tipke: one koriste otpornike ugrađene u čip, uključene u kodu pomoću INPUT_PULLUP. Ni za buzzer: pin se uvijek kreće samo između 0 V i 3.3 V, pa ga nema od čega štititi. Ako si vidio krug za piano nacrtan s četiri otpornika od 10 kΩ, to je drugačiji način spajanja tipki i nije ono što ova skica očekuje.
⚠️
Pobrini se da u ruci držiš pasivni buzzer, a ne aktivni. Pasivni buzzer svira onu frekvenciju koju mu pošalješ, a to je ovdje cijela svrha. Aktivni buzzer sadrži vlastiti oscilator i može piskati samo na jednoj fiksnoj visini, pa bi svaka tipka zvučala identično.

Spajanje komponenti

Ovaj sklop koristi pet pinova na pločici, i oni su razdijeljeni na obje njezine strane:

PinRedStranaŠto radi
IO225f–jTipka 1, nota C4
IO326f–jTipka 2, nota D4
IO427f–jTipka 3, nota E4
IO528f–jTipka 4, nota F4
IO1828a–eBuzzer
GND30f–jMasa za sve
⚠️
Red 28 pojavljuje se dvaput u toj tablici, a dva unosa su različiti pinovi. Na f–j strani red 28 je IO5, jedna od tipki. Na a–e strani red 28 je IO18, buzzer. Sjede na suprotnim krajevima istog broja reda i nisu spojeni međusobno. Čitaj ime ispisano na pločici, nikada broj reda sam.

Tijelo pločice prekriva srednje stupce, pa su uz nju slobodni samo stupac a na a–e strani i stupac j na f–j strani. Svaka žica koja dotiče pločicu ide zato u a… ili j… rupicu.

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

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. Pritisni je ravnomjerno dok svi pinovi ne sjednu.

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

Na fotografijama koje slijede pločica zauzima redove 25 do 30.

ℹ️
Tvoja pločica može sjediti u drugim redovima od one na fotografijama. Važno je u koji red sleti koji pin. Čitaj imena ispisana duž rubova pločice, a ne prepisuj brojeve.

2. Izvedi masu na plavu − vodilicu

Jedna kratka jumper žica iz j30 (red u kojem je GND) do plave vodilice na f–j rubu.

Jumper žica iz j30 do plave negativne vodilice na f-j rubu
Korak 2: GND izveden na plavu − vodilicu
ℹ️
Žica mora ići u red rupica koji ide uz plavu liniju. Svaki rub breadboarda nosi dva reda vodilica, a onaj uz crvenu liniju je zaseban pojas koji nije spojen s njim.

3. Spoji dvije plave − vodilice međusobno

Tipke i buzzer masu će uzimati s a–e ruba, ali je GND izveden na f–j rubu. Zato se dvije plave vodilice moraju spojiti u jednu.

Povuci jumper žicu s plave vodilice na f–j rubu, oko dalekog kraja breadboarda, do plave vodilice na a–e rubu. Postavi je blizu reda 1, dobro odmaknuto od svega drugoga.

Jumper žica premošćuje dvije plave negativne vodilice na kraju breadboarda kod reda 1
Korak 3: dvije plave − vodilice spojene u jednu liniju mase
ℹ️
Vodilice duž dva ruba breadboarda nisu spojene unutar njega: svaki pojas ide dužinom jednog ruba i tamo staje. Ta jedna žica je ono što ih pretvara u jednu liniju mase koju obje strane pločice mogu dosegnuti. Svaki spoj na masu odsad ide samo do bliže plave vodilice.

4. Postavi četiri tipke

Utisni četiri tipke u sredinu breadboarda tako da svaka premosti središnji kanal, nekoliko redova dalje od pločice. Svaka tipka obuhvaća dva reda.

Na fotografijama sjede u redovima 18 i 20, 15 i 17, 12 i 14, te 9 i 11, najbliža pločici prva, tri reda razmaknute, što je ugodan razmak za četiri prsta.

Četiri tipke postavljene preko središnjeg kanala
Korak 4: četiri tipke premošćuju središnji kanal
⚠️
Tipka ima četiri nožice, ali samo dvije su važne. Dvije nožice na istoj strani tipke trajno su spojene unutar nje. Pritisak tipke spaja jednu stranu s drugom. Zato za svaku tipku uvijek koristi jednu nožicu s a–e strane i jednu s f–j strane, u njezina dva različita reda. Ako uzmeš obje žice s iste strane, te dvije su već spojene i pločica će se ponašati kao da je ta tipka zauvijek pritisnuta.

5. Spoji svaku tipku na masu

Četiri kratke jumper žice, jedna po tipki, s a–e strane tipke do plave vodilice na tom rubu. Na fotografiji su to redovi 20, 17, 14 i 11, viši red para svake tipke.

Četiri jumper žice spajaju svaku tipku na plavu negativnu vodilicu na a-e rubu
Korak 5: sve četiri tipke spojene na masu na plavoj − vodilici

6. Spoji svaku tipku na svoj pin

Sada četiri signalne žice, sve na f–j strani. Svaka ide od pina pločice do nižeg reda para jedne tipke:

IzUTipkaNota
j25 (IO2)j181C4, 262 Hz
j26 (IO3)j152D4, 294 Hz
j27 (IO4)j123E4, 330 Hz
j28 (IO5)j94F4, 349 Hz
Četiri signalne jumper žice idu od pinova pločice do četiri tipke
Korak 6: svaka tipka spojena na svoj pin, IO2 na tipku najbližu pločici

Primijeti da četiri žice idu paralelno i nikada se ne križaju. IO2, pin najbliži tipkama, ide na najbližu tipku; IO5, najdalji pin, ide na najdalju tipku. Držanje tog redoslijeda je ono što tjera note da rastu kako ti se ruka odmiče od pločice, i vrijedi to dvaput provjeriti, jer sve četiri žice izgledaju jednako kada su unutra.

ℹ️
Svaka tipka sada ima masu s jedne strane središnjeg kanala i svoj pin s druge. To je isti dijagonalni par koji je za jednu tipku korišten u 2.1 Brojač pritisaka tipke, samo ponovljen četiri puta.

7. Postavi buzzer i spoji ga

Buzzer ide na a–e stranu, na daleki kraj breadboarda, s nožicama u dva susjedna reda, na fotografiji redovi 3 i 4.

Pogledaj vrh njegovog kućišta 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 4.

Zatim dvije žice:

  • Iz a4, reda u kojem je + nožica, u a28, a to je IO18. To je žica koja nosi pravokutni signal.
  • Iz a3, druge nožice buzzera, do plave vodilice na istom rubu.
Pasivni buzzer u redovima 3 i 4, jedna žica na IO18 i jedna na negativnu vodilicu
Korak 7: buzzer spojen između IO18 i mase
⚠️
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.

Krug je sada zatvoren: IO18 → buzzer → GND. Kućište od 12 mm skriva nožice kada je buzzer utisnut, pa ako spajanje moraš provjeriti kasnije, čitaj umjesto toga dvije jumper žice.

8. Spoji pločicu na računalo

Utisni USB-C kabel u pločicu. PWR LED-ica se upali čim pločica dobije struju.

Gotov krug mini piana napajan preko USB-C
Korak 8: gotov krug, napajan preko USB-C
ℹ️
Svi brojevi redova iznad samo su redovi koje fotografije slučajno koriste. Bilo koji slobodni redovi rade, dokle god svaka tipka premošćuje kanal u dva različita reda, vlastiti pin svake tipke doseže jednu njezinu stranu a masa drugu, i dokle god dvije nožice buzzera sjede u dva različita reda s IO18 na onoj s +.

Kako četiri tipke dijele jedan buzzer

Čitanje tipke. Svaki od četiri pina postavljen je s INPUT_PULLUP, što uključuje otpornik unutar čipa koji nježno veže pin na 3.3 V. Pin zato čita HIGH dok je njegova tipka otpuštena, a jedini posao tipke je spojiti taj pin na GND, što ga povuče na LOW.

ℹ️
Zato pritisnuta tipka daje LOW. To je obrnuto od onoga što većina ljudi očekuje. Tipka spojena na ovaj način naziva se active low, i to je standardni način spajanja tipke na bilo koji mikrokontroler. 2.1 Brojač pritisaka tipke to pokriva detaljno.

Pravljenje note. tone() prebacuje IO18 između 3.3 V i 0 V iznova. To je pravokutni signal. Broj prebacivanja u sekundi je frekvencija, a tvoje uho frekvenciju čita kao visinu tona. Četiri frekvencije, četiri note:

NotaFrekvencija (Hz)
C4262
D4294
E4330
F4349

To su prve četiri note C-dur skale, počevši od C-a u sredini klavijature piana. Promijeni brojeve i mijenjaš štimanje. Nema ništa posebno u tim četirima vrijednostima, a potražiti frekvenciju bilo koje druge note dovoljno je da sagradiš vlastitu skalu.

Samo jedna nota u jednom trenutku. Četiri provjere u loop() spojene su u jedan lanac if / else if, pa se pločica zaustavi na prvoj tipki koju nađe pritisnutu i ostale nikada ne pogleda. Pritisni dvije tipke zajedno i čuješ samo onu koja dolazi ranije u lancu, a to je niža nota. Pravi piano svira akorde; ovaj ne može, a else if lanac je razlog.

Puštanje. Kada nijedna od četiri nije pritisnuta, lanac propada do svojeg else i poziva noTone(), koji zaustavlja zvuk. To je ono što notu čini da traje točno onoliko dugo koliko tipku držiš pritisnutom.

ℹ️
delay(50) na kraju loop() daje kontaktima tipke trenutak da se umire tako da se jedan pritisak ne pročita kao nekoliko, ista ideja debouncea kao u 2.2 Debounce tipke. Također znači da pločica tipke gleda 20 puta u sekundi, pa do 50 ms može proći između slijetanja tvog prsta i početka note. Gotovo to možeš osjetiti ako sviraš brzo.

Kod

/**
**************************************************
*
* @file 7.2_Mini_piano.ino
* @brief Projekt koji četiri tipke i pasivni buzzer pretvara u mali piano. Svaka tipka ima svoju
* frekvenciju, a njezin pritisak svira tu notu dokle god tipku držiš pritisnutom.
* Gradi se na čitanju tipke iz sekcije 2.1 i buzzeru iz sekcije 2.4.
* Za detalje, shemu spajanja i više, pogledaj dokumentaciju primjera na: <link placeholder>
* @author Soldered
***************************************************
*/

/*
Ovo je varijabla kojoj predajemo broj pina na koji smo spojili buzzer.
NULA pločica ima logiku imenovanja pinova ovako: IO18, gdje je 18 broj koji dajemo varijabli.
*/
const int BUZZER_PIN = 18;

/*
Ovo su varijable kojima predajemo brojeve pinova na koje smo spojili četiri TIPKE. Svaka tipka
dobiva svoj pin, jer ih pločica mora moći razlikovati.
*/
const int BTN1 = 2;
const int BTN2 = 3;
const int BTN3 = 4;
const int BTN4 = 5;

/*
Ovo su frekvencije četiri note, u hercima. Frekvencija je koliko se puta u sekundi buzzer pomakne naprijed
i natrag, i to je ono što naše uho čuje kao visinu zvuka: što je broj veći, to je nota viša.
Imena dolaze iz glazbene skale, gdje je C4 onaj C u sredini klavijature piana. Slobodno eksperimentiraj
s ovim vrijednostima, ili potraži frekvencije drugih nota i sagradi vlastitu skalu.
*/
const int NOTE_C4 = 262;
const int NOTE_D4 = 294;
const int NOTE_E4 = 330;
const int NOTE_F4 = 349;

void setup() {

/*
pinMode() je funkcija koja konfigurira zadani pin da se ponaša ili kao ulaz ili kao izlaz.
Budući da ovi pinovi moraju otkriti je li tipka pritisnuta, stavit ćemo ih u INPUT_PULLUP mod. INPUT_PULLUP
uključuje mali otpornik unutar čipa koji svaki pin veže na 3.3V, što znači da pin sjedi na HIGH dok je njegova
tipka otpuštena a ide na LOW dok je pritisnuta.
*/
pinMode(BTN1, INPUT_PULLUP);
pinMode(BTN2, INPUT_PULLUP);
pinMode(BTN3, INPUT_PULLUP);
pinMode(BTN4, INPUT_PULLUP);

/*
Buzzer je jedini pin koji mora pisati a ne čitati, pa ga stavljamo u OUTPUT mod.
*/
pinMode(BUZZER_PIN, OUTPUT);
}

void loop() {

/*
digitalRead() je funkcija koja čita vrijednost sa zadanog digitalnog pina, ili HIGH ili LOW. Zbog
pull-up otpornika, pritisnuta tipka daje LOW.
tone() je funkcija koja tjera buzzer da proizvede zvuk zadane frekvencije. Pozvana samo s pinom i
frekvencijom, kao što je ovdje, nastavlja svirati dok je sami ne zaustavimo.
Primijeti lanac "else if": pločica provjerava tipke po redu i zaustavlja se na prvoj koju nađe pritisnutu, pa
pritisak dvije tipke odjednom svira samo notu koja dolazi prva u ovoj listi.
*/
if (digitalRead(BTN1) == LOW) {
tone(BUZZER_PIN, NOTE_C4);
}
else if (digitalRead(BTN2) == LOW) {
tone(BUZZER_PIN, NOTE_D4);
}
else if (digitalRead(BTN3) == LOW) {
tone(BUZZER_PIN, NOTE_E4);
}
else if (digitalRead(BTN4) == LOW) {
tone(BUZZER_PIN, NOTE_F4);
}
else {

/*
Ako nijedna tipka nije pritisnuta, završimo ovdje. noTone() zaustavlja svaki zvuk koji je buzzer pravio, a to je
ono što notu tjera da prestane onog trenutka kada pustiš tipku.
*/
noTone(BUZZER_PIN);
}

/*
delay() je funkcija koja započinje pauzu u kodu. Ova vrlo kratka pauza daje kontaktima tipke trenutak da se
umire, što sprječava da se jedan pritisak pročita kao nekoliko. Sekcija 2.2 to detaljno objašnjava pod imenom
debounce.
*/
delay(50);
}

Što bi trebao vidjeti

Prenesi skicu. Ništa se ne događa dok ne pritisneš tipku. Buzzer je tih, i nema serijskog ispisa, jer ova skica nikada ne poziva Serial.begin(). Jedini izlaz je zvuk.

Pritisni tipku najbližu pločici. Trebao bi čuti postojan ton koji traje točno onoliko dugo koliko je držiš, i prestaje onog trenutka kada je pustiš. Kreni prema vani i visina tona raste: C4, D4, E4, F4.

Prst pritišće jednu od četiri tipke na gotovom mini pianu
Držanje tipke pritisnutom: nota zvuči dokle god tvoj prst tamo ostaje

Stvari koje vrijedi probati kada radi:

  • Drži dvije tipke odjednom. Zvuči samo niža od dvije, zbog else if lanca.
  • Sviraj brzo. Kratka pauza u loop() znači da pločica tipke gleda samo 20 puta u sekundi, pa vrlo brzo sviranje djeluje malo tupo.
  • Promijeni frekvenciju. Uredi jednu od NOTE_ vrijednosti, prenesi ponovno, i ta je tipka preštimana.
ℹ️
Nema zvuka ni s jedne tipke? Provjeri prvo dvije žice mase: j30 do plave vodilice, i žicu koja spaja dvije plave vodilice. Bez te druge žice ništa na a–e rubu nije spojeno na masu, pa nijedna tipka ne može svoj pin povući u nisko stanje a buzzer nema povratni put. Jedna tipka tiha a ostale rade? Dvije žice te tipke vjerojatno su na istoj strani središnjeg kanala, ili su joj nožice sletjele u jedan red umjesto u dva.
ℹ️
Note u pogrešnom redoslijedu? Dvije od četiri signalne žice su zamijenjene. Sve su iste boje kada su na mjestu, pa ih prati natrag do pločice i provjeri da IO2 doseže tipku najbližu pločici a IO5 najdalju.

Cijeli primjer

Pogledaj cijeli kod primjera na linku ispod:

7.2_Mini_piano.ino

Projekt koji pravi jednostavan piano pomoću 4 tipke i pasivnog buzzera. Svaka tipka proizvodi svoju notu.