non centra perchè lui è dentro a una funzione quando ha bisogno di leggere la pressione del bottone che impegna il suo tempo, non ha mica un delay da 10 minuti
loop()
Vai alla funzione 1()
Vai alla funzione 2()
Vai alla funzione 3()
Vai alla funzione 4()
leggi il pulsante
il pulsante lo legge solo quando ha terminato le 4 funzioni, ci vuole qualcosa che intercetti il pulsante interrompendo per un istante tutto quello che il micro sta facendo, questo lo fa solo attivando un interrupt
@Pablos
Prima di dare suggerimenti agli altri ti consiglio di approfondire tu stesso le tue conoscenze in materia, visto che non sai la differenza fra delay() e millis() e che suggerisci improbabili esempi sulla gestione degli interrupt quando ci sono le apposite funzioni... Inoltre qui, anche usando l'interrupt, se sei bloccato in un dealy non ne esci.
P.S. Leggi per bene il mio codice e poi parla... Inoltre consiglio anche a te di leggere http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Per te sono un'inezia 50ms ma nella realtà dell'elettronica 50ms sono un tempo abissale. Pensa che il processore esegue un'istruzione ogni 62ns, quindi con un delay(50) fai stare fermo il processore per ben 806.000 operazioni. Inoltre quello che conta di più è imparare il metodo, quando sai come usarlo poi decidi tu se e quando usarlo...
ehm i delay NON bloccano gli interrupt, altrimentio non usciresti mai dalla delay visto che è basata su un interrupt del timer1
Si janos vado a studiare, intanto tu fagli usare un millis() per 50ms
Per te sono un'inezia 50ms ma nella realtà dell'elettronica 50ms
ma un pulsante premuto (da un essere umano) per meno di 50ms è abbastanza impossibile nella realtà..
Il problema è che quei delay(50) sono in loop e seguiti anche da delay(1000), il che rende il tempo della funzione troppo alto.
Io sono d'accordo con janos di usare la millis() come per l'esempio blinkWithoutDelay;
in particolare , mio caro matt-korban, se non lo fai, finchè l'arduino suona NON legge i pulsanti.
il sistema consigliato da pablos non è errato, ma un'alternativa assai valida: l'uso della millis costringe a riscirvere buona parte del codice, con memorizzazione dello stato tra un loop e l'altro (macchina a stati), e permette di interrompere a metà l'esecuzione di una canzoncina per effettuarne un altra.
l'interrupt permette di sostituire la digitalRead con una variabile booleana settata dall'interrupt e azzerata dopo il suo uso nel loop(l'interrupt conterrà al suo interno un algoritmo anti-bounce, o un anti-bounce HardWare), ma essa non verrà usata finchè il loop corrente è finito, quindi la canzincina deve finire.
lesto:
ehm i delay NON bloccano gli interrupt, altrimentio non usciresti mai dalla delay visto che è basata su un interrupt del timer1
Sono d'accordo con te, ma se lanci un delay(1000) e avviene un interrupt tu vai a eseguire l'interrupt. Il problema è che da interrupt non puoi fare niente perché una volta uscito torni a finire quanto ti resta del delay...
Diciamo che una soluzione intelligente, vista l'applicazione, sarebbe stata di lasciare i delay(50) e sostituire il delay(1000) con millis()...
cioè ma io posso scatenare un casino epocale per un quizzone di m____a?
quindi in parole povere mio caro lesto, quello che dovrei fare è???
usare gli interrupt oppure sostituire i delay con dei millis?
da quello che ho capito non basta sostituire le voci delay con millis, devo pure modificare il programma, giusto?
ma poi ragazzi il delay 1000 non mi da nessun fastidio in quanto tiene il led acceso per un secondo dopo la sirena, e questo mi sta bene... quello che blocca il programma è l'esecuzione della canzoncina prima che venga premuto il pulsante... una volta premuto il pulsante infatti, la canzoncina si ferma e parte una "sirena" che dura qualcosa come un secondo, e si accende un led...
un lucano! hahahaha ma si, ho caricato il tuo codice, ma non esce comunque dalla canzoncina quando premo il pulsante... magari riprovo un altro po e provo a smanettarci su, vediamo che succede...
No, l'errore non è li. La condizione dell'if può essere applicata anche ai numeri (in questo caso un int) e viene considerato falso lo zero e vero un qualsiasi numero diverso da zero. Il problema è che mi sono confuso, prova a sostiruire la riga con questo:
else (!statoRosso) fineCiclo = false; //Se non metti questa riga lui ti esegue a diritto
hahahaha sembra la storia infinita... mi da un altro errore...
expected ';' before 'fineCiclo'
comunque ho provato a risolvere cambiando l'else con else if, oppure modificando la punteggiatura e carica bene... il problema però rimane sempre... mentre suona non legge il pulsante... devo tenerlo premuto per farglielo leggere alla fine della musichetta...
Non vorrei risultare noiso o di difficile comprensione.
int melody[] = {
NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
Se ci fosse un nota END_NOTE, si potrebbe usare un while, anzi meglio una funzione con indice static.
Invece dell'array si può usare una array di struct, dove struct note contiene i campi, "note", "durata" e "pausa"
Ora una funzione processa solo una nota ed esce, grazie ad una variabile indice static, posso chiamare un numero di volte infinito questa funzione, e ad ogni chiamata l'indice viene incrementato, quando leggendo struct note trovo che "note" è uguale a 255 (cioè END_NOTE), azzero il contatore static index e alla prossima chiamata si ricomincia da dove si era interrotto.
La funzione viene processata nel loop e ritorna dopo aver suonato una nota la durata e la pausa, ma se dentro la funzione controllo una variabile di stato ricavata con la gestione dei PIN_CHANGED, posso bloccare il codice. Se il tempo per processare una nota la durata e la pausa non è molto alto
posso gestire il pulsante in pooling.
Mi rendo conto, sono poco comprensibile, ma è una buona soluzione.
Janos:
No, l'errore non è li. La condizione dell'if può essere applicata anche ai numeri (in questo caso un int) e viene considerato falso lo zero e vero un qualsiasi numero diverso da zero. Il problema è che mi sono confuso, prova a sostiruire la riga con questo:
else (!statoRosso) fineCiclo = false; //Se non metti questa riga lui ti esegue a diritto