Interrupt

Salve a tutti, dovrei misurare l'intervallo di tempo che passa tra l'invio di due impulsi sul pin digitale 3 di arduino (interrupt 1); non ho mai usato gli interrupt fin'ora e leggendo nel playground ho visto che nella funzione che devo inserire non posso usare delay() e millis() perchè con gli interrupt non funzionano... come posso risolvere?
Normalmente non uso gli interrupt ma stavolta credo siano necessari: devo far lampeggiare un led per 10 volte entro un tempo variabile, fissato appunto dai due impulsi che arrivano sul pin 3.
Pensavo di mettere un contatore che quando arriva il primo impulso comincia ad incrementarsi fino a quando non arriva il secondo segnale ottenendo così il l'intervallo di tempo tra i due impulsi, dividerlo per 10 così mi ritroverei il delay per passare al led per farlo lampeggiare 10 volte.
Altra cosa importante per cui credo sia necessario ricorrere agli interrupt è che la funzione che fa lampeggiare il led non viene eseguita una sola volta ma continuamente perciò appena arriva il secondo segnale il contatore si resetta e comincia il conteggio da capo... Inoltre c'è un altro problemino, riporto un esempio:
arriva l'impulso 1 e inizia a contare....
arriva l'impulso 2 e calcola che sono passati 10 secondi, quindi il led dovrà accendersi e spegnersi in un secondo, per 10 volte.
Supponiamo che arrivi il terzo impulso mentre la funzione sta ancora facendo lampeggiare il led... mi perderei una lettura e non riporterebbe poi la visualizzazione....
Come sbrogliare questa situazione?
Saluti

Si potrebbe pensare a mettere una variabile bool nell'interrupt, quando arriva il primo impulso la metti a true e nel loop quando va a true salvi il valore millis(). Quando arriva il secondo impulso se la prima variabile è true allora metti un secondo bool a true nell'interrupt e nel loop calcoli la differenza. A questo punto se sono passati 10 sec entri in un for o while per il lampeggio. Se dentro a questo ti arriva il terzo impulso, le due variabili bool che avevi reimpostate a false, ti tornera la prima a true quindi anche nel loop metti un controllo se true e salvi il valore di millis().

non ho mai usato gli interrupt fin'ora e leggendo nel playground ho visto che nella funzione che devo inserire non posso usare delay() e millis() perchè con gli interrupt non funzionano... come posso risolvere?

Non so se arduino fà qualcosa per impedire di usare millis e delay, so per certo che delay, blocca il micro in ciclo per un tempo x e se anche fosse possibile usarlo non và usate se non per brevissimi intervalli, per millis o micros invece non dovrebbero esserci controindicazioni, in leggono solo il valore del contatore del timer.

Io ho usato micros dentro un routine di interrupts ma non ho usato la funzione attach.... di arduino, può essere che anche con attach... puoi usare millis dentro la funzione.

L'importante che nella funzione compi operazioni che impiegano meno tempo possibile, se nella funzione che viene eseguita a seguito di un'interrupts scrivi codice che impiega tanto tempo devi tenerne conto, immagina che ci impieghi 2 secondi, per due secondi il codice nella funzione loop non verrà eseguito.

Inoltre prima di eseguire la funzione, tutti gli interrupt vengono disabilitati, es. 2 secondi senza interrupt e il micro sordo su tutti i pin.

C'è un modo complicato di lasciare gli interrupt inseriti anche nella funzione, ma prevede l'uso di macro ISR, ed anche altro.

Se ti va dai uno sguardo qui. http://www.arduino.cc/playground/Italiano/posizionatore

Quando uno dei pin della porta D cambia stato, avviene un salto all'etichetta (macro) ISR(PCINT2_vect)
e viene eseguito codice, come vedi uso micros.

anche a me serviva misuare l'inervallo di tempo tra due impulsi per ricavarne la frequenza.

Occhio che ciò che c'è scritto in quel codice contiene degli errori specie nei commenti, verifica sempre.

Ciao.

Per ora grazie ragazzi, spero di venirne fuori grazie ai suggerimenti che mi avete dato.

Prima di tutto non ti servono gli interrupt, puoi fare tutto nel loop usando la funzione pulseIn() http://arduino.cc/en/Reference/PulseIn
pulseIn blocca il codice finchè non arriva l'impulso, però puoi metterci un tempo di time-out, in pratica se non arriva un impulso entro il tempo di time-out, la funzione si sblocca.

Quindi ecco cosa dovresti fare: attendere il primo impulso (con pulseIn), attendere il secondo (sempre con pulseIn) (nel setup è meglio perchè non userai timeout), il secondo pulseIn e ottieni il tempo in microsecondi. microsecondi/10 ottieni la durata di un lampeggio, quindi per microsecondi/20 il led si accende e per microsecondi/20 il led si spegne. Quindi microsecondi/20 è anche il tempo che dovrai usare come time-out per le pulseIn() successive(o meglio la prima pulseIn() la seconda la fai solo se la prima ha avuto successo), in modo da evitare che le pulseIn() blocchino il codice non facendoti accendere/spegnere i led in tempo. Ovviamente per accendere / spegnere i led non devi usare delay ma basarti sull'esempio BlinkWithoutDelay.

Sembra un poco complicato, ma son qualche if e qualche variabile globale.

millis() e micros() le puoi usare all'interno dell'interrupt, però non si aggiornano. (anche se usi attachInterrupt() )

Per lo stesso motivo non puoi usare delay, perchè non aggiornandosi il valore bloccheranndo l'arduino sino al prossimo reset, e comunque l'interrupt deve essere veloce, altrimenti l'interrupt che aggiorna il timer non viene lanciato (ecco perchè i valori non si aggiornano) e, visto che molte librerie si basano sui timer, tutto sfasa.