Nel mondo di Arduino vi è data la possibilità di realizzare una miriade di progetti. In questo articolo vi sarà un tutorial su come comporre la colonna sonora dei “Pirati dei Caraibi” tramite l’ausilio di un buzzer passivo e inoltre sarà anche utilizzato un display LCD, sul quale saranno riportate le note riprodotte durante la composizione. Per capire e scoprire le potenzialità di un cicalino passivo e di un display LCD sono presenti rispettivamente tutorial che illustrano ciò (clicca qui per il tutorial per il display e clicca qui per il tutorial sul buzzer passivo).
Per la riuscita di questo progetto occorre utilizzare :
- 1x board di Arduino o schede compatibili
- 1x buzzer passivo
- 1x Un display LCD (In questo caso il display LCD1602)
- 1x Potenziometro (10k)
- Breadboard (in questo caso è stata utilizzata la breadboard con 830 fori)
- 19x connettori M-M (connettori Maschio-Maschio)
Nella immagine sottostante è riportata il diagramma di collegamento:
In seguito è riportato lo sketch per l’utilizzo del display LCD su Arduino:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
//in tale stringa vi è selezionato il pin // in cui il cicalino è collegato dal filo rosso const int buzzer = 2; //con tale stringa possiamo regolare la //velocità con cui viene riprodotto l'audio const float velocitasuono = 1.5; //la libreria per utilizzare a pieno //le potenzialità del display #include <LiquidCrystal.h> //in tale stringa vi sono //selezionati i pin in cui il display LCD è collegato LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // sono state definite le varia note, il valore //posto è la frequenza per cui si ottengono tali note. #define NOTE_DO4 262 #define NOTE_RE4 294 #define NOTE_MI4 330 #define NOTE_FA4 349 #define NOTE_SOL4 392 #define NOTE_LA4 440 #define NOTE_SI4 494 #define NOTE_DO5 523 #define NOTE_RE5 587 #define NOTE_MI5 659 #define NOTE_FA5 698 #define NOTE_SOL5 784 #define NOTE_LA5 880 #define NOTE_SI5 988 //tramite l'ausilio del vettore noteusate, vi sarà //data la possibilità di far comparire sul display //le note riprodotte, nelle seguenti righe di codice //sarà più chiaro questo passaggio int noteusate[] = { 3, 5, 6, 6, 0, 6, 7, 1, 1, 0, 1, 2, 7, 7, 0, 6, 5, 6, 0, 3, 5, 6, 6, 0, 6, 7, 1, 1, 0, 1, 2, 7, 7, 0, 6, 5, 6, 0, 3, 5, 6, 6, 0, 6, 1, 2, 2, 0, 2, 3, 4, 4, 0, 3, 2, 3, 6, 0, 6, 7, 1, 1, 0, 2, 3, 6, 0, 6, 1, 7, 7, 0, 1, 6, 7, 0, 6, 6, 6, 7, 1, 1, 0, 1, 2, 7, 7, 0, 6, 5, 6, 0, 3, 5, 6, 6, 0, 6, 7, 1, 1, 0, 1, 2, 7, 7, 0, 6, 5, 6, 0, 3, 5, 6, 6, 0, 6, 1, 2, 2, 0, 2, 3, 4, 4, 0, 3, 2, 3, 6, 0, 6, 7, 1, 1, 0, 2, 3, 6, 0, 6, 1, 7, 7, 0, 1, 6, 7, 0, 3, 0, 0, 4, 0, 0, 3, 3, 0, 5, 0, 3, 2, 0, 0, 2, 0, 0, 1, 0, 0, 7, 1, 0, 7, 0, 6, 3, 0, 0, 4, 0, 0, 3, 3, 0, 5, 0, 3, 2, 0, 0, 2, 0, 0, 1, 0, 0, 7, 1, 0, 7, 0, 6 }; //nel vettore note vi è lo spartito della colonna sonora dei pirati dei caraibi, //lo 0 (0 Hz) indica che in quel preciso momento non deve essere prodotto nessun suono. int note[] = { NOTE_MI4, NOTE_SOL4, NOTE_LA4, NOTE_LA4, 0, NOTE_LA4, NOTE_SI4, NOTE_DO5, NOTE_DO5, 0, NOTE_DO5, NOTE_RE5, NOTE_SI4, NOTE_SI4, 0, NOTE_LA4, NOTE_SOL4, NOTE_LA4, 0, NOTE_MI4, NOTE_SOL4, NOTE_LA4, NOTE_LA4, 0, NOTE_LA4, NOTE_SI4, NOTE_DO5, NOTE_DO5, 0, NOTE_DO5, NOTE_RE5, NOTE_SI4, NOTE_SI4, 0, NOTE_LA4, NOTE_SOL4, NOTE_LA4, 0, NOTE_MI4, NOTE_SOL4, NOTE_LA4, NOTE_LA4, 0, NOTE_LA4, NOTE_DO5, NOTE_RE5, NOTE_RE5, 0, NOTE_RE5, NOTE_MI5, NOTE_FA5, NOTE_FA5, 0, NOTE_MI5, NOTE_RE5, NOTE_MI5, NOTE_LA4, 0, NOTE_LA4, NOTE_SI4, NOTE_DO5, NOTE_DO5, 0, NOTE_RE5, NOTE_MI5, NOTE_LA4, 0, NOTE_LA4, NOTE_DO5, NOTE_SI4, NOTE_SI4, 0, NOTE_DO5, NOTE_LA4, NOTE_SI4, 0, NOTE_LA4, NOTE_LA4, NOTE_LA4, NOTE_SI4, NOTE_DO5, NOTE_DO5, 0, NOTE_DO5, NOTE_RE5, NOTE_SI4, NOTE_SI4, 0, NOTE_LA4, NOTE_SOL4, NOTE_LA4, 0, NOTE_MI4, NOTE_SOL4, NOTE_LA4, NOTE_LA4, 0, NOTE_LA4, NOTE_SI4, NOTE_DO5, NOTE_DO5, 0, NOTE_DO5, NOTE_RE5, NOTE_SI4, NOTE_SI4, 0, NOTE_LA4, NOTE_SOL4, NOTE_LA4, 0, NOTE_MI4, NOTE_SOL4, NOTE_LA4, NOTE_LA4, 0, NOTE_LA4, NOTE_DO5, NOTE_RE5, NOTE_RE5, 0, NOTE_RE5, NOTE_MI5, NOTE_FA5, NOTE_FA5, 0, NOTE_MI5, NOTE_RE5, NOTE_MI5, NOTE_LA4, 0, NOTE_LA4, NOTE_SI4, NOTE_DO5, NOTE_DO5, 0, NOTE_RE5, NOTE_MI5, NOTE_LA4, 0, NOTE_LA4, NOTE_DO5, NOTE_SI4, NOTE_SI4, 0, NOTE_DO5, NOTE_LA4, NOTE_SI4, 0, NOTE_MI5, 0, 0, NOTE_FA5, 0, 0, NOTE_MI5, NOTE_MI5, 0, NOTE_SOL5, 0, NOTE_MI5, NOTE_RE5, 0, 0, NOTE_RE5, 0, 0, NOTE_DO5, 0, 0, NOTE_SI4, NOTE_DO5, 0, NOTE_SI4, 0, NOTE_LA4, NOTE_MI5, 0, 0, NOTE_FA5, 0, 0, NOTE_MI5, NOTE_MI5, 0, NOTE_SOL5, 0, NOTE_MI5, NOTE_RE5, 0, 0, NOTE_RE5, 0, 0, NOTE_DO5, 0, 0, NOTE_SI4, NOTE_DO5, 0, NOTE_SI4, 0, NOTE_LA4 }; //in tale vettore vi è l'intervallo di tempo per //cui ciascuna nota del vettore note[i] sarà prodotta. int durata[] = { 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 375, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 375, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 125, 250, 125, 125, 125, 250, 125, 125, 250, 125, 250, 125, 125, 125, 250, 125, 125, 125, 125, 375, 375, 250, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 375, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 375, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 125, 250, 125, 125, 125, 250, 125, 125, 250, 125, 250, 125, 125, 125, 250, 125, 125, 125, 125, 375, 375, 250, 125, 375, 250, 125, 375, 125, 125, 125, 125, 125, 125, 125, 125, 375, 250, 125, 375, 250, 125, 375, 125, 125, 125, 125, 125, 500, 250, 125, 375, 250, 125, 375, 125, 125, 125, 125, 125, 125, 125, 125, 375, 250, 125, 375, 250, 125, 375, 125, 125, 125, 125, 125, 500 }; void setup() { //con lcd.begin si inizializzano le //righe e colonne di cui è composto il display lcd.begin(16,2); //con lcd.print si fa comparire il messaggio sulla //prima riga del display "Nota Usata : " lcd.print("Nota Usata : "); } void loop() { int i; String n; for (int i=0;i<203;i++){ //con il comando switch si attua una conversione dei valori interi (da 0 a 7) //posti all'interno del vettore, in stringhe (Che corrisponderanno alle note / /utilizzate) switch (noteusate[i]){ case 0: n = " "; break; case 1: n = "DO "; break; case 2: n = "RE "; break; case 3: n = "MI "; break; case 4: n = "FA "; break; case 5: n = "SOL"; break; case 6: n = "LA "; break; case 7: n = "SI "; break; } int attesa = durata[i] * velocitasuono; //tone è la funzione che permette di generare il suono //tramite il cicalino, vi sono tre parametri formali, //il primo parametro costituisce il pin in cui è collegato il cicalino, //il secondo parametro è costituito dal vettore note (lo spartito) //e dalle relative frequenze //il terzo parametro è costituito dal periodo durante //il quale verrà prodotto ciascun suono. tone(buzzer,note[i],attesa); //l'intervallo di tempo in cui vengono prodotte due //note (la nota posta a indice i, e poi la nota posta a indice i+1) delay(attesa); //tale funzione imposta la posizione del cursore, perciò dove il prossimo testo apparirà (nel // nostro caso colonna 0 e riga 1). Colonne e righe iniziano la numerazione da 0 e non // da 1. in questo caso è stata è stata selezionata la seconda riga lcd.setCursor(0, 1); //fa comparire sulla seconda riga dello schermo la nota riprodotta //in quel preciso istante di tempo t lcd.print(n); } // delay(2000) costituisce l'intervallo di tempo per cui //una volta terminato il brano lo ricomincerà da capo delay (2000); } |
Una piccola nota riguardo il programma: per far comparire le note riprodotte in quel preciso istante di tempo bastava creare un vettore di tipo “string” e inserire all’interno di questo vettore il nome delle note utilizzate. Il ragionamento è giustissimo ma vi sono degli inghippi a livello “pratico”. La memoria massima che può essere utilizzata per la creazione di un programma in Arduino è 2048 byte. Chi programma in C/C++ o qualsiasi altro tipo di linguaggio non ha problemi di questo tipo, poiché almeno in C++ la memoria massima utilizzabile (quella stack) è di 4 MB, nel caso si utilizzassero variabili, vettori e matrici “statiche” e non dinamiche. Ma coloro i quali programmano con Arduino.ide devono possedere l’accortezza di creare programmi “snelli” e poco “pesanti” a livello di memoria. Le stringhe “consumano” molta memoria, e per ovviare a questo ostacolo si può utilizzare il comando di “Swicth case statement”.
Link utili: