Úkolem je vytvořit Xylofon ovládaný pomocí ATMega16, který zahraje několik jednoduchých melodií
Jak je patrné ze zadání, Xylofon je tvořený kameny (noty C1,D1,E1,F1,G1,A1,H1,C2), které je potřeba spínat v určitých okamžicích a tím udávat takt pisně. Na kameny xylofonu se hraje pomocí upravených relé, ovládané pomocí obvodu na obr.1. Princip je jednoduchý, v místě, které označujeme jako cívka 1 je připojeno modifikované relé, jehož částí je cívka s feromagnetickým jádrem(princip solenoidu). Na feromagnetickém jádru je umístěn magnet a pokud je velikost a směr proudu takový, aby vybudil dostatečné magnetické pole, uzavírající se přes magnet, dojde k vyskočení jádra s magnetem a to způsobí, že na mechanický kontakt s kamenem a je zahrán tón. Každý solenoid je ovládán na vstupu +5V, přes odpor 300ohmů se vytvoří proud, který začne procházet fotodiodou v optočlenu. Ta způsobí, že jejím vyzářením sepne fototranzistor, který sepne 24V ovládací obvod cívek, což vyvolá vyskočení jádra a zahrání tónu. Takto ovládaných cívek je zde 8 (každá pro jeden tón), ty
jsou připojeny na PORTA a postupně spínány, což je vidět v programu.
U cívky je paralelně zapojena demagnetizační dioda, přes kterou je vedena zbývající energie cívky po jejím odpojení od vodiče GND.
Cívky jsou napájeny stejnosměrným napětím 24V, je potřeba vytvořit transformátor z ~230V/=24V s usměrňovačem. To ukazuje Obr. 2
  Obr.3 ukazuje celkové schéma ovládání všech osmi kamenů xylofonu. Spínání každého kamenu je signalizováno zelenou LED diodou, která je napojena přes rezistor 300 ohmů na piny PORTu A.
