Lekcja 8: Zagrajmy muzyczkę.
Lekcja dotyczy wykorzystania tzw. buzzera do wydawania dźwięków. Zagramy znaną przez wszystkich melodię. Ciekawe
czy ją znacie...
Buzzer to element magnetyczny generujący dźwięk. Jego specyfikacja znajduje się w tabeli poniżej.
Symbol: Buzzer z generatorem 5V 12mm - THT
|
Z teorii muzyki wiemy, że określone dźwięki mają swoje częstotliwości jak przedstawiono w tabeli poniżej.
Dźwięk | Częstotliwość [Hz] | Długość | Ton |
c | 261 Hz | 3830 | 1915 |
d | 294 Hz | 3400 | 1700 |
e | 329 Hz | 3038 | 1519 |
f | 349 Hz | 2864 | 1432 |
g | 392 Hz | 2550 | 1275 |
a | 440 Hz | 2272 | 1136 |
h | 493 Hz | 2028 | 1014 |
C | 523 Hz | 1912 | 956 |
Wykorzystamy buzzer w prosty sposób generując dźwięki o określonej długości i wysokości. Jako, że nasz buzzer może być zasilany napięciem 5V, podłączymy go bezpośrednio do Arduino do pinu np. numer 13 wg schematu jak poniżej:
Piszemy kod jak poniżej:
int PIN = 13; int dlugosc = 32; char nuty[] = "eefggfedccdeeddeefggfedccdedcc "; int bity[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 }; int tempo = 200; void grajTon(int tone, int czastrwania) { for (long i = 0; i < czastrwania * 1000L; i += tone * 2) { digitalWrite(PIN, HIGH); delayMicroseconds(tone); digitalWrite(PIN, LOW); delayMicroseconds(tone);} } void graj(char nuta, int czastrwania) { char symbol[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' }; int tony[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 }; for (int i = 0; i < 8; i++) { if (symbol[i] == nuta) { grajTon(tony[i], czastrwania);} }} void setup() { pinMode(PIN, OUTPUT); } void loop() { for (int i = 0; i < dlugosc; i++) { if (nuty[i] == ' ') { delay(bity[i] * tempo);} else { graj(nuty[i], bity[i] * tempo);} delay(tempo / 2); }}
Jak widzimy, nasz kod jest trochę bardziej skomplikowany niż poprzednie.
W linii 1 deklarujemy zmienną PIN, która będzie przechowywać numer pinu 13 do późniejszych funkcji.
W linii 2 deklarujemy długość naszej melodii, a dokładnie ilość dźwięków.
W linii 3 deklarujemy zmienną typu char o nazwie nuty, która będzie przechowywać naszą melodię. Zauważmy, że
to nowy typ zmiennej, która przechowuje ciąg znaków. Spacja na końcu jest przerwą między powtórzeniami melodii.
W linii 4 deklarujemy zmienną bity, która przechowuje bit melodii, a dokładnie długość trwania jednego bitu.
W linii 5 deklarujemy tempo grania melodii.
W linii 7 pojawia się zdefiniowana przez nas nowa funkcja o nazwie grajTon, której zadaniem jest odtworzenie tonu
przez wykonanie funkcji digitalWrite. Jak pamiętamy z wcześniejszych lekcji, podanie numeru pinu i polecenia HIGH
lub LOW włącza lub wyłącza sygnał na danym pinie.
W linii 10 i 11 pojawia się nowa funkcja delayMicroseconds, która tak jak znana już nam funkcja delay
odpowiada za przerwę w działaniu kodu, ale tym razem czas przerwy podajemy w mikrosekundach.
W linii 14 zaczyna się zdefiniowana przez nas funkcja graj, której zadaniem jest dopasowanie symbolu do danej
wartości tonów, których zestaw widzieliśmy wcześniej w tabeli. Funkcja zawiera dwie zmienne: typu char i int. Po dopasowaniu
tonu wywoływana jest w linii 19 poprzednia funkcja grajTon o zadanej wartości tonu i czasie trwania.
W linii 21 mamy standardową funkcję z przypisaniem numeru do pinu.
W linii 24 zaczyna się funkcja loop, której zadaniem jest ciągłe odtwarzanie sekwencji tonów w pętli z
określony tempem. Funkjca if sprawdza tylko czy dany ton nie jest spacją, która ma 'wygrać' ciszę
(spacja jako ostatni symbol w deklaracji w linii 3).
Sprawdzamy teraz działanie naszego układu.
Znacie tę melodię?
Powrót do spisu materiałów