En aquesta pràctica, posarem en pràctica no tan sols la programació sinó la música en una activitat on haurem de fer sonar una melodia d'una cançó mitjançant els Piezo Speakers.
PIEZO SPEAKERS
Els Piezo Speaker són uns components electrònics capaços de generar una espècie de brunzit d'un mateix to gràcies a un electroimant i a una làmina piezoelèctrica. Els Piezo Speakers aprofiten la propietat de certs materials anomenada efecte piezoelèctric mitjançant el qual si a aquests materials se'ls i aplica una força o un moviment produiran un camp electromagnètic. Per altra banda, també succeeix el contrari, si se'ls hi aplica un voltatge aquests produiran moviment que és com funcionen els Piezo Speakers. Si es regula el voltatge introduït, el moviment oscil·latori que produeixen les làmines de material piezoelèctric que conformen el Piezo Speaker, es pot arribar a reproduir una nota musical en fer coincidir la velocitat de moviment amb la freqüència de la nota. D'aquesta manera, controlant el voltatge es poden reproduir melodies més extenses.
Freqüències
El so està conformat per ones i depenent de si aquest so és més agut o més greu, la freqüència en què es repetiran aquestes ones en un espai de temps determinat serà major o menor. D'aquesta manera la freqüència d'un so és el nombre de vegades que una ona es repeteix en un espai de temps determinat.
La unitat del sistema mètric internacional per mesurar la freqüència de les ones són els hercis (Hz)
TEMPS HIGH
Per poder reproduir el so de la nota corresponent el temps que vulguem haurem de calcular el "temps high" que seria el nombre de vegades que la nota està per sobre de la línia central com es pot veure en la imatge de dalt.
Per fer-ho, només fa falta aplicar una senzilla fórmula:
Temps HIGH = 1 / (Hz * 2)
ESQUEMA ELÈCTRIC
L'esquema elèctric dels Piezo Speakers és senzill, ja que simplement haurem de connectar un dels terminals del Piezo Speaker al "pin 9" que serà per on rebrà la informació i l'altre al "ground" que serà on finalitzarà el circuit.
CODI "LITTLE STAR"
Abans de començar a fer la nostra cançó, farem tocar "Little Star":
Primerament, declararem la variable tipus "integer" anomenada "speakerPin" valor de la qual serà corresponent al pin on connectem el Piezo Speaker, en aquest cas el 9 i seguidament crearem una altra "integer" de nom "lenght" que serà equivalent al nombre de notes que tindrà la cançó, en aquest cas 15 (tenint en compte que la primera nota és 0)
Un cop fet això, crearem dues "arrays": "char notes [ ]" i "int beats [ ]". La primera tindrà a dins totes les notes que conformaran la nostra cançó i la segona serà l'encarregada de la duració de cada nota, és a dir, 1 = negra, 2 = blanca, 0,5 = corxera, etc.
Finalment, crearem un altre "integer" anomenada "tempo" que serà el tempo de la cançó, en aquest cas 300.
int speakerPin = 9;
int length = 15; // the number of notes
char notes[] = "ccggaagffeeddc "; // a space represents a rest
int beats[] = { , 1, 1, 1, 1, 1, 2, 1, 1,
void loop() {
for (int i = 0; i < length; i++) {
if (notes[i] == ' ') {
delay(beats[i] * tempo);
}
else {
playNote(notes[i], beats[i] * tempo);
}
delay(tempo / 2);
}
Primer iniciarem amb un loop.
Per començar escriurem un "for", mitjançant el qual donada una variable "integer" "i = 0", mentre "i" sigui més petita que "length", a "i" se li sumi 1.
Per cada volta del "for", però, s'hauran de complir una sèrie d'instruccions. Primerament, hi haurà un "if" mitjançant el qual si dins la variable "notes" hi ha un espai en blanc, és a dir, un silenci, farà esperar-se amb un "delay" el temps equivalent a multiplicar la variable "beats" per la variable "tempo. Per altra banda, si no es detecta un silenci ("else") es cridarà a la funció "playNote" (explicada a continuació) que demanarà la nota que s'ha de tocar "notes [i]" i el temps que s'haurà de tocar "beats[i] * tempo).
Per acabar, entre cada volta del "for" hi haurà un "delay" equivalent a la meitat del tempo.
Aquesta funció serà l'encarregada de reproduir cada nota. Primerament, es crearan dues "arrays" noves: "char names [ ]" i "int tones [ ]". La primera tindrà el nom de cada nota i la segona el "temps high" corresponent a cada nota. Un cop fet això, amb un "for" mitjançant el qual donada una "integer" "i = 0" mentre "i" sigui més petita que 8 a "i" se li haurà de sumar 1. D'aquesta manera, per cada volta del "for" s'haurà de fer complir un "if" mitjançant el qual si la variable "names" és igual que la de "tones" es cridarà la funció "playTone" explicada a continuació.
void playNote(char note, int duration) {
char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
for (int i = 0; i < 8; i++) {
if (names[i] == note) {
playTone(tones[i], duration);
}
}
}
void playTone(int tone, int duration) {
for (long i = 0; i < duration * 1000L; i += tone * 2) {
digitalWrite(speakerPin, HIGH);
delayMicroseconds(tone);
digitalWrite(speakerPin, LOW);
delayMicroseconds(tone);
}
}
Per últim, la funció "playTone" serà l'encarregada de fer que el so surti del Piezo Speaker, però amb el temps i freqüència que vulguem. Per fer-ho, mitjançant les instruccions de l'esquerra, aquesta funció generarà un senyal que farà que encaixi el "temps high" amb el del "playNote"
D'aquesta Manera, quedaria conclòs el codi per reproduir la cançó "Little Star"
CODI LA NOSTRA Cançó
int speakerPin = 9;
int length = 47; // the number of notes
char notes[] = "VBNVGFEDV VPaBVDE GFEDVG GNGFDFEVEDBaPVDN FGFEDV"; // a space represents a rest
float beats[] = { 1, 1, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.001, 0.5, 0.5, 0.5, 0.5, 1, 1, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 2, 1.5, 1, 0.5, 0.5, 1.5, 0.5, 0.5, 1.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1, 1, 0.5, 0.5, 1, 2, 3, 4, ;
int tempo = 300;
void playTone(int tone, int duration) {
for (long i = 0; i < duration * 1000L; i += tone * 2) {
digitalWrite(speakerPin, HIGH);
delayMicroseconds(tone);
digitalWrite(speakerPin, LOW);
delayMicroseconds(tone);
}
}
void playNote(char note, int duration) {
char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C', 'V' , 'B' , 'N' , 'G' , 'F' , 'E' , 'D', 'P'};
int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956, 949, 1275, 758, 637, 716, 758, 851, 1012,};
// play the tone corresponding to the note name
for (int i = 0; i < 16; i++) {
if (names[i] == note) {
playTone(tones[i], duration);
}
}
}
void setup() {
pinMode(speakerPin, OUTPUT);
}
void loop() {
for (int i = 0; i < length; i++) {
if (notes[i] == ' ') {
delay(beats[i] * tempo); // rest
} else {
playNote(notes[i], beats[i] * tempo);
}
// pause between notes
delay(tempo / 2);
}
}
Un cop explicat el codi per reproduir cançons, nosaltres tocarem l'himne d'Espanya. Per fer-ho, però, haurem de canviar alguns aspectes del codi. Primerament, per tocar l'himne d'Espanya hem hagut d'afegir notes a més de les originals (subratllades en groc a la funció "playNote") i, per tant, els seus "time high" escrits a l'array "tones". Com que en total hem utilitzat 16 notes, el "for" de la funció "playNote" serà sobre 16 i no sobre 8 com a la cançó "Little Star". Seguidament, hem hagut de canviar el valor de "length", ja que l'himne d'Espanya tenia un total de 47 notes. Com és deduïble, també vam haver de posar totes les notes noves amb les lletres que els hi vam assignar a la variable "notes" i per últim, però no menys important, vam haver de canviar el tipus de la variable "beats" d'un "integer" a un "float" pel fet que moltes de les notes eren corxeres (0,5) i els "integers" no accepten valors decimals.
Un cop fet això, i tenint en compte que la resta del codi és igual que en l'anterior cançó, l'himne d'Espanya quedaria conclòs i el podeu veure en el vídeo adjuntat