Salve
Mi sto imbattendo in un problema che riguarda la creazione di una funzione di temporizzazione con millis().
Il mio dubbio riguarda la creazione di una funzione temporizzata con millis() senza che però vi siano dichiarazioni esterne di variabili.
Io sono riuscito solo a pensare a qualcose di simile
bool funzioneTemporizata()
{
unsigned long tempoInizio = millis();
unsigned long tempo = 3000;
if(millis() - tempoInizio > tempo)
{
return 1;
}
}
Ma ovviamente la funzione continuerebbe ad aggiornare il valore di tempoInizio e la differenza non si verificherebbe mai. So che potrei dichiarare tempoInizio() globalmente e settarla uguale a millis() appena prima di entrare nella funzione, ma vorrei togliermi questa curiosità. Grazie a chiunque mi sarà d'aiuto
Se la vuoi locale, ma persistente (ovvero che non viene creata ogni volta che chiami la funzione, ma conserva il suo contenuto tra una chiamata e la successiva), devi aggiungere davanti la parolina "static". In questo modo la variabile verrà creata solo la prima volta che chiami la funzione e poi manterrà il suo valore.
Grazie. Domanda: se poi richiamo quella funzione più avanti nel programma, mi verrà aggiornata la variabile static? Cioè rimane statica finchè il codice esegue la funzione e poi la volta successiva acquista un nuovo valore oppure rimane?
Come ti ho detto, la variabile "static" è come una globale, solo che rimane visibile solo dentro la funzione dove l'hai definita, quindi, ogni volta che entri in quella funzione, la variabile avrà conservato il suo ultimo valore.
Va bene. Grazie. Se però io facessi alla fine del programma una cosa del tipo tempoInizio=millis() ne riuscirei comunque a variare il valore, corretto?
NO, ti ho detto che è comunque visibile SOLO all'interno della funzione in cui è dichiarata, fuori NON esiste, altrimenti sarebbe una comune "globale" !
Potresti pensare di mettere dei parametri alla funzione, un parametro messo a 0 non aggiorna, maggiore di zero aggiorna la variabile static.
bool funzioneTemporizata(unsigned long t, byte conferma)
{
static unsigned long tempoInizio = 0;
if(conferma)
tempoInizio=t;
unsigned long tempo = 3000;
if(millis() - tempoInizio > tempo)
{
return 1;
}
}
// Chiamata senza aggiornamento
funzioneTemporizata(0,0);
// Chiamata con aggiornamento
funzioneTemporizata(millis(),1);
Grazie, ma non capisco una cosa. Facendo così, non rischio che continuando a ciclare la funzione allora la variabile tempoInizio sia sempre = millis() e che quindi la differenza non si verifichi?
Nella funzione non assegna mai millis() alla variabile, se lo vuoi fare lo fai nella chiamata a funzione.
Mentre il codice che hai postato tu cera proprio questo problema, nel tuo codice entrando nella funzione assegnavo millis() alla variabile, per cui ogni volta che chiamavo la funzione era sempre uguale a millis().
Nel codice che ti ho postato io non c'è quella assegnazione.
Ovviamente nel programma nel loop() ci saranno delle condizioni if(), in una condizione vera aggiorno la variabile con millis(), normalmente invece richiamo la funzione senza aggiornare.
bool funzioneTemporizata(unsigned long t, byte conferma)
{
static unsigned long tempoInizio = 0; // Questa riga viene eseguita una sola volta
if(conferma)
tempoInizio=t;
unsigned long tempo = 3000;
if(millis() - tempoInizio > tempo)
{
tempoInizio=millis(); // Trascorso il tempo azzero la differenza
return 1;
}
}
// Chiamata senza aggiornamento
funzioneTemporizata(0,0);
// Chiamata con aggiornamento
funzioneTemporizata(millis(),1);