Obr.4 ukazuje reálný výrobek xylofonu, vpravo nahoře je úmístěn transformátor s usměrňovačem pro =24V. Samotný xylofon je umístěn nahoře, pod ním je ovládací schéma z Obr. 1. Celý obvod je připojen k pinům portu A v ATMega16.
#include <avr/io.h> // Knihovna vtupne/vystupni #include <util/delay.h> // Knihovna pro zpozdeni /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////__________PISNE__________//////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //_____Stupnice <->, pomalu______// unsigned int noty[16] = {1,2,3,4,5,6,7,8,8,7,6,5,4,3,2,1}; unsigned int takt[16]={40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40}; //_____Stupnice <->, rychle______// unsigned int noty1[16] = {1,2,3,4,5,6,7,8,8,7,6,5,4,3,2,1}; unsigned int takt1[16]={10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10}; //_____Utikej kaco utikej______// unsigned int noty2[30] = {1,3,5,8,6,6,5,5,6,5,5,3,3,3,5,2,4,3,3,4,3,3,1,3,5,1,6,5,4,3}; unsigned int takt2[30]={10,10,10,20,10,10,10,10,10,10,10,10,10,10,20,10,10,10,10,10,10,10,10,10,10,20,10,20,10,20}; //______Za vodou, za vodou, za vodickou______// unsigned int noty3[40] = { 3,5,8,5,4,3,2,4,7,6,2,4,7,6,5,4,3,5,8,5,3,5,8,5,4,3,2,4,7,6,2,4,7,6,5,4,5,5,4,3}; unsigned int takt3[40]={15,5,10,15,5,10,15,5,10,20,15,5,10,15,5,10,10,10,10,20,15,5,10,15,5,10,15,5,10,20,15,5,10,15,5,10,10,10,10,20}; //_____Ovcaci cveraci______// unsigned int noty4[21] = {1,3,5,1,3,5,3,3,2,3,4,2,3,3,2,3,4,2,3,2,1}; unsigned int takt4[21]={20,20,20,20,20,20,10,10,10,10,20,20,10,10,10,10,20,20,20,20,40}; //_____Kocka leze dirou______// unsigned int noty5[21] = {1,2,3,4,5,5,6,6,5,6,6,5,4,4,4,4,3,3,2,2,1}; unsigned int takt5[21]={10,10,10,10,20,20,20,20,20,20,20,20,10,10,10,10,20,20,20,20,20}; //_____Stedry vecer nastal______// unsigned int noty6[24] = {1,3,4,3,2,1,3,5,5,4,4,6,2,4,4,3,3,5,1,3,4,3,2,1}; unsigned int takt6[24]={20,20,10,10,20,20,20,20,10,10,10,10,20,20,10,10,10,10,20,20,10,10,20,20};
V této cásti byla definována pole not a taktu celkem pro 6 písnicek, do kterých je razena i stupnice.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////__________TELO HLAVNIHO PROGRAMU__________/////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main(void) { unsigned int i=0; // Promenna ukayujici na misto v poli unsigned int j=39; // Promenna definujici velikost pole unsigned int nota=0; // Promenna pro realizaci noty unsigned int k=0; // Pomocna promenna unsigned int delay=0; // Promenna pro realizaci taktu unsigned int odehrane=0; // Pocet odehranych pisni unsigned int pocet_pis =7; // Celkovy pocet pisni DDRA = 0b11111111; // Nastaveni portu A na vystupni PORTA = 0b00000000; // Na portu A nastav log. 0 while(1) // Nekonecna smycka { for(k=0; k< pocet_p // Cyklus ridici aktualni hranou pisen { for(i=0; i<j; i++) // Cyklus ridici vycitani z poli { if(k == 0) // Pokud je k=0 -> vyber prvni pisen { if(i == 0) // Pokud je i=0 nastav konkretni velikost pole na prislusnou hodnotu { j=16; } nota = noty[i]; // Nota odpovydajici dane pozici v poli delay = takt[i]; // Takt odpovydajici dane pozici v poli } if (k == 1) // Pokud je k=0 -> vyber druhou pisen { if(i == 0) // Pokud je i=0 nastav konkretni velikost pole na prislusnou hodnotu { j=16; } nota = noty1[i]; // Nota odpovydajici dane pozici v poli noty1 delay = takt1[i]; // Takt odpovydajici dane pozici v poli takt1 } if (k == 2) // Pokud je k=0 -> vyber treti pisen { if(i == 0) // Pokud je i=0 nastav konkretni velikost pole na prislusnou hodnotu { j=30; } nota = noty2[i]; // Nota odpovydajici dane pozici v poli noty2 delay = takt2[i]; // Takt odpovydajici dane pozici v poli takt2 } if (k == 3) // Pokud je k=0 -> vyber ctvrta pisen { if(i == 0) // Pokud je i=0 nastav konkretni velikost pole na prislusnou hodnotu { j=40; } nota = noty3[i]; // Nota odpovydajici dane pozici v poli noty3 delay = takt3[i]; // Takt odpovydajici dane pozici v poli takt3 } if (k == 4) // Pokud je k=0 -> vyber pata pisen { if(i == 0) // Pokud je i=0 nastav konkretni velikost pole na prislusnou hodnotu { j=21; } nota = noty4[i]; // Nota odpovydajici dane pozici v poli noty4 delay = takt4[i]; // Takt odpovydajici dane pozici v poli takt4 } if (k == 5) // Pokud je k=0 -> vyber sesta pisen { if(i == 0) // Pokud je i=0 nastav konkretni velikost pole na prislusnou hodnotu { j=21; } nota = noty5[i]; // Nota odpovydajici dane pozici v poli noty5 delay = takt5[i]; // Takt odpovydajici dane pozici v poli takt5 } if (k == 6) // Pokud je k=0 -> vyber sedma pisen { if(i == 0) // Pokud je i=0 nastav konkretni velikost pole na prislusnou hodnotu { j=24; } nota = noty6[i]; // Nota odpovydajici dane pozici v poli noty6 delay = takt6[i]; // Takt odpovydajici dane pozici v poli takt6 } if(nota == 0) // Pokud nota z pole je rovna 0 nastav port tak, aby zadnou notu nehral { PORTA = 0b00000000; } if(nota == 1) // Pokud nota z pole je rovna 1 nastav port tak, aby hral notu c1 { PORTA = 0b10000000; } if(nota == 2) // Pokud nota z pole je rovna 2 nastav port tak, aby hral notu d1 { PORTA = 0b01000000; } if(nota == 3) // Pokud nota z pole je rovna 3 nastav port tak, aby hral notu e1 { PORTA = 0b00100000; } if(nota == 4) // Pokud nota z pole je rovna 4 nastav port tak, aby hral notu f1 { PORTA = 0b00010000; } if(nota == 5) // Pokud nota z pole je rovna 5 nastav port tak, aby hral notu g1 { PORTA = 0b00001000; } if(nota == 6) // Pokud nota z pole je rovna 6 nastav port tak, aby hral notu a1 { PORTA = 0b00000100; } if(nota == 7) // Pokud nota z pole je rovna 7 nastav port tak, aby hral notu h1 { PORTA = 0b00000010; } if(nota == 8) // Pokud nota z pole je rovna 8 nastav port tak, aby hral notu c2 { PORTA = 0b00000001; } _delay_ms(100); // Doba nutna pro vybuzeni civky PORTA = 0b00000000; // Na portu A nastav log. 0 _delay_ms(delay*20); // Zpozdeni odpovidajici prislusneho taktu } if(i>=j) // Pokud je dohrana dana pisen, tak: { i=0; // Nuluj promennou j=39; // Nasatavi univeryalni hodnotu pole nota=0; // Nulovani promenne odehrane++; // Navyseni pocitadla odehratych pisni _delay_ms(1000); // Zpozdeni mezi pisnemi } if (odehrane >= pocet_pis) // Pokud jsou odehrany vsechny pisne nastav promenne pro spusteni prvni pisne { odehrane=0; // Nuluj promennou } } } }
V závěru nutno podotknout, že se podařilo vytvořit funkční xylofon ovládaný mikrokontrolerem. Jak je patrné z videa, není zvuk zcela ideální. To je způsobeno dvěma faktory. První je ten, že na kameny xylofonu mechanicky působíme magnetem s rovnou plochou o rozměrech 5x5 mm. Vhodnější by bylo zmenšit plochu magnetu nebo ještě vhodnější rešení je na magnet „upevnit“ zakulaceny předmět nejlépe ze dřeva. Druhým faktorem je, že u optočlenu dochází na straně tranzistoru ke vzniku nežádoucího odporu, který snižuje proud procházející cívkou a tím i silové účinky cívky. Tuto nevýhodu by bylo možné odstranit použitím tranzistoru JFET ve funkci spínače, zapojení by však přišlo o funkci galvanického oddělení.
Celý projekt v soubouru zip je možné stáhnout zde
Ukázkové video funkčního xylofonu je možné shlédnout na http://www.youtube.com/watch?v=joiR2uDrPhw&feature=youtu.be/
[1] http://www.nerdkits.com/videos/robotic_xylophone/
[2] FRÝZA,T., FEDRA Z., ŠEBESTA. J.: Mikroprocesorová technika - Laboratorní cvieení. Vývojová deska ATmega16. str. 45. Dostupné na WWW: