Le mie avventure con Arduino


Mi chiamo Gilberto e abito a Forlì sono perito elettrotecnico poi riconvertito all’informatica con conoscenze di elettronica di base, ho scoperto per caso Arduino e mi ha appassionato subito in quanto consente di realizzare progetti anche complessi in modo semplice.

Ho acquistato un Arduino mega2560, un Luigino328 e un Arduino Nano a luglio 2012 e ho cominciato ad utilizzarli inizialmente realizzando gli esempi più semplici per prendere dimestichezza con l’hardware e il software.

Per prendere dimestichezza con Arduino ho realizzato qualche cubo di led modificando esempi trovati sul web, e creando un vero cubo metallico con 9 led per le 5 facce del cubo, quindi un cubo 9×5 pilotato da transistor, una matrice 9×5 con un comando riga colonna, in totale ho utlizzato 14 pin dell’Arduino mega2560 per pilotare 45 led.

Quando ho scoperto Arduino il mio intento era quello di realizzare un comando per le luci dell’albero di Natale: era troppo semplice acquistare i fili già fatti che cambiavano da soli la sequenza di luci e volevo fare riprodurre ad Arduino musiche natalizie diverse premendo i tasti di un telecomando.

Quindi ho recuperato i fili luminosi utilizzati lo scorso anno ho studiato come erano realizzati i collegamenti e per questo ho smontato una centralina che pilotava le luci per vedere come erano collegati e ho scoperto che anche se le luci erano a tre fili sono collegate con un filo in comune e quindi si riescono ad accendere le luci ma sempre a coppie di due, queste luci sono alimentate da 21-24V.

Arduino come noto gestisce in ingresso e uscita tensioni di 5V dc quindi il primo scoglio da superare era come interfacciare arduino con circuiti che lavorano con tensioni superiori.

Sul sito ufficiale di arduino a questo link: http://arduino.cc/forum/index.php?PHPSESSID=1e4a4883d1494c29861a458c565d7b79&topic=36133.msg265830#msg265830

Ho trovato questo semplice schema:

quindi mi sono procurato la basetta mille fori e i componenti necessari per realizzare l’interfaccia per pilotare le mie luci natalizie.

Ho realizzato due schede con quattro relè a uno scambio che in uscita potevano pilotare una tensione fino a 240V, quattro relè perché avevo a disposizione due fili di luci natalizie due relè per ogni coppia di luci da pilotare e avevo intenzione di acquistarne altre due fili di luci natalizie.

Prima ho testato il circuito su breadboard tutto ok e poi montato su mille fori dopo il montaggio del primo relè ho testato il circuito e il relè non si agganciava dopo diversi tentativi ho scoperto che il valore delle resistenza R1 era troppo elevata e inserendo una resistenza da 220 il relè funzionava probabilmente le saldature hanno aumentato la resistenza globale del circuito e la corrente fornita da arduino non era sufficiente per pilotarlo.

Ho realizzato una scheda da montare su arduino con a bordo morsetti tasto reset e un led per vedere se arduino caricava il codice del programma per interfacciare arduino con le due interfacce a relè in modo sicuro.

Ora ho realizzato il montaggio finale con Arduino Luigino328 e le due schede a relè in tre contenitori di riciclo che originariamente contenevano mirtilli secchi che ho utilizzato per fare la grappa ai mirtilli.

Ho insonorizzato i contenitori dove ho messo i relè con paglia sintetica non avevo considerato che otto relè a bobina che lavorano di continuo sono un po’ rumorosi a pensarci prima potevo utilizzare relè statici o triac ma ormai avevo realizzato le due interfacce con relè tradizionali.

Nel montaggio finale utilizzo un solo alimentatore da 24 v di quelli smontati dalle luci natalizie ho scelto quello con potenza maggiore e cosi sono riuscito a pilotare tutti i 4 fili di luci natalizie con in solo alimentatore invece di 4 e un alimentatore 12v dc per Arduino.

Ho scritto questo codice e caricato su Luigino328

int i=0;
int i1=50;

int cas1=0;
int cas2=0;
int cas3=0;
int cas4=0;
int cas5=0;
int cas6=0;
int cas7=0;
int cas8=0;

int t=0;
int t1=100;
int t2=500;

int t3=1000;

