mentre arduino sta eseguendo funzione1() viene generato un interrupt che dovrebbe richiamare una funzione che dovrebbe saltare alla funzione successiva dal punto in cui c'è stato l'interrupt,in questo caso alla funzione2().
è possibile?
La soluzione migliore è esattamente come ti ha spiegato uwe. Potresti fare così:
#define pin 13;
volatile byte funzione_da_eseguire = 0;
void setup() {
pinMode(pin, OUTPUT);
attachInterrupt(0,salto,RISING); //solo sul fronte di salita, vedi te quali sono le tue esigenze
}
void loop() {
switch (funzione da eseguire) {
case 0:
funzione0();
break;
case 1:
funzione1();
break;
case 2;
funzione2();
default:
//non eseguire niente, inconsistenza dei dati
}
}
void salto() {
if (funzione_da_eseguire < 2) funzione_da_eseguire++;
else funzione_da_eseguire = 0;
}
Facendo così se avviene un interrupt a metà di una funzione si esegue la funzione successiva solo alla fine del ciclo così che la funzione attuale termina correttamente la propria esecuzione.
salve riprendo questo post, perchè non mi è chiaro come gestire questa situazione:
Facendo così se avviene un interrupt a metà di una funzione si esegue la funzione successiva solo alla fine del ciclo così che la funzione attuale termina correttamente la propria esecuzione.
scusa ma a qst punto a ke serve l'interrupt? se cmq aspetta la fine della funzione e poi esegue quella dopo?...qst lo fà già il programma da sè, perchè esegue le cose da sopra a sotto come codice.
dovrei dare delle label a dei punti nel programma e generato l'interrupt punterei alla label successiva a qlla ke sono...nn so se mi riesco a spiegare
cerozziello88:
dovrei dare delle label a dei punti nel programma e generato l'interrupt punterei alla label successiva a qlla ke sono...nn so se mi riesco a spiegare
Non si fanno salti nel codice, i classici "goto", perché rendono illeggibile il codice.
Quello che vogliono spiegarti Uwe e Janos è:
se tu nel mezzo di una funzione ricevi un interrupt e "molli" la funzione saltando ad altro, perdi dati.
A questo punto la questione è: ti interessa oppure no di perdere dati?
Inoltre c'è da fare una considerazione: gli interrupt si usano normalmente per operazioni di poca complessità perché il codice in esso contenuto blocchi il meno possibile l'esecuzione dello sketch dell'utente e la gestione degli altri interrupt del micro. Quindi per i tuoi scopi potrebbe bastare un flag come ha suggerito Janos oppure no?
Cmq se spieghi cosa vuoi fare magari possiamo suggerirti una soluzione alternativa.
si credo che come ha suggerito janos andrebbe bene: no tanto nn perderei niente.
allora sempre in merito al programma per la lavatrice che ho intenzione di fare vorrei :
questo è qnt esegue un certo programma:
carico acqua;
lavaggio dx e sx;
scarico acuqa;
carico acqua livello alto;
lavaggio dx e sx; //primo risciacquo
scarico acqua;
carico acqua livello alto;
lavaggio dx e sx;// secondo risciaquo
scarico acqua;
centrifuga;
fine
ad esempio quando parte il secondo risciaquo ed io mi accorgo ke nn è necessario dando un input (pulsante) passerei a scarico acqua; e dopo continua normalmente.
magari dove metto questo controllo del pulsante di avanzamento alla funzione successiva mi preoccuperò di mettere LOW le uscite che erano attivate nella funzione ke nn è stata finita.
Secondo me l'interrupt è inutile nel tuo caso.
Basta incapsulare ogni funzione all'interno di un while da cui esci al verificarsi di una condizione:
tempo del ciclo in esecuzione trascorso (dipende dal ciclo)
pressione pulsante
verificarsi di un errore
Esempio. Prendiamo il carico acqua. Qui non serve il tempo, ma serve ricevere un input dal galleggiante per sapere quando il cestello ha raggiunto il livello.
Quindi:
digitalWrite(Elettrovalvola, HIGH); //apre l'acqua
do {
} while ((digitalRead(Pulsante) != HIGH) && (digitalRead(Livello) != HIGH));
digitalWrite(Elettrovalvola, LOW); //chiude l'acqua
Mettiamo che Elettrovalvola sia il pin con cui comandi l'elettrovalvola, Pulsante il pin attaccato al pulsante e Livello il pin collegato allo switch del galleggiante. Apri l'acqua, poi ti metti in attesa che una delle 2 condizioni di uscita dal while si verifichi: se l'acqua raggiunge il livello oppure l'utente preme il pulsante, esci e chiudi l'acqua.
ok capito piu o meno... e quando non ho un tempo di ciclo, una condizione e nn premo il pulsante come fa a uscire dal do-while?
visto che cmq nn ci sn cose da ripetere mi basta che esegue almeno una volta poi o esce per la pressione del pulsante o ....magari inizializzo una variabile all'inizio del do e poi prima di chiudere la cambio valore?
cerozziello88:
ok capito piu o meno... e quando non ho un tempo di ciclo, una condizione e nn premo il pulsante come fa a uscire dal do-while?
Solo l'eternità dura per SEMPRE
Quello fatto è un esempio. Avrai una condizione per passare al ciclo successivo altrimenti come fai a farli eseguire in sequenza?
La mia lavatrice esegue i cicli a tempo: prelavaggio, risciacquo, lavaggio, risciacquo, centrifuga.
Tot minuti di prelavaggio, tot di risciacquo ecc...
visto che cmq nn ci sn cose da ripetere mi basta che esegue almeno una volta poi o esce per la pressione del pulsante o ....magari inizializzo una variabile all'inizio del do e poi prima di chiudere la cambio valore?
cerozziello88:
ok capito piu o meno... e quando non ho un tempo di ciclo, una condizione e nn premo il pulsante come fa a uscire dal do-while?
Solo l'eternità dura per SEMPRE
Quello fatto è un esempio. Avrai una condizione per passare al ciclo successivo altrimenti come fai a farli eseguire in sequenza?
La mia lavatrice esegue i cicli a tempo: prelavaggio, risciacquo, lavaggio, risciacquo, centrifuga.
Tot minuti di prelavaggio, tot di risciacquo ecc...
visto che cmq nn ci sn cose da ripetere mi basta che esegue almeno una volta poi o esce per la pressione del pulsante o ....magari inizializzo una variabile all'inizio del do e poi prima di chiudere la cambio valore?
Questo lo decidi tu in base alle tue esigenze.
nn sto capendo piu niente.
come hai detto tu: la lavatrice esegue delle cose con il programmatore che cammina man mano. se tu sposti il programmatore avanti lei interrompe quello che sta facendo e fa quello su cui tu hai portato il programmatore. io vorrei fare questo.
leo72:
Secondo me l'interrupt è inutile nel tuo caso.
Basta incapsulare ogni funzione all'interno di un while da cui esci al verificarsi di una condizione:
tempo del ciclo in esecuzione trascorso (dipende dal ciclo)
pressione pulsante
verificarsi di un errore
Il punto 2) è un pulsante come un programmatore a rotella come un'altra qualsiasi cosa.
case 3:
do {
digitalWrite(carico, HIGH);
statolivellobasso=digitalRead(livellobasso);
}
while (statolivellobasso== HIGH);
digitalWrite(carico, LOW);
lavaggiobreve();
do {
digitalWrite(acquacalda, HIGH);
permessoacquacalda=digitalRead(okacquacalda);
}
while (permessoacquacalda == HIGH);
digitalWrite(acquacalda,LOW);
for (int contatorelavaggi=0; contatorelavaggi <= 1 ; contatorelavaggi++){
lavaggiolana();
}
do {
digitalWrite(acquacalda, HIGH);
permessoacquacalda=digitalRead(okacquacalda);
}
while (permessoacquacalda == HIGH);
digitalWrite(acquacalda,LOW);
for (int contatorelavaggi=0; contatorelavaggi <= 1; contatorelavaggi++){ //vorrei poter uscire dal for con la pressione del pulsante
lavaggiolana();
}
scaricolana();
centri_e_scarico_lana();
do {
digitalWrite(carico, HIGH);
statolivelloalto=digitalRead(livelloalto);
}
while (statolivelloalto== HIGH);
digitalWrite(carico, LOW);
lavaggiolana; //vorrei saltare questa funzione mentre è in esecuzione
scaricolana();
centri_e_scarico_lana();
do {
digitalWrite(carico, HIGH);
statolivelloalto=digitalRead(livelloalto);
}
while (statolivelloalto== HIGH);
digitalWrite(carico, LOW);
lavaggiolana;
scaricolana();
centri_e_scarico_lana_lunga();
}
}
Devi ristrutturare il programma, come l'hai fatto tu non è fatto bene per la logica che vuoi adottare. Tu prevedi un'esecuzione lineare, dalla riga 1 alla riga 2 ecc ma non prevedi cicli condizionali per poter appunto uscire nel caso di eventi che modifichino il "corso degli eventi".
E, purtroppo, la strutturazione logica di un programma non si insegna in 3 minuti
quindi non posso farlo? non puoi darmi nemmeno un incipit? cioè dovrei riscrivere tutto? e eseguire ogni funzione con un ciclo? e x simulare l'uscita naturale dal ciclo come faccio? cioè se nn è premuto il pulsante per quale condizione esce dal ciclo?
Non ho detto che non puoi farlo, ho detto che devi riscrivere le parti principali inserendo il metodo di gestione dei loop con i suggerimenti dati.
Per simulare l'uscita da un ciclo devi inserire le condizioni da verificare in fondo al while in base al ciclo che stai eseguendo.
leo72:
Non ho detto che non puoi farlo, ho detto che devi riscrivere le parti principali inserendo il metodo di gestione dei loop con i suggerimenti dati.
Per simulare l'uscita da un ciclo devi inserire le condizioni da verificare in fondo al while in base al ciclo che stai eseguendo.
Ma non chiedermi di scrivere il codice, però
ok devo riscrivere tutto con i do-while xò ogni cosa la eseguirò almeno una volta giusto? quindi mi torna utile quando voglio uscire dai cicli ripetitivi e nn da un ciclo che esegue una sola funzione .
A parte che quel for a me pare che esegua solo 2 cicli, e non capisco l'utilità di usare un for per fare questo, dato che per 2 cicli soli "spendi" in termini computazionali molto meno mettere due volte la chiamata a lavaggiolana, l'uscita la devi mettere proprio in lavaggiolana (anche se non so cosa facciano).
ok devo riscrivere tutto con i do-while xò ogni cosa la eseguirò almeno una volta giusto?
Non è detto. Se metti un do..while allora il ciclo sarà eseguito sempre ALMENO 1 volta. Se metti il ciclo come while{}, hai il controllo della condizione PRIMA di entrare nel ciclo quindi se la/le condizione/i non è/sono vera/e, puoi anche saltare il ciclo.