Buonasera a tutti.
Tra impegni famigliari e rogne sul lavoro è sempre difficile entrare qua, ma quando riesco (anche alle 3 di notte) è sempre un piacere.
Postando nel precedente messaggio il mio codice in effetti è mancato qualcosa...nel ripulirlo dai commenti e dalle parti di codice di debug ho ranzato un po troppo. Riallego quindi il codice completo di tutti i commenti e del led verde aggiunto solo come debug.
Infinitamente semplice nella sua essenzialità...ma non funziona!
int pin = 13; // Led rosso
int verde =12; // Led verde...test point per il ciclo di while
int int0 = 2; // pin di interrupt esterno
volatile bool change=false; // abilita cambio di stato del led rosso
int state = LOW; //Variabile di stato del led rosso
void setup()
{
pinMode(pin, OUTPUT);
pinMode(verde, OUTPUT);
pinMode(int0, INPUT);
attachInterrupt(0, blink, FALLING);
digitalWrite(verde,LOW);
}
void loop()
{
if(change)
{
noInterrupts(); // disabilito interrupts per non farmi buttar fuori dall'if se ci fosse un rimbalzo del pulsante.
change=false; // riarmo change per non farmi rientrare nel if fino alla prossima pressione del pulsante
state=!state; // not della variabile di stato del led rosso
digitalWrite(pin, state); // che poi vado a scrivere sull'uscita del led rosso
while(digitalRead(int0)==LOW) // mentre ho ancora gli interrupt disabilitati giro in questa while finche il pulsante è premuto
{
digitalWrite(verde,HIGH); // accendo un led verde per conferma che non esco dal while
delay(200); // delay di 200ms tanto per fare qualcosa
}
digitalWrite(verde,LOW); // se sono qui è perchè il pulsante è stato rilasciato...
// mentre l'interrupt è ancora disabilitato
delay(200); // al rilascio del pulsante aspetto ulteriori 200ms di debuncing prima di riabilitare gli interrupt
interrupts(); // se sono qui è perchè il pulsante è stato rilasciato e sono terminati tutti i rimbalzi...quindi posso riarmare l'interrupt
// e attendere, senza far nulla, la nuova pressione del pulsante.
}
}
void blink()
{
change=true; // triggerato interrupt sul pin int0. Al prossimo ciclo della loop()il program counter mi entra nel condizionale if(change)
}
Claudio_FF:
L'errore è nel dare per scontato di restare nel while che attende il rilascio.
Claudio ti ringrazio per l'interessamento ma purtroppo non è nemmo come dici tu...se rileggi il codice colpleto che ho postato qui sopra vedi che nel ciclo di while ci ho messo un led verde che rimane acceso fintanto che sono nel while, ed in effetti cosi è. Quindi ho la prova che nella while ci rimango finche c'è il pulsante premuto, quando lo rilascio il led verde si spegne e solo dopo che il led verde si è spento e sono trascorsi ulteriori 200ms vado a riarmare l'iterrupt. Ma spesso, oltre a spegnersi il led verde, mi cambia ancora di stato il led rosso.
Silente:
Tanto per incominciare ti chiedo se non sarebbe più utile e comodo effettuare il debounce hardware e non software de pulsante (chiedi e guarda in giro per maggiori info in merito). Credo che, infatti, il debounce software NON sia strada percorribile.
Perdonami silente ma temo di non essere daccordo, con un pic e piu o meno le stesse righe di codice tutto funziona alla grande.
Ma a parte questo so bene che un debuncing hardware con una RC, o meglio ancora un flip flop con due nand, sarebbe la soluzione ideale...ma confidando un giorno di poter fare con arduino qualcosa di piu utile di un led che cambia stato, sviscerare a fondo il comportamento degli interrupt è un passo fondamentale, piu precisamente è fondamentale capire come il compilatore dell IDE di arduino traduce in assembler le righe di codice che gli diamo in pasto.
Per Guglielmo, ti ringrazio infinitamente per la stima che ti ha suscitato in me la mia presentazione, ma credimi, alla soglia dei 50 quando riguardo il codice che scrivevo 15/20 anni fa mi gia la testa!
Ad oggi (complice anche mansioni diverse di lavoro che mi trovo a fare rispetto a tempo fa) mi ritengo un esordiente totale!
Ciao a tutti e grazie per l'interssamento.