void setup()
{
	// pin di pilotaggio rele’
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
}

void loop()
{
	// accensione di tutte le luci
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);

cas4=random(10,t3);	// genera dei numeri casuali da 10 a t3-1
// utilizzati come variabile ritardo
delay(cas4);

	// tutte le luci spente
digitalWrite(1, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);

cas4=random(10,t3);	//genera dei numeri casuali da 10 a t3-1
cas3=random(1,i1);	//genera dei numeri casuali da 1 a i1-1
for (i=0; i <= cas3; i=i+1)
{
cas2=random(1,3);	//genera dei numeri casuali da 1 A 2 1=SPENTO 2=ACCESO
if (cas2=2)
{
		// accensione luci
cas1=random(1,9);	//genera dei numeri casuali da 1 a 8
digitalWrite(cas1, HIGH);
t=random(t1,t2);	// t= RITARDO CASUALE DA t1 a t2-1
delay(t);
cas2=random(1,9);	//genera dei numeri casuali da 1 a 8
digitalWrite(cas2, HIGH);
t=random(t1,t2);	// t= RITARDO CASUALE DA t1 a t2-1
delay(t);
cas3=random(1,9);	//genera dei numeri casuali da 1 a 8
digitalWrite(cas3, HIGH);
t=random(t1,t2);	// t= RITARDO CASUALE DA t1 a t2-1
delay(t);
cas4=random(1,9);	//genera dei numeri casuali da 1 a 8
digitalWrite(cas4, HIGH);
t=random(t1,t2);	// t= RITARDO CASUALE DA t1 a t2-1
delay(t);
}
if (cas2=1)
{

digitalWrite(cas1, LOW);
digitalWrite(cas2, LOW);
digitalWrite(cas3, LOW);
digitalWrite(cas4, LOW);
t=random(t1,t2);	// t= RITARDO CASUALE DA t1 a t2-1
delay(t);
}

}
}

 

 

Questo codice accende e spegne le luci in modo del tutto casuale generando effetti luminosi gradevoli e sempre diversi.

Dopo aver realizzato la parte di accensione luci quasi senza problemi a parte cambiare il valore di R1 in corso d’opera, ho affrontato il problema audio non volevo acquistare un scheda midi per Arduino, dopo varie ricerche ho scoperto la libreria tone.h e il file di esempio rtttl gia’ scritto e fornito con Arduino e i problemi sono stati molteplici e quasi mi ero scoraggiato dal realizzare la parte audio per il mio albero di natale.

La libreria tone.h che ho scaricato non è compatibile con le versioni dell’IDE superiore alla 023 e di questo problema non ho trovato spiegazioni solo su un forum che parlava dei problemi di compatibilità delle librerie in generale ma non nello specifico di quella che serviva a me.

Nel forum si consigliava di utilizzare non le ultime versioni dell’ide arduino, dopo diversi tentativi ho scoperto che la libreria tone.h funziona con il l’IDE Arduino fino alla versione 023.

Ho utilizzato e modificato l’esempio rtttl fornito con arduino questo file utilizza la libreria tone.h e consente di fare riprodurre le vecchie suonerie dei cellulari in formato rtttl ad Arduino collegato a uno speaker o buzzer.

Ho scaricato numerose suonerie natalizie in formato rttl e modificate per renderle compatibili con arduino.

Volevo collegare un telecomando ad Arduino per selezionare la musica da riprodurre ho acquistato un ricevitore a infrarossi e l’ho collegato seguendo questo schema che ho trovato sul web.

Poi ho utilizzato la libreria iremote.h direi molto semplice e sarebbe andata benissimo per il mio scopo ma ho scoperto che la libreria iremote.h e tone.h sono incompatibili fra di loro con tutte le versioni dell’IDE Arduino.

Quindi ho decodificato manualmente i tasti del telecomando ho modificato un semplice programma per la decodifica ir scaricato dal web in questo modo:

 

void setup()
{
pinMode(pinData, INPUT);
Serial.begin(9600);
}

