ancora millis()

Salve a tutti ,
sono nuovo del forum e anche principiante nella programmazione con arduino .
Mi sono imbattuto nella funzione millis , letto tutorial vari e spulciato vari topic ,
non ho trovato pero' la soluzione al mio quesito , e cioe':
impostare il ritardo dopo un input , con questo codice quando pigio il pulsante connesso al pin 4 il led si accende immediatamente . Mentre io vorrei che il led si accendesse dopo i 2 secondi impostati (tenendo premuto il pulsante).

unsigned long prev_time;
unsigned long time;
unsigned long rit=2000;
const int led =13;
const int pin=4;

void setup () {
  pinMode(13,OUTPUT);
  pinMode(4,INPUT);
 
}

void loop() {
unsigned long time=millis();
if (digitalRead(4)==1){
  if(time > prev_time + rit){
  digitalWrite(13,1);
}
  
  else if (time >=5600){
  
  digitalWrite(13,0);
  }
}
}

pensate ci sia qualche speranza o sono un caso irrecuperabile ?

cosa vuoi fare con
else if (time >=5600){
?

il "else if" si riferisce al "if(time > prev_time + rit){" e non al "if (digitalRead(4)==1){"

Ciao Uwe

Beh speravo di spegnere il led a 5600..... Ma non è questo il punto , era solo un test.
Il dubbio che ho è come fare a lanciare millis quando voglio io, cioè dopo la pressione del pulsante.
Ciao

tucano101:
Il dubbio che ho è come fare a lanciare millis quando voglio io, cioè dopo la pressione del pulsante.
Ciao

millis è un contatore e si "lancia" da solo all'accensione del micro, indipendentemente dal fatto che lo usi o meno.

dovresti fare:
if pulsante premuto salvi millis in una variabile: T1 = millis();
if millis() - T1 > 2000 allora accendi il led

pensate ci sia qualche speranza o sono un caso irrecuperabile ?

Tante, ma non è ancora arrivato per te il momento di usare millis().

PS: Per qualche strano motivo il semplice copia ed incolla del codice non rispetta la formatazione, però
nell'IDE ci sono opzioni che permettono di copiare il codice per postarlo nel forum.

Il codice così come è formattato nel post non è leggibile/comprensibile ed è questo che ti faceva notare uwefed.
Modifica il post del codice usando l'opzione presente nell'ide al fine di rispettare una corretta formattazione, diversamente a me girano gli occhio con tutte quelle parentesi graffe non allineate.

L'argomento millis è ricorrente in questo forum, prova a cercare nei precedenti topic, sicuramente troverai anche molte mie risposte all'argomento. L'uso di millis sembra complicato, ma non lo è.
Alcuni consigli:

  • Non copiare codice da altri sperando che funzioni
  • Simula il valore restituito da millis e quello che contengono le varie variabili.

Ciao.

Ciao ragazzi e grazie per le risposte ,

per postare il codice l'ho prima selezionato in giallo e poi col tasto destro ho scelto "copia per il forum"..........pensando fosse la prassi corretta .
Se lo impone il galateo la prossima volta mettero' le graffe allineate , promesso . :frowning:

il codice non l'ho scopiazzato , ho preso spunto guardandomi in giro in rete ;
sto solo tentando di carpirne bene il concetto per poterlo usare come si deve , tutto qua' .
Comunque ,alla fine , anche le bacchettate servono per imparare ..........

alla prossima

ciao ciao

per postare il codice l'ho prima selezionato in giallo e poi col tasto destro ho scelto "copia per il forum"..........pensando fosse la prassi corretta .

Ok, ma è uscita una formattazione pessima da questa procedura, non so il perché.

il codice non l'ho scopiazzato , ho preso spunto guardandomi in giro in rete ;

Capito male, non ho detto che il codice lo hai scopiazzato, ti consiglio di evitare di farlo in particolare
per la funzione millis(), perché è controproducente.

void loop() {
     unsigned long time=millis();

     if (digitalRead(4)==1) {
         if(time > prev_time + rit) {

             digitalWrite(13,1);

        } else if (time >=5600) {
  
             digitalWrite(13,0);
        }
    }
}

Ricordo un vecchio post, ora provo a cercarlo: millis

Riporto integralmente una mia risposta:

La funzione millis() ritorna un valore in millsimi di secondo accumulato dentro una variabile unsigned long.
Ogni millesimo di secondo un timer hardaware genera una specifica richiesta di interruzione, come risultato di ciò viene eseguito del codice che incrementa la variabile unsigned long, dopo l'incremento la CPU riprende ad eseguire il flusso sequenziale delle istruzioni.

Se non fosse chiaro, il flusso sequenziale viene interrotto ogni millesimo di secondo al fine di eseguire il codice che incrementa la variabile unsigned long.

Grazie al valore di questo contatore è possibile eseguire codice ad intevalli temporali specificati, tuttavia non c'è certezza che la tempistica specificata sia rispetta e ciò accade perché il controllo del tempo scaduto viene eseguiti nel loop.
Il tempo impiegato per eseguire tutto il codice inserito nel loop dipende appunto dalla quantità e dal codice stesso, nel senso che un ciclo for che richiede un minuto per essere esguito impedisce al micro di eseguire il codice presente dopo questo fantomatico ciclo for.

L'uso di millis() è paragonabile a guardare continuamente l'orologio al polso al fine di verificare il tempo trascorso.
Quindi è abbastanza semplice risalire alle azioni che compiresti:
Ho bisogno di contare il tempo che passa ? Si else No
Se si guardi l'orologgio e ti segni in un pezzo di carta l'ora (in millesimi di secondo)
<<Ciò equivale a consarbare il valore restituito da millis() nella variabile startTimer>>

Visto che la funzione loop equivale ad un ciclo infinito, dovrai trovare il modo di prendere il tempo solo quando serve e una volta sola.

startTimer conterrà sempre un valore inferiore al valore restituito dalla funzione millis().

Il controllo del tempo sarà qualcosa di simile a:
if (millis() > startTimer + Intervallo) {
...
}

Dove intervallo è il tempo che deve trascorrere prima che il codice tra {} possa essere eseguito.
Se ad esempio:
startTimer = 2000 (cioè 2 secondi)
intervallo = 11000 (cioè 11 secondi)
if (millis() > 2000 + 11000) {
....
}
Quindi il codice verrà eseguito quando millis() restituisce un valore maggiore di 13000.

Spero ti sia di aiuto.

Tu chiedi questo:

con questo codice quando pigio il pulsante connesso al pin 4 il led si accende immediatamente . Mentre io vorrei che il led si accendesse dopo i 2 secondi impostati (tenendo premuto il pulsante).

unsigned long time = 0;
void loop() {
      if ( time == 0 )    //  Se time == 0, salvo il temo corrente dentro time che adesso non è più 0
          time = millis(); // (1)
     
     if ( digitalRead(4) == 1 ) {  // se il pin 4 è alto
        
          if ( millis() > (time + 2000 ) {   // se millis() supera time + 2000 sono passati 2 secondi  
              digitalWrite( 13, 1 );   
              time = 0;    // azzero time cosi che al prossimo ciclo venga eseguita la (1)
          }

     }  else  {

         time = 0;  se il pulsante non è premuto azzero time, così al prossimo ciclo viene eseguita la (1)
     }

Prova con il codice sopra.

PS; Le bacchettate servono si, ma non è questo il caso.

Ripeto cerca nelle vecchie discussione, anche perché ci sono diversi modo di usare millis a seconda di ciò che vuoi ottenere.

Se lo impone il galateo la prossima volta mettero' le graffe allineate , promesso . :frowning:

No nessun galateo, abbiamo la capacità di capire cosa fa il codice e quale errore di logica contiene, in meno di 10 secondi solo se il codice è scritto chiaramente, dotato di commenti, diversamente a me personalmente mi viene la nausea, mi girano gli occhio e la testa e non per scherzare ma sul serio. Poi c'è chi ne fa una questione di etichetta, e altri che hanno scritto centinaio di libri su come scrivere codice migliore, più comprensibile, più ordinato ecc. Pensa che nel scegliere il nome di una variabile ci si può anche impiegare 30 minuti, minuti che li ricuperi in futuro quando leggerai il programma a distanza di tempo (settimane/mesi).

Ciao.

Altra possibilita', che include un controllo in piu ... [ARRESO]Pulsante con doppia funzione. - #17 by Etemenanki - Generale - Arduino Forum

Il primo esempio ti permette di eseguire due diverse istruzioni, o serie di istruzioni, alla pressione oppure al rilascio del pulsante, e puo essere modificato facilmente per ottenere un'attivazione ritardata di qualcosa (una volta che il pulsante e' stato premuto, si controlla con un'if il tempo trascorso e si agisce di conseguenza) ... il secondo esempio, ti da la possibilita' di scegliere se eseguire due diverse istruzioni, o serie di istruzioni, secondo se il pulsante e' rimasto premuto piu o meno di un certo tempo (ma solo quando viene rilasciato, ovviamente, altrimenti non potresti calcolare per quanto tempo e' rimasto premuto)

Il debounce fallo hardware, che ti elimina un bel po di problemi di gestione nello sketch :wink:

grazie ragazzi e' tutto molto piu' chiaro ora .