Go Down

Topic: Millis: scusate ma non capisco (Read 759 times) previous topic - next topic

usul5761

Buongiorno a tutti, vi chiedo come mai in uno sketch come questo:
Code: [Select]

int led = 11;
unsigned long time;
unsigned long accensione;
unsigned long spegnimento;

void setup() {
  time=millis();
  accensione=millis();
  spegnimento=millis(); 
  pinMode(led, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  time=millis();
  if (time>accensione+2000){
    digitalWrite(led, HIGH);
    Serial.println (time);
   }
  if(time>spegnimento+4000){
    digitalWrite(led, LOW);
    Serial.println (time);
    accensione=millis();
    spegnimento=millis();
    }
 
}

tutto funziona...
ma se cambio il tempo di " accensione" esempio in 4000 e lo "spegnimento" in 1000
tutto si ferma.
Se ho capito bene ad ogni ciclo di if {} di millis corrisponde un tempo indipendente....
evidentemente non è cosi' o sbaglio?

Grazie in anticipo.

Patrick_M

Questi li hai gia letti/studiati?

Per capire come funziona e come applicare la funzione millis(), puoi studiare prima QUI, poi QUI ed infine leggere anche QUI e QUI  e questo post di Claudio_FF... vedrai che ti sarà tutto più chiaro
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

usul5761

si e penso anche di averli compresi, ma non mi torna la logica.
Se uso due "delay()" ognuno conta il suo tempo, ma con millis() no.
E' qui che mi fermo

ORSO2001

ragiona bene su quando passi il valore di millis() alle variabili.

usul5761

scusa sarò di coccio ma non ci arrivo......scusatemi

fabpolli

Non lio hai compresi se non ti torna la logica :)
A parte gli scherzi, è un errore in cui è facile cadere, delay è una funzione che blocca l'esecuzione del programma nel punto in cui è posizionata per un certo numero di mS quindi è vero che conta il suo tempo ma nel frattemo la MCU non può far nient'altro.
La funzione millis(9 invece ti restituisce in numero di mS trascorsi dall'avvio della MCU, sta a te determinare un istante d'inizio e di fine (su cui effettuare la necessaria differenza matematica) per determinare se il tempo voluto è trascorso e da li fare le operazioni desiderate. Se ritrovo un'immagine postata tempo fa sul forum molto bella ed esplicativa forse il concetto sarà ancora più chiaro.

usul5761

se faccio un if {millis() > vecchiomillis +2000}
secondo me vuol dire che 2000 è il tempo che voglio che passi
in effetti è cosi'....solo che se ne aggiungo un'altro per far fare il contrario o altro a millis() secondo me si incasina e non conta più ne il primo ne il secondo tempo
sembra quasi che i due tempi interagiscono uno con l'altro

fabpolli

#7
Sep 13, 2018, 02:25 pm Last Edit: Sep 13, 2018, 02:25 pm by fabpolli
Guarda questo post qui magari ti  aiuta.
Non è che si bloccano a interagiscano semplicemente sei tu che ti segni nel posto sbagliato l'ora d'inizio se dici al programma di accenderi dopo 4 secondi ma di spegnersi dopo 1 e allo spegnimento dici di nuovo accenditi tra 4 secondi ma spegniti tra 1 capisci bene da solo che i 4 secondi non arriveranno mai, così come hai scritto tu il programma ti funziona come vuoi tu se e solo se il tempo di spegnimento è maggiore del tempo di accensione. ma essendo logicamente difficile da comprendere come l'hai scritto ti consiglio di modificare il programma anche perché così capisci meglio come funziona la logica dietro millis() e sarai libero di riapplicarla in futuro.

ORSO2001

vai tranquillo che, per così poco, non si incasina.

dato che il tuo programma è semplicissimo...fatti un debug a mano...cioè scriviti su un pezzo di carta i valori delle tue varibili...considerando che il loop() è ciclico...e guarda come si comportano le due if()...cioè verifica se e quando le condizioni sono rispettate.

miky_police

e certo...sarà sempre verificata prima la if e poi la seconda dipendendo da quest'ultima la prima...
quando inverti i valori (nel senso di ritardare l'accensione e ridurre il tempo di HIGH per lo spegnimento) cosa succede?
è semplice, verrà verificata come TRUE (VERO) sempre prima lo spegnimento che a sua volta aggiorna le variabile... tradotto ---> il led non si accenderà MAI! e tu pensi di essere de coccio
CONSIGLIO: Usa millis() in questo modo
Code: [Select]

if (accensione-millis()>=2000) {
digitalWrite(LEDBUILTIN, HIGH);
accensione = millis();
}

così evitiamo di arrivare a parlare di nuovo di overflow di variabili e di che cosa accade e perché accade e tutti ci iniziamo a fare di nuovo le pippate sulle lancette dell'orologio...(ammetto, io l'ho capito con quello :D )
ultima, ma non per importanza, quando la condizione è verificata, oltre a far accendere o spegnere il led devi aggiornare anche la variabile interessata, cosa che hai fatto nello spegnimento, ma non nell'accezione.
Quindi se accensione - millis() è maggiore o uguale a 2000 accendi il led e accensione = millis()

PS: ho risposto da smartphone, mi scuso per errori grossolani ;)
Il vero stupido è colui che fa e rifa la stessa cosa aspettandosi risultati diversi. A.E.