void loop()
{
//look for a header pulse from the IR Receiver
lengthHeader = pulseIn(pinData, LOW);
if(lengthHeader > 1024)
{
//step through each of the 32 bits that streams from the remote
byteValue = 0;
for(int i = 1; i <= 32; i++)
{
bit = pulseIn(pinData, HIGH);

//read the 8 bits that are specifically the key code
//use bitwise operations to convert binary to decimal
if (i > 16 && i <= 24)
if(bit > 1024)
byteValue = byteValue + (1 << (i - 17));
}

//send the key code to the processing.org program
Serial.println(byteValue*1048576);	// valore letto premendo i tasti del
// telocomando
Serial.flush();
}

delay(100);
}

 

Ho utilizzato un telecomando Nortech di un dvd video recorder e dopo prove sono riuscito a trovare la costante da utilizzare per decodificare il mio telecomando il valore letto da Arduino in digitale risultava molto piccolo e Arduino faceva confusione e confondeva i tasti ho moltiplicato il valore letto da Arduino in digitale per 1048576 (due alla ventesima) per differenziare i valori letti e mappare i tasti del telecomando.

Sicuramente questo codice si adatta a tutti i telecomandi ma bisogna trovare la costante di decodifica specifica per il telecomando.

Ho iniziato a scrivere il codice che premendo i tasti del telecomando riproduceva una canzone natalizia inizialmente ho inserito solo pochi tasti del telecomando nel programma e provato se tutto funzionava regolarmente. Premetto che per le prove ho utilizzato Arduino nano e uno speaker tutto funzionava regolarmente.

Poi ho completato il codice prevedendo la decodifica ti tutti i 52 tasti del telecomando senza testarlo su Arduino, ho caricato il codice completo su Arduino nano e dopo il caricamento il mio Arduino ha dato gravi segni di squilibrio il led interno sul pin 13 lampeggiava in continuazione e non dava altri segni di vita se cercavo di scaricare sull’Arduino un altro codice sul pc mi compariva un errore.

Non contento ho scaricato lo stesso programma sul Luigino328 e ho ottenuto lo stesso risultato ho bloccato anche questo Arduino.

Un gran risultato due Arduino bloccati senza sapere per quale motivo.

Poi ho caricato lo stesso codice sull’Arduino mega2560 le cose sono andate solo un po’ meglio nel senso che questo Arduino non si è bloccato ma non eseguiva il programma, ho ridotto sperimentalmente il numero di tasti nel programma fino ad trovare il massimo di tasti che potevo utilizzare sul mio Arduino senza bloccarlo sono arrivato a 32 tasti utlizzabili.

Pensavo che Il problema fosse nel numero di if (un if per ogni pulsante) nidificati all’interno di altro if anche se di questo non ho trovato specifiche ma riducendo il numero di tasti arduino mega funzionava.

Il programma originale rtttl prevedeva una sola uscita audio ma volevo dare al mio Aduino una parvenza di effetto stereo e quindi utilizzato una seconda uscita per l’audio.

Ho costruito due casse una per il canale destro e una per il canale sinistro utilizzando 4 speaker smontati da pc portatili non funzionanti due speaker in parallelo per canale.

Ho inserito i due speaker per canale in due contenitori di plastica che inizialmente contenevano crema al gorgonzola utilizzata per fare gli gnocchi al gorgonzola, ho cosi realizzato due casse acustiche che riproduco un effetto quasi stereo anche se le vecchie suonerie rtttl non hanno nulla di stereo ma l’effetto audio finale non e’ male.

Ora mi rimaneva da risolvere il problema dei due arduino bloccati che non davano piu segni di vita.

Potevo rimandarli indietro in garanzia ma temevo di non fare in tempo per natale, ho cercato sul web ho trovato molteplici probabili soluzioni al problema ma nessuna mi sembrava attendibile molti siti parlavano di ricaricare il bootloader di arduino utilizzando un programmatore avr o un arduino funzionante ma non mi convinceva sacrificare l’unico arduino rimasto funzionante e poi cercando bene ho trovato questa soluzione sul sito ufficiale di arduino nella sezione playground tra i problemi noti e risolti la soluzione: http://playground.arduino.cc/Italiano/Pobleminoti

Il tastino di reset non è come il reset del computer, che fa riavviare la macchina e cancella il programma in memoria. La memoria su cui è memorizzato lo sketch non è RAM, che si cancella senza alimentazione, è di tipo Flash e mantiene quindi il programma fino a successiva riprogrammazione.

