Oggi 8 dicembre 2014 è giorno di addobbi natalizi ed ho realizzato un progetto natalizio: suonerie natalizie arduino.
L’idea mi è venuta qualche giorno fa, quando Carlo, un appassionato arduino e lettore del blog, mi ha scritto che stava realizzando un progetto in cui arduino avrebbe riprodotto delle melodie natalizie.
Carlo mi ha inviato lo sketch che stava utilizzando per la riproduzione che presentava qualche problema.
Ciò che ho subito notato è la presenza di 31 brani natalizi già codificati che Carlo non so come abbia ottenuto ma per me che non sono un esperto musicista sono stati una vera e propria manna.
Il progetto delle suonerie natalizie arduino
Puoi realizzare il progetto “suonerie natalizie arduino” con pochi semplici componenti:
n.1 arduino uno ( o simili: Leonardo,Mega,ecc )
n.1 resistenza da 20 a 330ohm ( io ho scelto una 20ohm
n.1 altoparlante da 8ohm di impedenza, io ho usato quello di un vecchio Pc
n.2 cavetto per breadboard
Assembla il progetto suonerie natalizie arduino seguendo questo schema:
il filo di colore giallo lo devi collegare al positivo dell’altoparlante passando dalla resistenza che avrai scelto; il filo blu è il polo negativo e lo collegherai su Gnd.
Il collegamento è molto semplice ed ho realizzato anche delle foto per aiutarti a ricostruire il progetto, ecco ocme si presenta la resistenza saldata direttamente alla cassa:
e come puoi collegare i pin ad arduino, considera che il pin Gnd è fisso ma il pin positivo puoi collegarlo a qualsiasi pin digitale, ti basterà solo cambiarlo nello sketch, il lho collegato al pin 13:
Il progetto finale visto dall’alto dovrebbe apparirti così:
Lo sketch
Lo sketch fa uso della libreria Tone.h che puoi scaricare qui, se vuoi usarla con un IDE di versione 1.0 o superiore è necessario applicare un piccolo workaround che trovi descritto in questa issue
#include <Tone.h> Tone tone1; byte contatore = 0; #define OCTAVE_OFFSET 0 int notes[] = { 0, NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4, NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6, NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7 }; //SUONERIE NATALIZIE //char *song0 = "XMASHEARTS:d=4,o=5,b=70:16a4,8a.,16a#,8a,8g,8f,8g,8a,16g,16a,8a#,8a,8g,8f,e,8p,16e,16f,g,8g.,16a,g,8p,16a,16a#,8a,8g,8f,8g,a,8p,16a4,8a,8a,8a.,16f,8a#,8a,8p,16g#,16a,8d6,8d6,8a,8c6,a#,8p,16g,16a,a#.,8c6,8a#,8a,8p,8e,8a,8g,8f,8e,d,8p,8d,8c,8e,8f,8g,a,8p,16e,16f,g.,8c,8a#,a,8d,8c,8e,8f,8g,a,8p,8a,8g#,8a,2b,c6,2c.6"; char *song1 ="firstnoel:d=4,o=5,b=112:16e.,32p,8d,c.,8d,8e,16f.,32p,g.,8p,16a,16p,16b.,32p,c6,b,8a.,16p,g.,8p,16a.,32p,16b.,32p,c6,b,a,g,8a.,16p,b,c6,g,f,e."; //char *song2 ="firstnoel2:d=16,o=5,b=28:32f#,32e,d.,32e,32f#,32g,a.,32p,32b,32c#6,d6,c#6,b,a.,32p,32b,32c#6,d6,c#6,b,a,b,c#6,32d6,a,g,f#.,32p,32f#,32e,d.,32e,32f#,32g,a.,32p,32d6,32c#6,b.,32p,b,8a,p,d6,c#6,b,a,b,c#6,d6,a,g,f#.,32p,32f#,32e,d.,32e,32f#,32g,a.,32p,32b,32c#6,d6,c#6,b,a.,32p,32b,32c#6,32d6,c#6,b,a,b,c#6,d6,a"; char *song3 ="Angels_on_high:d=4,o=5,b=180:a,a,a,c6,c.6,8a#,2a,a,g,a,c6,a.,8g,2f,a,a,a,c6,c.6,8a#,2a,a,g,a,c6,a.,8g,2f,2c6,8d6,8c6,8a#,8a,2a#,8c6,8a#,8a,8g,2a,8a#,8a,8g,8f,g.,8c,2c,f,g,a,a#,2a,2g,1f"; char *song4 ="All I Want For Christmas:d=4,o=5,b=100:c,e,g,b,a,2a,8g,8e,c,e,g,b,a,2d,a,b4,d,f,b,a,2a,8d,8e,f,g,a,b,1g,c,e,g,b,a,2a,8g,8e,c,e,g,b,a,2d,a,b4,d,f,b,a,2a,8d,8e,f,g,a,b,c6,g,c6,c6,d6,a,a,8b,8d6,c6,g,2g,b,a,g,f,2e.,e,a,e,e,8f#,8a,g,d,2d,f#,e,d,c"; char *song5 ="In the Bleak MidWinter:d=4,o=5,b=112:b.,8c6,d6,b,2a,2g,a.,8b,a,e,2a.,p,b.,8c6,d6,b,2a,2g,a.,8b,a.,8g,2g.,p,c6,b,c6,d6,e6,e6,2b,d.6,8b,a.,8g,2a.,p,b.,8c6,d6,b,2a,2g,a.,8b,a.,8g,2g."; char *song6 ="Jingle Bells 2:d=4,o=5,b=225:b4,g#,f#,e,2b.4,c,c#,a,g#,f#,2c#,p,8c#,8p,c#,a,g#,f#,2b.,g#,f#,c#,d#,8e.,32p,2f#,p,8b4,8p,b4,g#,f#,e,2b.4,c,c#,a,g#,f#,2c#,p,8c#,8p,c#,a,g#,f#,b,g#,8e.,g#,8f#,8p,f#,g#,a#,2b,2p,b4,g#,f#,e,2b.4,c,c#,a,g#,f#,2c#,p,8c#,8p,8c#.,32p,a,g#,f#,2b.,g#,f#,c#,d#,e,2f#,p,8b4,8p,b4,g#,f#,e,2b.4"; char *song7 ="Jingle Rock Rock:d=8,o=5,b=160:32c6,p,c6,c6,p,16b,16p.,b,b,p,a,32p,b,a,p,e,4p.,a,32p,b,a,16p.,e,p,g,p,a,32p,b,a,p,f,4p.,d,32p,e,f,p,g,p,a,p,d,32p,e,f,p,g,p,16a,16p,a,a,16p,b,p,g,c6"; /* char *song8 ="Jolly Old St Nicholas:d=8,o=5,b=112:d6,d6,d6,d6,c6,c6,4c6,a#,a#,a#,a#,2d6,g,g,g,g,f,f,4a#,a,a#,c6,d6,2c6,d6,d6,d6,d6,c6,c6,4c6,a#,a#,a#,a#,2d6,g,g,g,g,f,f,4a#,c6,a#,c6,d6,4a#"; char *song9 ="Joy to the World:d=8,o=5,b=56:4c6,b.,16a,4g.,f,4e,d.,16p,4c.,g,4a.,a,4b.,b,2c.6,p,c6,c6,b,a,g,g.,16f,e,c6,c6,b,a,g,g.,16f,e,e,e,e,e,16e,16f,4g.,16f,16e,d,d,d,16d,16e,4f.,16e,16d,c,4c6,a,g.,16f,e,f,4e,4d,2c"; char *song10="Let it Snow:d=4,o=5,b=125:8c,8c,8c6,8c6,a#,a,g,f,2c,8c,16c,g.,8f,g.,8f,e,2c,d,8d6,8d6,c6,a#,a,2g.,8e.6,16d6,c6,8c.6,16a#,a,8a#.,16a,2f.,c,8c6,8c6,a#,a,g,f,2c,8c.,16c,g.,8f,g.,8f,e,2c,d,8d6,8d6,c6,a#,a,2g.,8e.6,16d6,c6,8c.6,16a#,a,8a.,16g,2f."; char *song11="Rudolph The Red Nose Reindeer:d=4,o=5,b=250:8g,a,8g,e,c6,a,2g.,8g,8a,8g,8a,g,c6,2b.,p,8f,g,8f,d,b,a,2g.,8g,8a,8g,8a,g,a,2e.,p,8g,a,8a,e,c6,a,2g.,8g,8a,8g,8a,g,c6,2b.,p,8f,g,8f,d,b,a,2g.,8g,8a,8g,8a,g,d6,2c.6,p,a,a,c6,a,g,e,2g,d,e,g,a,b,b,2b,c6,c6,b,a,g,f,2d,8g,a,8g,e,c6,a,2g.,8g,8a,8g,8a,g,c6,2b.,p,8f,g,8f,d,b,a,2g.,g,a,g,a,"; char *song12="Santa Claus is Coming to Town:d=4,o=5,b=200:g,8e,8f,g,g.,8g,8a,8b,c6,2c6,8e,8f,g,g,g,8a,8g,f,2f,e,g,c,e,d,2f,b4,1c,p,g,8e,8f,g,g.,8g,8a,8b,c6,2c6,8e,8f,g,g,g,8a,8g,f,f,e,g,c,e,d,2f,b4,1c,p,c6,d6,c6,b,c6,a,2a,c6,d6,c6,b,c6,2a.,d6,e6,d6,c#6,d6,b,b,b,8b,8c6,d6,c6,b,a,g,p,g.,8g,8e,8f,g,g.,8g,8a,8b,c6,2c6,8e,8f,g,g,g,8a,8g,8f,2f,"; char *song13="Sleigh Ride:d=8,o=5,b=225:b,p,b,p,b,p,b,p,c#6,p,b,16g#,4e,f#,p,g#,p,f#,16d#,4c#,1b4,4p,c#,16p.,d#,p,f#,p,b,p,c#6,p,b,g#,f#,e,f#,p,f#,g#,f#,e,4c#,1e,4p,b,p,b,p,b,p,b,p,c#6,p,b,16g#,4e,f#,p,g#,p,f#,16d#,4c#,1b4,4p,c#,p,d#,p,f#,16p.,b,p,c#6,p,b,g#,f#,e,f#,p,f#,g#,f#,e,4c#,1e,4p,b,p,b,p,b,p,b,p,c#6,p,b,16g#,4e,"; char *song14="The First Noel:d=16,o=5,b=28:32f#,32e,d.,32e,32f#,32g,a.,32p,32b,32c#6,d6,c#6,b,a.,32p,32b,32c#6,d6,c#6,b,a,b,c#6,32d6,a,g,f#.,32p,32f#,32e,d.,32e,32f#,32g,a.,32p,32d6,32c#6,b.,32p,b,8a,p,d6,c#6,b,a,b,c#6,d6,a,g,f#.,32p,32f#,32e,d.,32e,32f#,32g,a.,32p,32b,32c#6,d6,c#6,b,a.,32p,32b,32c#6,32d6,c#6,b,a,b,c#6,d6,a"; char *song15="Twelve Days of Christmas:d=16,o=5,b=90:c.,c.,8c.,f.,f.,8f.,e.,f.,g.,a.,a#.,g.,4a,32p,a#.,8c.6,d.6,a#.,a.,f.,8g.,2f,c.,c.,c.,f.,f.,f.,8f.,e.,f.,g.,a.,a#.,g.,4a.,8c.6,g.,a.,8a#.,a.,a#.,8c.6,d.6,a#.,a.,f.,8g.,4f."; char *song16="12 Days OF Christmas:d=4,o=5,b=140:8d,8d,d,8g,8g,g,8f#,8g,8a,8b,8c6,8a,b,8p,8c6,d6,8e6,8c6,8b,8g,a,2g,8d6,8d6,d6,8g6,8g6,g6,8f#6,8g6,8a6,8b6,8c7,8a6,2b6,d7,8a,8b,c6,8b6,8c7,d7,8e7,8c7,8b6,8g6,a6,2g.6,8f#,8f#,f#,8b,8b,b"; char *song17="CarolBells:d=8,o=5,b=180:4a,g#,a,4f#,4a,g#,a,4f#,4f#6,f#6,f#6,e6,d6,4c#6,c#6,c#6,b,a,4b,b,b,c#6,b,4f#,f#,f#,4f#,c#,d#,e,f#,g#,a,b,c#6,4b,4a,c#,d#,e,f#,g#,a,b,c#6,4b,4a,4a,g#,a,4f#,4a,g#,a,4f#"; char *song18="Away In A Manger:d=4,o=5,b=112:d6,d.6,8c6,b,b.,8a,g,g,f#,e,2d,d,d.,8e,d,d,a,f#,e,d,g,2b,d6,d.6,8c6,b,b.,8a,g,g,f#,e,2d,d,c.6,8b,a,b,a,g,a,e,f#,2g,d6,d.6,8c6,b,b.,8a,g,g,f#,e,2d,d,d.,8e,d,d,a,f#,e,d,g,2b"; char *song19="Ill be home for Xmas:d=8,o=6,b=40:c.7,16b,d.7,16c7,g,4g,p,a.,16g,a#.,16a,4d,p,d.,16e,g.,16f,e.,16g,c.7,16b,d7,d7,b,32p,16b,4a,g,p,c.7,c.7,16b,d.7,16c7,g,4g,p,a.,16g,a#.,16a,4d,p,d.,16e,g.,16f,e.,16g,c.7,16b,d7,d7,b.,16b,4a,g,p,c.7,c.7,16b,d.7,16c7,g,4g,p,a.,16g,a#.,16a,4d,p,d,32p,16e,g.,16f,e.,16g,c.7,16b,d7,d7,b.,"; char *song20="Deck The Halls:d=4,o=5,b=160:c.6,8a#,a,g,f,g,a,f,8g,8a,8a#,8g,a.,8g,f,e,2f,c.6,8a#,a,g,f,g,a,f,8g,8a,8a#,8g,a.,8g,f,e,2f,g.,8a,a#,g,a.,8a#,c6,g,8a,8b,c6,8d6,8e6,f6,e6,d6,2c6,c.6,8a#,a,g,f,g,a,f,8d6,8d6,8d6,8d6,c.6,8a#,a,g,2f"; char *song21="I Saw Mommy Kissing Santa Claus:d=4,o=6,b=160:2c.,d,e,g,a,8c7,2b.,g,2e,a,g,e,c,a,g,e,8c.,2b.5,f,e,d,d.,8c#.,2d.,8a.,16b.,8a.,g.,f#.,8a.,2g.,e,d,e,f#,g,a,g#,a,a#,b,a,f,8e,2d.,g,2c.,d,e,g,a,8c7,2b,g,2e,a,g,2e,16c,a,g,e,8c.,2a,16g#,8a.,16b,c7,8c.7,c7,8d.7,1b,f#,8a.,16a,g,f,8e,2d,8e.,2f,g,a,8c.7,a,2c7,2d7,1c7"; char *song22="Feliz Navidad:d=4,o=5,b=140:8a,d6,8c#6,8d6,2b.,p,8b,e6,8d6,8b,2a.,p,8a,d6,8c#6,8d6,b.,8g,b,b,8a,8a,8b,8a,g,8g,1f#,p,8a,d6,8c#6,8d6,2b.,p,8b,e6,8d6,8b,2a.,p,8a,d6,8c#6,8d6,b.,8g,b,b,8a,8a,8b,8a,g,8g,1f#,p,8f#6,8f#6,8f#6,8f#6,e6,8d6,d6,b,8b,d.6,8p,8e6,8e6,8e6,e6,8d6,8b,b,a,8g#,a."; char *song23="Frosty The Snowman:d=4,o=5,b=140:2g,e,8p,8f,g,2c6,8b,8c6,d6,c6,b,a,2g,p,8b,8c6,d6,c6,b,8a,8a,8g,c6,e.,8f,8a,g,f,e,f,2g,2p,2g,e,8p,8f,g,2c6,8b,8c6,d6,c6,b,a,2g,p,8b,8c6,d6,c6,b,8a,8a,8g,c6,e.,8g,8a,g,f,e,d,2c,p,c,a,a,c6,c6,b,a,g,e,f,a,g,f,2e,p,e,d,d,g,g,b,b,d6,8d6,8b,d6,c6,b,a,g,p,2g"; char *song24="Have Yourself A Merry Little Christmas:d=4,o=5,b=100:16b4,8c,8e.,g.,16b,8c6,8g,f,16p,8e,16d,c,16c,d.,8p,16b4,8c,8e,g.,16b,8c.6,2g,p,e,g,c6,16d6,8e.6,8d.6,8c6,8b,8a,g,16e,f,2e,16p,8f,16g,16d,16d,8c,8d,16a4,c.,e,g,16b,8c.6,8g,f.,16p,8e,16d,8c,16d,16e,8d.,8e,8p,16c,8e,g.,16b,8c6,2g,p,e,g,c6,d6,8d.6,16c6,16p,8b,16a,g#.,8b.,16b,2c.6,16p"; char *song25="Last Christmas:d=4,o=5,b=112:16d6,e6,8p,e6,8d6,8p,8a,8e6,8e6,8f#6,d.6,8b,8b,8e6,8e6,f#6,d.6,8b,8c#6,8d6,8c#6,2b.,16e6,f#6,8p,e.6,8p,8b,8f#6,8g6,8f#6,2e6,8d6,8c#6,8d6,8c#6,c#6,8d6,8p,8c#6,8p,2a,16d6,e6,8p,e6,8d6,8p,8a,8e6,8e6,8f#6,d.6,8b,8b,8e6,8e6,f#6,d.6,8b,8c#6,8d6,8c#6,2b.,16e6,f#6,8p,e.6,8p,8b,8f#6,8g6,8f#6,2e6,8d6,8c#6,8d6,8c#6,c#6,8d6,8p,8c#6,8p,a"; char *song26="chestnuts Roasting On An Open Fire:d=4,o=5,b=125:8d#,16p,16d6,8d#6,16c#6,8d.6,8c6,a#,8g#,8p,16f,8g.,8a#,a#,16a#,8c.6,2d#,p,8d#,16p,16a#,8c6,a#,8g#,16f,8g.,8a#,16d#,16f,1d#,p,8c,16d,16d#,8d,8d#,f.,p,8d,8d#,8f,8f,g,8a#,8p,8c6,8g,16c6,1d6,8c6,8b,8c6,d.6,8b,16p,16b,c#6,8b,8p,a#,8g#,8p,16g#,1a#,p,p"; char *song27="we Wish You A Merry Christmas:d=4,o=5,b=200:d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d,d,b,8b,8c6,8b,8a,g,e,d,e,a,f#,2g,d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d,d,b,8b,8c6,8b,8a,g,e,d,e,a,f#,1g,d,g,g,g,2f#,f#,g,f#,e,2d,a,b,8a,8a,8g,8g,d6,d,d,e,a,f#,2g"; char *song28="Winter Wonderland:d=4,o=5,b=112:8a#.,16a#,2a#.,8a#.,16a#,g,2a#,8a#.,16a#,2a#.,8a#.,16a#,g#,2a#,8p,16a#,8d.6,16d6,8d.6,c.6,8p,16c6,8a#.,16a#,8a#.,g#.,8p,16g#,8g.,16g,8g.,16g,8f.,16f,8f.,16f,2d#,p,8a#.,16a#,2a#.,8a#.,16a#,g,2a#,8a#.,16a#,2a#.,8a#.,16a#,g#,2a#,8p,16a#,8d.6,16d6,8d.6,c.6,8p,16c6,8a#.,16a#,8a#.,g#.,8p,16g#,8g.,16g,8g.,16g,8f.,16f,8f.,16f,2d#,p,8d.,16d,8b.,16b,8e.,16e,8c.6,16c6,b,2g,p,8d.,16d,8b.,16b,8e.,16e,8c.6,16c6,2b.,p"; char *song29="Mary's boy child - Bony M:d=16,o=6,b=40:32g,32p,g,g,c7,c7,a,f,d,32a,32a,g,b,a,f,4e,g,e7,d7,c7,a,f,d.,g,c7,b,d7,4c7,e7,e7,f7,f7,d7,d7,e.7,32e7,c7,c7,d7,c7,8b.,a,g,e7,d7,c7,a,f,d.,32a,g,c7,b,d7,4c7,32g,32p,g,g,c7,c7,a,f,d,32a,32a,g,b,a,f,8e.,32p,g,e7,d7,c7,a,f,d.,32a,g,c7,b,d7,4c7,e7,e7,f7,f7,d7,d7,e.7,32e7,c7,c7,d7,c7,8b"; char *song30="cristmas In Our Hearts:d=4,o=5,b=70:16a4,8a.,16a#,8a,8g,8f,8g,8a,16g,16a,8a#,8a,8g,8f,e,8p,16e,16f,g,8g.,16a,g,8p,16a,16a#,8a,8g,8f,8g,a,8p,16a4,8a,8a,8a.,16f,8a#,8a,8p,16g#,16a,8d6,8d6,8a,8c6,a#,8p,16g,16a,a#.,8c6,8a#,8a,8p,8e,8a,8g,8f,8e,d,8p,8d,8c,8e,8f,8g,a,8p,16e,16f,g.,8c,8a#,a,8d,8c,8e,8f,8g,a,8p,8a,8g#,8a,2b,c6,2c.6"; */ char *songs[6]; void setup(void) { Serial.begin(9600); tone1.begin(13); songs[0] = song1; songs[1] = song3; songs[2] = song4; songs[3] = song5; songs[4] = song6; songs[5] = song7; } #define isdigit(n) (n >= '0' && n <= '9') void loop(void) { if (contatore < 0 || contatore > 5 ) contatore = 0; Serial.println( contatore ); play_rtttl(songs[contatore]); delay(1000); contatore++; } void play_rtttl(char *p) { byte default_dur = 4; byte default_oct = 6; int bpm = 63; int num; long wholenote; long duration; byte note; byte scale; // format: d=N,o=N,b=NNN: // find the start (skip name, etc) while(*p != ':') p++; // ignore name p++; // skip ':' // get default duration if(*p == 'd') { p++; p++; // skip "d=" num = 0; while(isdigit(*p)) { num = (num * 10) + (*p++ - '0'); } if(num > 0) default_dur = num; p++; // skip comma } Serial.print("ddur: "); Serial.println(default_dur, 10); // get default octave if(*p == 'o') { p++; p++; // skip "o=" num = *p++ - '0'; if(num >= 3 && num <=7) default_oct = num; p++; // skip comma } Serial.print("doct: "); Serial.println(default_oct, 10); // get BPM if(*p == 'b') { p++; p++; // skip "b=" num = 0; while(isdigit(*p)) { num = (num * 10) + (*p++ - '0'); } bpm = num; p++; // skip colon } Serial.print("bpm: "); Serial.println(bpm, 10); // BPM usually expresses the number of quarter notes per minute wholenote = (60 * 1000L / bpm) * 4; // this is the time // for whole note (in milliseconds) Serial.print("wn: "); Serial.println(wholenote, 10); // now begin note loop while(*p) { // first, get note duration, if available num = 0; while(isdigit(*p)) { num = (num * 10) + (*p++ - '0'); } if(num) duration = wholenote / num; else duration = wholenote / default_dur; // we will need to check // if we are a dotted note after // now get the note note = 0; switch(*p) { case 'c': note = 1; break; case 'd': note = 3; break; case 'e': note = 5; break; case 'f': note = 6; break; case 'g': note = 8; break; case 'a': note = 10; break; case 'b': note = 12; break; case 'p': default: note = 0; } p++; // now, get optional '#' sharp if(*p == '#') { note++; p++; } // now, get optional '.' dotted note if(*p == '.') { duration += duration/2; p++; } // now, get scale if(isdigit(*p)) { scale = *p - '0'; p++; } else { scale = default_oct; } scale += OCTAVE_OFFSET; if(*p == ',') p++; // skip comma // now play the note if(note) { Serial.print("Playing: "); Serial.print(scale, 10); Serial.print(' '); Serial.print(note, 10); Serial.print(" ("); Serial.print(notes[(scale - 4) * 12 + note], 10); Serial.print(") "); Serial.println(duration, 10); tone1.play(notes[(scale - 4) * 12 + note]); delay(duration); tone1.stop(); } else { Serial.print("Pausing: "); Serial.println(duration, 10); delay(duration); } } }
lo sketch è lungo ma ben scritto per cui ci metterai proco a comprendere come funziona, partiamo dalla linea 001: includi la libreria Tone.h;
linea 003: inizializza l’oggetto tone1;
linea 005: crea un contatore il cui valore andrà da 0 a 6 per cui puoi usare il classico int o come ho fatto io il byte per risparmiare memoria arduino;
linea 007: imposta il valore della costante OCTAVE_OFFSET a 0;
linee 009-013: definisi tutte le note che userai per il progetto suonerie natalizie arduino;
linee 017-049: sono tutte le canzoni natalizie che puoi usare; ogni canzone è indicata come songX dove X è un valore numerico da 0 a 30 ( 31 suonerie ). Avrai notato che sono quasi tutte commentate in quanto se le decommenti tutte sovraccarichi la memoria arduino non riuscendo ad eseguire nessuna suoneria. Dai test che ho eseguito puoi caricare al massimo 6 suonerie in un arduino uno senza rischiare errori in fase di esecuzione o blocco dello sketch;
linea 051: definisci un array da 6 elementi che userai per definire quali suonerie eseguire;
linea 055: imposta per l’ìoggetto tone il pin a cui hai connesso la cassa, nel mio caso il 13;
linee 057-062: imposta per ciascun elemento dell’array songs la suoneria natalizia che desideri sia eseguita;
lineea 065: imposta la costante funzionale isdigit(n) ossia una funzione statica il cui scopo è restituirti true se n è un numero ed è compreso tra 0 e 9, e false in caso contrario. La userai in seguito;
linea 068: imposta un controllo per ogni ciclo in modo che il valore della variabile contatore sia compreso tra 0 e 5;
linea 070: richiama la funzione, definita in seguito, play_rtttl a cui passi il brano da riprodurre per il tuo progetto suonerie natalizie arduino;
linea 071: aspetta 1 sec tra una esecuzione e la successiva;
linea 072: incrementa il valore di contatore di uno;
linea 075: definisci la funzione play_rtttl() il cui scopo è analizzare tutte le informazioni che potrai passargli sulla suoneria e controllare il pin 13 per eseguire la melodia;
linee 077-084: definisci tutte le variabili che servono ad eseguire il brano, come la durata della nota la durata di default, la nota ecc..
char *song7 ="Jingle Rock Rock:d=8,o=5,b=160:32c6,p,c6,c6,p,16b,16p.,b,b,p,a,32p,b,a,p,e,4p.,a,32p,b,a,16p.,e,p,g,p,a,32p,b,a,p,f,4p.,d,32p,e,f,p,g,p,a,p,d,32p,e,f,p,g,p,16a,16p,a,a,16p,b,p,g,c6";
linee 089-090: scorri tutta la linea, ne ho riportata una di esempio subito sopra, fino a quando non trovi i “:” e li salti come posizione, hai trovato il titolo;
linee 093-101: se il valore posizionale “p” è uguale a d, e dovrebbe esserlo guardando la riga, salta due posizioni “d=” e leggi il numero in base 10, fino a quando la funzione isdigit() ti restituisce true, nell’esempio della suoneria “Jingle Rock Rock” la durata è 8 per cui il valore di num al termine sarà:
num = ( num * 10 ) + ( 8 – 0 ) = ( 0*10 ) + ( 8 – 0 ) = 0 + 8 = 8;
infine se num > 0 lo imposti come durata di default;
linee 106-111: esegui le stesse operazioni per il valore “o=”, al termine varrà 5 nel nostro esempio, quindi selezioni la 5° ottava;
linee 116-124: esegui nouvamente la medesima operazione per i BPM ( Battiti per minuto ) il cui valore, nell’esempio, sarà 160;
linea 129: calcola le battute al minuto partendo dall’informazione che sono solitamente espresse in 1/4 al minuto per cui devi moltiplicarle per 4;
linea 135: inizia a suonare la melodia, quindi esegui un ciclo while sul valore posizionale p che legge nota per nota e la esegue con il tempo indicato, vediamo come fa;
linee 138-141: per ciascuna nota leggi la durata, ad esempio per la prima nota dell’esempio avrai: 32;
linee 143-144: calcola la durata della nota in funzione del BPM o della durata di default se non è di tipo numerico;
linee 150-176: leggi la nota ( in formato testuale ) da “a” a “g” più la “p” per la pausa e valorizza la variabile note con il malore numerico corrispondente nella scala delle ottave;
linee 178-182: se la nota presenta un “#” shifta di uno il valore della nota, avrai notato che le note delle righe precedenti non corrispondono a valori numerici consecutivi 1,3,5,6,8,10,12. Se la nota fosse del tipo “c#” invece di essere 1 il suo valore sarebbe 2;
linee 184-188: se la nota è eseguita da un “.” il suo valore in durata è la metà;
linee 190-196: calcola la scala su cui eseguire la nota;
linea 198: somma alla scala calcolata l’ottava di offset da cui partire;
linea 200: salta il valore “,” che interrompe ogni nota in modo che il ciclo while successivo si ritrovi a partire sempre con la durata della nota;
linee 202-218: finalmente è il momento di eseguire la nota per la durata stabilita e sulla scala definita, insomma ascoltiamo finalemente le suonerie natalizie arduino e per farlo concentrati solo sulle linee 210,211 e 212: la prima imposta il tono della nota da eseguire, la seconda attende il tempo necessario alla durata della nota e la terza riga ferma il tono con uno stop();
linee 213-216: servono solo in caso di pausa ed usano u delay della durata calcolata per eseguirlo;
Buon divertimento con le suonerie natalizie arduino:
Jacopo ha realizzato un video da condividere sul progetto:
50 commenti
1 ping
Vai al modulo dei commenti
Ho importato la libreria e provato a caricare il codice, ma mi dà il seguente errore:
http://pastebin.com/1VE8U2Dk
Autore
Ciao Marco,
hai eseguito la modifica descritta nell’articolo e riportata nel sito dell’autore della libreria?
SI funziona tutto, avevo sbagliato a correggere la libreria. Grazie mille e scusami =)
Autore
Ottimo Marco.
anche facendo le modifiche come da te suggerito, mi da errore.
This report would have more information with
“Show verbose output during compilation”
enabled in File > Preferences.
Arduino: 1.0.5 (Linux), Board: “Arduino Uno”
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp: In member function ‘void Tone::begin(uint8_t)’:
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp:121: error: ‘bitWrite’ was not declared in this scope
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp:123: error: ‘digitalPinToPort’ was not declared in this scope
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp:123: error: ‘portOutputRegister’ was not declared in this scope
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp:124: error: ‘digitalPinToBitMask’ was not declared in this scope
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp: In member function ‘void Tone::play(uint16_t, uint32_t)’:
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp:198: error: ‘OUTPUT’ was not declared in this scope
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp:198: error: ‘pinMode’ was not declared in this scope
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp:294: error: ‘bitWrite’ was not declared in this scope
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp: In member function ‘void Tone::stop()’:
/home/iz2rpn/Scaricati/arduino-1.0.5/libraries/Tone/Tone.cpp:361: error: ‘digitalWrite’ was not declared in this scope
Autore
Ciao Pietro,
hai provato a scaricare l’ultima versione della libreria ?
Mi sembra che ci siano troppi errori, la libreria Tone è composta da Tone.h e Tone.cpp hai scaricato entrambe dal link presente nell’articolo?
Stranamente funziona solo su la ide 1.0.6 non spiegarmi il perchè. Cmq meglio cosi, bel code, grazie.
Autore
Ciao Pietro,
se riprovi con la 1.0.5 ti da nuovamente l’errore?
Controlla di aver posizionato la libreria nel path Documents/libraries del tuo utente e non tra le librerie dell’IDE.
Salve, anche a me da degli errori del genere con le modifiche fatte a tone.cpp (spero di non aver sbagliato):
Ci puoi delucidare sulla modifica del tone.cpp :
Grazie
This report would have more information with
“Show verbose output during compilation”
enabled in File > Preferences.
Arduino: 1.0.6 (Windows 7), Board: “Arduino Uno”
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:100: error: ‘Tone’ has not been declared
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:103: error: ‘Tone’ has not been declared
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp: In function ‘void begin(uint8_t)’:
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:107: error: ‘_pin’ was not declared in this scope
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:108: error: ‘_timer’ was not declared in this scope
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:182: error: ‘_timer’ was not declared in this scope
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp: At global scope:
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:190: error: ‘Tone’ has not been declared
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp: In function ‘void play(uint16_t, uint32_t)’:
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:196: error: ‘_timer’ was not declared in this scope
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:199: error: ‘_pin’ was not declared in this scope
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp: At global scope:
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:333: error: ‘Tone’ has not been declared
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp: In function ‘void stop()’:
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:335: error: ‘_timer’ was not declared in this scope
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:362: error: ‘_pin’ was not declared in this scope
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp: At global scope:
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:366: error: ‘Tone’ has not been declared
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp: In function ‘bool isPlaying()’:
C:\Users\MASSIMO\Documents\Arduino\libraries\Tone\Tone.cpp:370: error: ‘_timer’ was not declared in this scope
Autore
Ciao Massimo,
hai scaricato entrambi i files .h e .cpp dal sito indicato?
si ho controllato e i file ci sono tutti, ma credo (non sono molto afferato con arduino, ma mi appassiona) di aver sbagliato ad inserirli (devo inserirli nel path Documents/libraries del mio utente e non tra le librerie dell’IDE giusto?).
Autore
Giusto Massimo,
le librerie che aggiungi devi metterle nella directory ( o path ) del tuo utente in modo che:
1) tu abbia disponibile le librerie aggiuntive anche se rimuovi l’IDE
2) tu possa installare più versioni dell’IDE non dovendo copiare in ciascuna le librerie/esempi/sketch
Ho fatto come mi consigliate e la libreria nuova la trovo nella lista delle librerie dell’IDE ma “NADA” niente mi da una serie di errori ( ho fatto anche come consiglia Alessandro ma niente) dove sbaglio?
ha…ho provato anche con un Mega 2560 sempre niente, il sistema operativo che uso è un Win 7 64bit…
Mi potete aiutare??
Grazie
Autore
Ciao Massimo,
l’errore riguarda l’include della libreria o l’uso ?
Se è quello che ha postato anche Alessandro è dovuto ad un errata posizione della patch nella libreria.
Ragazzi….
seguite le istruzioni di patch Tone.cpp che funziona..
fate solo copia incolla dopo la prima definizione
Testato su Arduino 1.0.5
#if defined(__AVR_ATmega8__)
#define TCCR2A TCCR2
#define TCCR2B TCCR2
#define COM2A1 COM21
#define COM2A0 COM20
#define OCR2A OCR2
#define TIMSK2 TIMSK
#define OCIE2A OCIE2
#define TIMER2_COMPA_vect TIMER2_COMP_vect
#define TIMSK1 TIMSK
#endif
#if ARDUINO > 22
#include “Arduino.h”
#else
#include
#include
#endif
Autore
Grazie Alessandro.
Salve, pur avendo copiato le librerie ed usando sia Arduino 1.0.5 che Arduino 1.0.6, con win Xp, mi arrivano una serie di errori che iniziano con:Toni_natalizi\Tone.cpp.o: In function `Tone::begin(unsigned char)’:
Autore
Ciao Renzo,
se leggi tra i commenti vedrai che altri utenti si sono trovati già ad vere i medesimi errori ed ho suggerito di applicare una patch al codice delle librerie.
Anche Alessandro, un appassionato e lettore del blog, ha indicato come eseguire la modifica alla libreria.
Fatto, incollato all’inizio di Tone.cpp tutto come prima
Contrordine, ho solo rinominato la cartella che avevo in da a e va .
Chissà perché?
Grazie Renzo
Autore
Ciao Renzo, sono contento … ma cos’hai rinominato? così anche altri utenti che hanno lo stesso problema potrebbero risolvere come hai fatto tu.
Contrordine, ho solo rinominato la cartella che avevo in libraries da Toni_natalizi a toni e va .
Chissà perché?
Grazie Renzo
p.s. la formattazione de testo non è riprodotto
Autore
Grazie per la delucidazione !!!
salve.
mi da un errore anche dopo aver riportato le opportune modifiche.
questo è l’errore:
sketch_feb06a.ino:14:10: error: #include expects “FILENAME” or
Mi potrebbe aiutare.
grazie
Autore
Ciao Emanuele,
la libreria tone l’hai caricata in arduino ?
Non mi sembra sia inclusa nell’IDE.
Ciao Mauro
sono ritornato con un altro problema.
Ho provato a inserire nel famoso centralina alba la suoneria natalizia , poichè due funzioni di loop() non possono
esistere ho eliminato void loop (void) , ma ottengo errore ,mi dice che play_rtt1 non è declared per questo scopo.
Vorrei sapere quale errore sto facendo e se mi puoi aiutare a risolvere.
Grazie Giuseppe
chiedo scusa forse non mi sono spiegato bene,La mia intenzione è voler inserire le suonerie natalizie anzi una suoneria , mentre avviene il giorno e per la durata di tale fase , Ottengo errore durante la compilazione.Volevo sapere cosa sbaglio e come corregere,
Grazie Giuseppe
Autore
Ciao Giuseppe,
se mi indichi l’errore posso provare ad aiutarti.
Ciao Mauro, ti indico l’errore che ottengo :: In function ‘void loop()’:
:93:32: error: ‘play_rtttl’ was not declared in this scope
:97:26: error: a function-definition is not allowed here before ‘{‘ token
:305:1: error: expected ‘}’ at end of input
Errore durante la compilazione.
Approfitto di chiederti anche la centralina alba ho voluto aumentare il tempo delle fasi a due minuti cosi come esposto dalla tabella elaborata da te Ma risulta il tempo negativo e gli step 0. cosa posso fare .Grazie
Autore
Ciao Giuseppe,
è un errore di sintassi, hai fatto confusione con le parentesi graffe e non riesce a capire dove finisce una funzione e dove inizia un’altra.
Controlla di aver aperto e chiuso correttamente le funzioni e vedrai che si risolve.
Per l’altro quesito ti chiedo di aggiungerlo allo sketch che stai leggendo perché non sono in grado di aiutarti in questo modo.
sto controllando la sintassi non riesco ancora a capire quale parentesi graffa manca o in eccesso ,perchè digitando Ctrl+T non ottengo errore. continuerò a sbattere la testa.
Per l’altro quesito ho inserito alle fasi della centralina alba i 4 valori corrispondenti a due minuti di funzionamento totale cosi come descritto dalla tua tabella (alba,giorno,tramonto,notte) e risulta dal monitor seriale fase sun tempo corrente -19598 e single step -376 e quindi si blocca il ciclo..Vorrei tanto capire il perchè.
Ti ringrazio Giuseppe
Autore
Ciao Giuseppe,
dovresti aggiungere il commento sui tempi che hai variato all’articolo corretto perché io possa aiutarti.
Ho solo aggiunto le fasi corrispondente a due minuti tutto il programma è rimasto invariato Aggiungo la prima parte dello sketch perchè se invio l’intero sketch mi entra la sicurezza e sparisce il mio commento:
#define pin_down 3
#define pin_sun 5
#define pin_sunset 6
#define pin_moon 9
#define pin_starsA 10
#define pin_starsB 11
int oneminrome[4] = { 8389,45915,8390,57303 };
int timeStepOld = 0;
int timeStep = 0;
long timeCurr = 0;
byte fade[] = {255,250,245,240,235,230,225,220,215,210,205,200,195,190,185,180,175,170,165,160,155,150,145,140,135,130,125,120,115,110,105,100,95,90,85,80,75,70,65,60,55,50,45,40,35,30,25,20,15,10,5,0}; // 52 step
byte curr = 0;
N.B:
quando lancio il programma e apro il monitor seriale appaiano i 52 step del down dopo scrive tempo corrente -19598 single step -376 sun
Autore
Ciao Giuseppe,
ti avevo chiesto la cortesia di non incollare sketch ma di inserire solo il commento nell’articolo corretto.
In futuro non risponderò più a commenti non posizionati nell’articolo corretto perché impossibile mi è farlo.
Prova a cambiare byte con int e dovrebbe funzionare.
scusa tanto
Autore
Nessun problema Giuseppe.
Se hai altre richieste di chiarimenti falle pure negli articoli che leggi.
Ciao Mauro riprendendo lo sketch precedente ho voluto inserire tre canzoni natalizie nello sketch centralina alba tramonto. siccome nello sketch delle suonerie ci sono due funzioni void loop e void play_rttt1(char *p) è chiaro che devo usare un solo loop ma quel void play_rttt1 (char *p) se lo elimino mi da errore perchè non conosce la *p se la inserisco mi dice le parentesi graffe non chiude il loop. Fa sembrare un errore di sintassi l’errore che ottengo :
Arduino:1.6.1 (Windows 7), Scheda:”Arduino Uno”
centralina_con_quattro_rele.ino: In function ‘void loop()’:
centralina_con_quattro_rele.ino:154:26: error: a function-definition is not allowed here before ‘{‘ token
centralina_con_quattro_rele.ino:305:1: error: expected ‘}’ at end of input
Errore durante la compilazione
Le parentesi graffe ho controllato racchiudono tutte le definizione .Spero di essere stato chiaro e grazie per l’aiuto
Autore
Ciao Giuseppe,
le parentesi {} devono definire una sola funzione e non racchiudere più funzioni.
Prova a leggere sul web come si definiscono le funzioni in C vedrai che ciascuna funzione è definita entro le {}
Ciao Mauro ho letto come si definiscono le funzioni . Per risolvere il problema ho inserito lo sketch della suoneria
dopo la fine del loop dello sketch della centralina alba tramonto . In questo modo la compilazione va buon fine
ma non risolve il problema . La suoneria non funziona . Il mio desiderio è far suonare una canzone
natalizia durante la fase del giorno che dura 45 sec. Come devo modificare lo sketch. Grazie
Autore
Ciao Giuseppe,
certo, gli sketch servono a indicare ad arduino come eseguire quello che desideri.
Come ti ho scritto qualche commento fa non si tratta di sole modifiche ma di sconvolgere l’intero ragionamento logico con cui i due sketch lavorano.
Magari per il prossimo natale ci ragiono su e trovo una soluzione, ad oggi non l’ho trovata.
Ok grazie allora aspetterò il prossimo natale in attesa elaborerò la parte scenica e l’illuminazione.
Autore
Ciao Giuseppe, se nell’attesa ottieni un risultato prima del mio progetto avvisami che magari il prossimo natale il progetto che pubblico sarà il tuo 🙂
ciao scusatemi
ho fatto tutti i collegamenti illustrati
ho copiato incollato lo sketch e non funziona.. ho scaricato il file tone.. ma non so che cosa farci
potete darmi più istruzioni perfavore?
Autore
Ciao Antonio,
oltre al copia e incolla hai letto le spiegazioni sullo sketch?
Se non sai come installare una libreria su arduino ti consiglio di leggere gli articoli in cui lo spiego o di documentarti su internet, troverai molti articoli che lo spiegano.
Mauro,
Ho copiato il testo dello sketch e subito mi ferma la complilazione : missing wiring.h
Puoi aiutarmi, grazie.
Arduino 2: 1.0.5 +dfsg2-4 (Ubuntu 15.10)
Carlo
Autore
Ciao Carlo,
mi sembra un errore di installazione dell’IDE, la wiring.h è inclusa nell’IDE quando lo installi.
Buona sera e complimenti innanzitutto per il vostro progetto.
Passo alla domanda: sono alle prese anche io con un piccolo progetto natalizio che include l’uso di un motorino dc, un display lcd e 10 led.
Ora, ho scritto per ciascuno di questi elementi hardware lo sketch necessario a far fare ciò che voglio, mi trovo però ora nella situazione di voler far funzionare questi 3 sketch contemporaneamente.
In poche parole voglio che mentre il motore ruoti da una parte all’altra, il display mandi le frasi che ho scritto e che i led si accendano e si spengano, tutto questo contemporaneamente. In pratica vorrei effettuare un multithreading, ma non so se sia possibile e se si come fare.
Grazie
Autore
Ciao Giuseppe,
la buona notizia è che si può fare, la cattiva è che non è un multithread ma una simulazione di tale comportamento.
Tutto dipende da come hai scritto i tuoi sketch, il primo passo è adattarli per farli convivere, quindi ad esempio non puoi gestire i tempi con il comando delay ma con il millis(), leggi l’articolo che ho scritto in merito.
Purtroppo ricevo questo messaggio di errore,chi puoi aiutarmi?
open sketch\sketch_dec23c.ino.cpp: Accesso negato.
Errore durante la compilazione per la scheda Arduino/Genuino Uno.
Grazie mille
Autore
Ciao Amos, che sistema operativo stai utilizzando?
[…] Le suonerie e la spiegazione dello sketch la trovi nel primo articolo. […]