usul5761

ok ho letto l'orologio.....ma non ci arrivo :smiley-confuse:
quindi ditemi se sbaglio(di sicuro)
devo sempre aspettare che il primo tempo che imposto sia maggiore del tempo che passa tra la prima e la seconda operazione?????

fabpolli

#11
Sep 13, 2018, 03:36 pm Last Edit: Sep 13, 2018, 03:38 pm by fabpolli
no non devi aspettare nessun tempo semplicemnete devi iniziare a contare il tempo che deve trascorrere per o spegnimento solo quanto hai acceso e viceversa, stai leggendo i post quantomeno con poca attenzione in modi differenti ti è stata suggerita la cosa già nei post #3, #5, #7, #8, #9 sempre in modi differenti ma il succo era quello.
Se ancora non riesci a capirlo allora il consiglio è quello di fare un passo indietro, ovvero fai un semplice programma che
  • all'avvio memorizza millis() (Setup), entra nel loop e dopo N secondi (diciamo 5) accende il led e nientaltro
  • Quando il punto uno ti funziona allora aggiungerai la funzionalità che quando il led è stato acceso (trascorsi 5 secondi dall'accensione) lo spenga dopo 2 secondi
  • Quando ti funzionano il punto 1 e 2 allora aggiungerai la funzionalità per riaccendere il led dopo che sono trascorsi 5 secondi dopo che è stato spento.

usul5761

#12
Sep 13, 2018, 03:43 pm Last Edit: Sep 13, 2018, 03:44 pm by usul5761
ok scusatemi per il disturbo grazie.

Standardoil

per lo OP:
Se posso fare un commento
il tuo errore è semplice e non grave
tu hai capito (più o meno) l'uso di millis,
ma stai tentando di usarlo per due differenti temporizzazioni,
quando in realtà tu devi pensare ad un'unica temporizzazione ciclica
questo sarebbe il classico esempio di macchina a stati: stato 1->stato2->stato1 etc etc
Prima legge di Nelson (che sono io): Non scambiare il fine con il mezzo: ricorda "cosa" devi fare, non "come" devi farlo

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

Claudio_FF

#14
Sep 13, 2018, 07:33 pm Last Edit: Sep 13, 2018, 07:36 pm by Claudio_FF
Quote from: miky_police
PS: ho risposto da smartphone, mi scuso per errori grossolani ;)
Ehmm, si, il confronto con millis()... è millis()-accensione


Quote from: usul5761
ok ho letto l'orologio.....ma non
Ho messo un'altra sintesi qui.

Per il resto (trascurando l'errore dell'overflow dopo 1192 ore) si tratta solo di due parti di programma concorrenti. Come dice Standardoil è un compito affrontabile più facilmente usando una logica a "situazioni" (una variabile "situazione" va usata assieme alle altre if per "abilitare" di volta in volta solo quelle corrispondenti alla situazione attuale).

Ad esempio, per usare le tue stesse variabili (ma si potrebbe semplificare):
Code: [Select]
void loop()
{
  time = millis();
  if (situazione == 0  &&  time - accensione >= 4000)
  {
    digitalWrite(led, HIGH);
    Serial.println(time);
    spegnimento = millis();
    situazione = 1;
  }
  else if(situazione == 1  &&  time - spegnimento >= 1000)
  {
    digitalWrite(led, LOW);
    Serial.println (time);
    accensione = millis();
    situazione = 0;
  }
}
* * * *    'if' e 'case' non sono cicli   * * * *
* * * Una domanda ben posta è già mezza risposta. * * *
* La corrente si misura in 'mA', la quantità di carica in 'mAh' *

Go Up