La Manovra d’emergenza di solito serve quando il micro è bloccato sulla seriale ma non sembra bloccato sulla seriale, sembra invece “sordo”, nel senso che non comunica più col computer, ed è la seguente:

  1. aprire l’IDE
  2. caricare uno sketch qualunque, anche il “blink” modificato (prova a mettere un delay doppio)
  3. prendere l’Arduino e tenere premuto il pulsante “reset”.
  4. MENTRE si tiene questo tasto pigiato, collegare l’Arduino al PC.
  5. adesso, MENTRE si continua a tenere pigiato il pulsantino, premere il tasto di upload dello sketch
  6. ora rilasciare il pulsantino di reset
  7. se si è trovato la sincronizzazione giusta tra la pressione del pulsante grafico di upload dello sketch ed il rilascio del reset, verrà caricato lo sketch

Seguendo queste semplici istruzioni ho risolto il problema e i il mio luigino328 e il mio Arduino Nano sono rinati anche se non e’ semplice trovare la sincronizzazione fra pc e Arduino dopo qualche tentativo ci sono riuscito.

Non contento ho caricato il codice funzionante su Arduino mega 2560 sul luigino328 e sorpresa questo Arduino si è bloccato di nuovo il programma per questo Arduino era troppo complesso e quindi di nuovo utilizzato la procedura di sblocco.

Per evitare di bloccare Arduino con un codice troppo complesso ho deciso di usare il Luigino328 per pilotare le luci dell’albero in quanto il codice e’ molto semplice e Arduino mega2560 per riprodurre i suoni, inizialmente volevo utilizzare un solo Arduino ma visti i problemi ho deciso di dividere il carico di lavoro fra due Arduino.

Il risultato ottenuto e gradevole per la vista e per l’udito e ho chiamato il mio albero “albero ai mirtilli e gorgonzola” visto che ho utilizzato contenitori di riciclo per mirtilli per contenere il luigino328 e le due interfacce a relè insonorizzati con paglia sintetica e due contenitori  per crema al gorgonzola per le casse acustiche e un contenitore per gorgonzola per contenere Arduino mega2560 e il ricevitore ir montato su mini breadboard.

Allego il codice che gestisce i suoni dell’albero di natale con telecomando. Quello per la gestione delle luci è riportato sopra.

 

#include <Tone.h>

Tone tone1,tone2;

long test;

#define OCTAVE_OFFSET 0

int pinData= 2; // pin sensore ir

unsigned long lengthHeader;
unsigned long bit;
int byteValue;

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
};

void setup(void)
{
  Serial.begin(9600);
// pin audio gestiti dalla libreria tone.h 2 per ottenere un effetto quasi
// stereo
  tone1.begin(7);
  tone2.begin(6);

  pinMode(pinData, INPUT);
}
void loop()
{
  ir(); /funzione che attiva il ricevitore ir
//  Serial.println(byteValue);
if ( byteValue <= -100)
{
  ir();
}
  else
  {
  // decodifica telecomando alla pressione dei tasti indicati viene
  // riprodotta una melodia
if ( test == 16777216)
    { // ch+
       Serial.println(test);
       char *song = "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";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 17825792)
    { // ch-
       Serial.println(test);
       char *song="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.";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 17825792)
    { // vol+
       Serial.println(test);
       char  *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 18874368)
    { // vol-
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 14680064)
    { // enter
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==23068672)
    { // setup
       Serial.println(test);
       char *song="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.";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 9437184)
    { // edit
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 27262976)
    { // 1
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 72351744)
    { // 2
       Serial.println(test);
       char *song="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#";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 79691776)
    { // 3
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 71303168)
    { // 4
       Serial.println(test);
       char *song="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.";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 67108864)
    { // 5
       Serial.println(test);
       char *song="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,";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 68157440)
    { // 6
       Serial.println(test);
       char *song="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,";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 69206016)
    { // 7
       Serial.println(test);
       char *song="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,";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 70254592)
    { // 8
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test == 25165824)
    { // 9
       Serial.println(test);
       char *song="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.";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==24117248)
    { // 0
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
 if ( test ==87031808)
    { // 10+
       Serial.println(test);
       char *song="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#";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==26214400)
    { // clear
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
 if ( test ==84934656)
    { // slow
       Serial.println(test);
       char *song="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.,";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==30408704)
    { // step
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==77594624)
    { // sub-t
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==78643200)
    { // goto
       Serial.println(test);
       char *song="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.";
       play_rtttl(song);
       test=-11111;
     }
/*
if ( test ==75497472)
    { // audio
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==85983232)
    { // pal/nstc
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==97517568)
    { // angle
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==82837504)
    { // return
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
*/
if ( test ==80740352)
    { // prog
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==81788928)
    { // repeat
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==98566144)
    { // zoom
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }
if ( test ==99614720)
    { // osd
       Serial.println(test);
       char *song="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";
       play_rtttl(song);
       test=-11111;
     }        

   }  

}

#define isdigit(n) (n >= '0' && n <= '9')

void play_rtttl(char *p)
{
  // Absolutely no error checking in here

  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 for next note (or we may be at the end)

    // 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]);
      tone2.play(notes[(scale - 4) * 12 + note]);
      delay(duration);
      tone1.stop();
      tone2.stop();
    }
    else
    {
     // Serial.print("Pausing: ");
     // Serial.println(duration, 10);
      delay(duration);
    }
  }
}

