Funzione con millis() e dichiarazione var. locali

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.

Guglielmo

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.

Guglielmo

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" !

Guglielmo

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);

torn24:
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);