Pro Mini e Interrupts routines

Salve a tutti,

Devo trasformare un impulso (High) lungo circa 2 minuti in due impulsi (High) lunghi 2-3 secondi sul Pin 4.
In particolare questi 2 impulsi, uno deve essere generato dal fronte di salita dell'impulso lungo di comando, e il secondo dal fronte di discesa dello stesso impulso (spero di essere stato chiaro).
Per fare cio' mi servo di una Pro Mini a 5 V, e imposto il programma utilizzando entrambi i Pin di interrupt (o e 1) della scheda, e faccio in modo che sul fronte di salita venga generato un interrupt che mi fornisce il primo impulso (Pin 4) di circa 2/3 secondi, e sul fronte di discesa venga generato un secondo interrupt per fornire un secondo analogo impulso (Pin 4).
Ma ho l'impressione di non trovarmi con le temporizzazioni introdotte dai vari "Delay" sparsi nel programma, in particolare mentre sembra che i Delay scritti nella parte "Void Setup" eseguano una corretta temporizzazione (in Millisecondi),
sembra che che i "Delay" inseriti nella routines degli Interrupts, non eseguano una corretta temporizzazione, tanto che per ottenere un ritardo di circa 2 secondi devo usare un valore in Millisecondi di 20000.
Non capisco, e mi e' venuto il dubbio che nelle routines gestite dagli interrupts il parametro dei Delay vada espresso in "cicli di clock" del controllore.
Possibile? O sbaglio qualcosa?

Questo e' il codice:

int ledPin = 13;  // LED is attached to digital pin 13

void setup() {                

pinMode(4,OUTPUT);
attachInterrupt(0, salitaimpulso, RISING);
attachInterrupt(1, discesaimpulso, FALLING);
digitalWrite(4, LOW);
digitalWrite(4, HIGH);
delay(3000);
digitalWrite(4, LOW);
delay(8000);    
}

void loop() {

}

// Interrupt service routine for interrupt 0
void salitaimpulso() {

digitalWrite(4, HIGH);
delay(20000);
digitalWrite(4, LOW);
digitalWrite(ledPin, HIGH);   
}

// Interrupt service routine for interrupt 1
void discesaimpulso() {

digitalWrite(4, HIGH);
delay(20000);
digitalWrite(4, LOW);
digitalWrite(ledPin,LOW);   
}

>Antony3000: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra). Grazie,

Guglielmo

Salve,
Problema risolto. Leggendo qualche vecchio post ho visto che le temporizzazioni nelle routines degli Interrupts presentano qualche problema e vanno trattate in modo diverso che con i "Delay".

Grazie a questo forum

Si ma devi fare quanto ti ho chiesto al post #1 !

Guglielmo

Ma l'avevo gia' fatto. Non capisco ....
Adesso lo rifaccio...

Se il segnale é lungo 2 minuti allora non serve un interrupt. basta controllare se c'é un cambio di stato sul pin (non interessa nemmeno se un fronte in salita o discesa).

Ciao Uwe

Grazie per l'idea, Uwe

probabilmente anche nel modo da te suggerito arriverei allo stesso risultato, ma nel mio caso devo tenere conto dei fronti salita/discesa.
Inoltre mi sono gia' "incanalato" negli interrupts.

Ciao
Antonio

Antony3000:
Inoltre mi sono gia' "incanalato" negli interrupts.

Che non ti porta a niente perché nei interrupt non puoi avere dei ritardi o misure di tempo. Gli interrupt devono essere piú brevi possibili. Per questo non é una soluzione adottabile al Tuo progetto.
Ciao Uwe

Pero' stranamente il progetto sta funzionando.
Il progetto e' banale: praticamente devo generare due brevi impulsi ALTI, il primo per avviare una certa apparecchiatura e il secondo per fermarla.
Essendo che il progetto funziona, e' indubbio che entrambi gli impulsi vengono generati (sul Pin 4).
Nei delay inseriti nelle routines degli interrupts (che in teoria dovrebbero restringere o allargare gli impulsi) , se io nel parametro dei millis metto 2000 il progetto non funziona, se metto 10000 il progetto funziona in modo inaffidabile cioe' alle volte parte / si ferma e alle volte no, se metto 20000 non ci sono problemi.
Faccio presente che nella realta' per avviare / fermare l'apparecchiatura basta un impulso ALTO anche di 300 Millis.
Ovviamente io non sono in grado di misurare la durata degli impulsi generati effettivamente.

Le ISR DEVONO essere le più veloci possibili ... normalmente basta mettere vera una flag che viene poi verificata nel loop() che gira in continuazione.

Sicuro di non poter riscrivere così il tuo codice ?

Guglielmo

P.S.: Per sapere cosa si può e cosa invece NON si deve assolutamente fare nelle ISR ... leggere QUI ! :wink:

Provero' a riscrivere il codice seguendo i consigli fin qui avuti, se non altro per fare esperienza che mi manca.

Grazie a tutti
Antonio

E' semplice, dichiari variabili byte con attributo "volatile"; nel setup le metti a "false", le ISR le mettono a true.

Nel loop() se trovi una variabile a true, esegui quello che devi eseguire e la rimetti a false ... :wink:

Guglielmo