Go Down

Topic: Funzione con millis() e dichiarazione var. locali (Read 162 times) previous topic - next topic

Mattia9914

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
Code: [Select]
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

gpb01

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
Search is Your friend ... or I am Your enemy !

Mattia9914

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?

gpb01

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
Search is Your friend ... or I am Your enemy !

Mattia9914

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?

gpb01

NO, ti ho detto che è comunque visibile SOLO all'interno della funzione in cui è dichiarata, fuori NON esiste, altrimenti sarebbe una comune "globale" !

Guglielmo
Search is Your friend ... or I am Your enemy !

torn24

#6
Oct 11, 2019, 07:03 am Last Edit: Oct 11, 2019, 07:03 am by torn24
Potresti pensare di mettere dei parametri alla funzione, un parametro messo a 0 non aggiorna, maggiore di zero aggiorna la variabile static.



Code: [Select]



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



Mattia9914

Potresti pensare di mettere dei parametri alla funzione, un parametro messo a 0 non aggiorna, maggiore di zero aggiorna la variabile static.



Code: [Select]



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?

torn24

#8
Oct 14, 2019, 06:48 am Last Edit: Oct 14, 2019, 06:59 am by torn24
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.

Code: [Select]





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







Go Up