uscita immediata da un loop o un ciclo

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...

@janos
sto sistemando il tuo codice sull'ide e sembra tutto ok, però quando vado a caricare mi da questo errore:

could not convert 'digitalWrite(((uint8_t)ledRosso), 1u)' to 'bool'

su questa riga:

else (!digitalWrite(ledRosso, HIGH)) fineCiclo = false;		//Se non metti questa riga lui ti esegue a diritto

qualche idea?

digitalòWrite ritorna HIGH o LOW (int), non true/false (boolean), janos ha confuso questo particolare.

Sistema l'if di conseguenza.

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...

Allora, vediamo un attimo di fare il punto perché probabilente non ho capito bene cose deve fare... Me lo spieghi nel dettaglio?

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.

Ciao.

Taparia tapioco come fosse antani a destra, che ne dici? :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes:

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

hai ragione, dal "wiring.h"

#define HIGH 0x1
#define LOW  0x0

aaaaaaaaallora... sto costruendo un quizzone... praticamente squadra rossa e squadra blu si contenderanno la vittoria a suon di risposte giuste o sbagliate... ho 2 pulsanti, uno rosso ed uno blu, 2 led uno rosso ed uno blu, e una sirena (semplice altoparlante)...
deve funzionare in questa maniera:

appena viene fatta la domanda dal "conduttore" 2 rispettivi membri delle squadre si alzeranno e andranno al pulsante correndo... il primo che lo preme deve rispondere... in base alla risposta aggiudica il punto alla squadra...

quindi, nel mio programma fino a quì non c'è niente di complesso; ho solo 2 pulsanti con 2 led ed una sirena... se viene premuto il pulsante rosso si accende il led rosso e suona la sirena, idem per il blu, cambia solo il led che si accende (blu al posto del rosso)...

per fare il tutto più carino però, volevo che il mio quizzone, riproducesse una musica in loop mentre il conduttore fa la domanda, fino a quando non viene premuto uno dei 2 pulsanti... ecco perchè alla pressione del pulsante IMMEDIATAMENTE deve smettere la musica, suonare la sirena e accendere il rispettivo led di squadra... se arduino fosse multitasking non ci sarebbero problemi, ma dal momento che non lo è, come cappero posso fare???

vuoi per caso dare anche una scossa elettrica al concorrente che sbaglia la domanda? :grin:
la fine di questo topic sarà tragica :.

matt-korban:
se arduino fosse multitasking non ci sarebbero problemi, ma dal momento che non lo è, come cappero posso fare???

facendo lavorare le meningi :wink:

Qui vedi, nel secondo sketch di esempio, che fanno un controllo su un ingresso analogico e modificano un parametro (il volume).
Basta che tu sostituisca quello alla lettura dei pulsanti digitali.

Come vedi leo ti ha dato il software completo a cui apportare solo qualche modifica, comunque ora che ho un po di tempo, spiego almeno la cosa imprensibile di prima.

Quando vogliamo processare un array siamo abituati ad usare un cicli while o for, ma è possibile anche creare un iteratore, una cosa simile a questo pseudo code:

foreach (note, notes) {
processa note;
grab key
switch (key)
case()
.....
}

Tradotto, cicla per ogni "note" in "notes".

Se processa note è una funzione la possiamo dare in pasto a leOS, o qualcosa di simile magari creato apposta, in questo caso processa note, ritorna subito, perchè quello che fa è registrarsi nello scheduler, che suona note ogni millesimo di secondo, e abbiamo il tanto cercato multitasking.

Più semplicemente, invece per processare una array si può scrivere una funzione simile a questa:

int array[100];

void processData() // lavora con variabili globali
{
    static byte idx = 0;   // questa inizializzazione viene fatta a tempo di compilazione e quindi solo una volta
                                     // idx conserva il valore anche al termine della funzione.

    if (array[idx] == -1)   // se array[idx] contiene il valore sentinella -1 sono arrivato in coda all'array
        idx = 0;   // azzero il contatore statico così' alla prossima chiamata ricomincia tutto
    else {
        Serial.write(array[idx]);
        idx++;
    }
}

Ora se nel loop chiamo la funzione processaData(), processero tutti i dati nell'array uno per volta e ritorno al loop, per fare altro.
Quindi sto processando un array di 100 elementi ma tra un elemento e l'atro controllo la tastiera o altro, se il processamento di un solo
elemento prende un tempo troppo alto bisogna se possibile ridurre questo tempo ad una unità processabile a richiesta.

Ora è più comprensibile, no.

Ciao.

Su segnalazione di Janos, aggiunto l'incremento di idx.

Decisamente, non male come idea... Solo che ti sei dimenticato di incrementare idx... :wink:

Per il natale 2011 avevo fatto delle luci per il presepe con dei led RGB che simulavano alba-giorno-tramonto-notte oppure potevano fare altri tipi di fading e, premendo un pulsantino, si poteva far riprodurre una musichetta natalizia (Jingle Bells) mentre lo sketch continuava a fare il fading dei led. Non usavo scheduler (all'epoca non l'avevo ancora realizzato) ed alla fine era venuta una cosa un po' lunghetta.

Mi ricordo però che avevo adottato un semplice metodo. Avevo messo 2 array, uno con le note da suonare, ed uno con la durata delle stesse. Ogni ciclo, controllavo se la nota era finita e quindi se dovevo suonare la successiva, fino alla fine della melodia. Si trattava insomma di un po' di if e di while annidati.