void ir()
{
//look for a header pulse from the IR Receiver
lengthHeader = pulseIn(pinData, LOW);
if(lengthHeader > 1024)
{
//step through each of the 32 bits that streams from the remote
byteValue = 0;
for(int i = 1; i <= 32; i++)
{
bit = pulseIn(pinData, HIGH);

//read the 8 bits that are specifically the key code
//use bitwise operations to convert binary to decimal
if (i > 16 && i <= 24)
if(bit > 1024)
byteValue = byteValue + (1 << (i - 17));
}

//send the key code to the processing.org program
Serial.println(byteValue*1048576);
  test=byteValue*1048576; 

Serial.flush();
}

delay(100);
}

 

Pensavo di avere risolto e avere capito come sono riuscito a bloccare 2 Arduino come esposto sopra attribuivo la colpa all’elevato numero di if nidificati dentro un altro if ma mi devo ricredere.

Oggi ho testato il codice riportato sopra che ancora non avevo testato per gestire i suoni dell’albero di natale che funzionava correttamente utilizzando 32 tasti del telecomando, ho semplicemente sostituito i brani che avevo caricato in precedenza con suonerie più’ lunghe e più complete per rendere più gradevole il mio albero di natale, ho utilizzato i soliti 32 tasti che ho decodificato ma appena ho caricato il codice su Arduino mega2560 il mio Arduino è andato in blocco e non eseguiva il codice.

A differenza del Luigino328 e dell’Arduino nano che vanno in blocco facendo lampeggiare in continuazione il led sul pin 13 Arduino e bisogna ripristinare seguendo le istruzioni sopra, Arduino mega2560 va in blocco e non esegue il codice ma basta ricaricare un codice più semplice e Arduino riprende a funzionare senza dovere eseguire la procedura per sbloccarlo.

Ho risolto il problema riducendo ancora il numero di tasti utilizzati da 32 a 28 e quindi il numero degli if nidificati ma ritengo che il problema non sia l’elevato numero di if nidificati ma che il problema sia nella libreria tone.h e un elevato numero di istruzioni char *song =”……….” Con stringhe molto lunghe per qualche motivo bloccano Arduino avevo testato tutti i brani singolarmente e non mi hanno creato problemi ma l’elevato numero di istruzioni char *song =”……….” bloccano Arduino ma non capisco il motivo e non ho trovato specifiche su questo.

Ora ho risolto il problema rinunciando ad altre 4 canzoni da riprodurre.

Se anche tu hai realizzato un progetto simpatico e interessante e vuoi pubblicarlo sul nostro blog, contattaci all’indirizzo:
redazione@elettronicain.it

2 pensieri riguardo “Le mie avventure con Arduino

  • 07/01/2013 in 01:29
    Permalink

    Ciao, hai provato ad utilizzare la direttiva PROGMEM per l’allocazione delle stringhe contenenti i brani musicali ?

    Quando ci sono delle stringhe costanti e’ piu’ corretto dire al software di allocarle direttamente nella flash usata da programma, piuttosto che farle allocare in ram.

    Fai una prova….spero sia giusto il suggerimento.
    Saluti.

    Risposta

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Ricevi un avviso se ci sono nuovi commenti. Oppure iscriviti senza commentare.