Tutorial: millis() contro delay()

In questi giorni ho approfondito alcuni comandi e librerie che Arduino ti mette a disposizione, lo scopo personale è stato quello di comprendere meglio alcune funzionalità e poter scrivere degli sketch più interessanti.

millis vs delay

La funzione che ha catturato la mia attenzione e potrebbe tornarti molto utile è millis(); ho voluto contrapporla a delay dopo aver trovato un interessantissimo articolo che ne descrive in modo egregio il funzionamento.

Sei abituato a vedere la funzione delay() e in tutti i miei sketch l’hai utilizzata moltissime volte, ma quante volte hai visto utilizzare la funzione millis(), io pochissime.

In effetti le due funzioni sono molto differenti pur avendo in comune alcune caratteristiche, una è che entrambe ragionano per millisecondi, ma sono differenti tra loro.

delay(): interrompe il ciclo di eseguzione di uno sketck ( il ciclo di loop() ) per un numero di millisecondi assegnato come argomento;

millis(): ritorna il valore in millisecondi trascorsi dall’inizio dell’eseguzione dello sketch;

E si, sono davvero differenti.

Vittorio Zuccalà ha scritto un interessantissimo tutorial, ben fatto e con un paio di esempi davvero chiari, ti invito a leggerlo e rimarrai davvero illuminato dal suo articolo.

Se hai dubbi commenta questo articolo con le tue domande, io sono sempre contento di poter aiutare neo appassionati, come me, ad apprendere cose nuove su arduino per i tuoi progetti.

Buon divertimento

  • Questo sito ed i suoi contenuti è fornito "così com'è" e Mauro Alfieri non rilascia alcuna dichiarazione o garanzia di alcun tipo, esplicita o implicita, riguardo alla completezza, accuratezza, affidabilità, idoneità o disponibilità del sito o delle informazioni, prodotti, servizi o grafiche correlate contenute sul sito per qualsiasi scopo.
  • Ti chiedo di leggere e rispettare il regolamento del sito prima di utilizzarlo
  • Ti chiedo di leggere i Termini e Condizioni d'uso del sito prima di utilizzarlo
  • In qualità di Affiliato Amazon io ricevo un guadagno dagli acquisti idonei qualora siano presenti link al suddetto sito.

Permalink link a questo articolo: https://www.mauroalfieri.it/elettronica/tutorial-millis-delay.html

67 commenti

Vai al modulo dei commenti

    • francesco il 20 Marzo 2013 alle 14:01
    • Rispondi

    Ciao , seguo con molto interesse il tuo sito e volevo ringrazziarti per l’ottimo lavoro che fai !!!
    posso usare la funzione mills per tenere acceso un led ?
    il mio primo progetto prevede una fotoresistenza che comanda un led ….solo che non volevo usare il delay per evitare che il led cominci a lampeggiare (pensando ad un uso fututo che tramite rele’mi comandera’ una vera luce esterna.)
    volevo impostare un tempo di 5 minuti e senza RTC non so come fare …
    grazie mille
    PS. lo sketch che ho fatto e’
    /*
    Fotoresistenza (A1)che comanda un led (2)
    */
    int fotoresistenzaPin = A1; // Pin di collegamento della fotoresistenza
    int fotoresistenzaValue; // Variavile che memorizzerà la lettura del valore
    #define luce 2 // pin di comando del LED
    void setup(){
    pinMode(luce, OUTPUT);
    Serial.begin(9600); // Inizializo la seriale
    }
    void loop(){
    int fotoresistenzaValue = analogRead(fotoresistenzaPin); // Leggo il valore della misurazione
    Serial.print(“Valore luminosità = “);
    Serial.println(fotoresistenzaValue);
    if(fotoresistenzaValue<190) //se il valore letto dalla luminosità è basso, accendo il led
    digitalWrite(luce,HIGH);
    // tenere acceso la luce per 5 minuti ….
    else
    digitalWrite(luce,LOW); //altrimenti lo spengo
    }

    1. Ciao Francesco,
      lo sketch che hai scritto è quello che in elettronica si chiama “interruttore crepuscolare”.
      Così come lo hai scritto non mi sembra abbia errori e non hai bisogno di delay() o millis()
      perchè se la luminosità è maggiore di 190 la luce sarà spenta, se minore sarà accesa.

      Cmq se vuoi usare millis() puoi farlo, la tecnica è scritta in moti tutorial sul sito, gli step logici sono:

      memorizzi millis() in una variabile unsigned long;
      verifichi che millis() – variabile sia maggiore di 5000 ( 5sec ) se è maggiore allora hai superato il tempo di attesa.

      Ricorda che se metti tutto questo codice nel tuo sketch non eviti il controllo ( if ) che fai;

      Mauro

    • francesco il 20 Marzo 2013 alle 17:38
    • Rispondi

    grazie mille Mauro , il millis lo voglio aggiungere perche’ se passa uno davanti al sensore si accende un flash la luce e poi si spegne .tecnicamente ho un progetto di domotizzarmi casa e sto pensando in modo reale e non su basetta (il sensore crepuscolare lo andro’ a mettere su una spina esterna protetta IP55 altezza uomo )e quindi sto cercando di immaginarlo gia’ comeuscirebbe.
    Nello sketch finale vorrei imparare ad usare ilmills per tenere acceso un pin per tempi evitando delay futuri , sto cercando anche la possibilita’ di dirgli alcaro Arduino
    “Se X> Y per TOT secondi allora fa questo per TOT2 secondi …e qua il delay o non ci sta o ci cade male….

    cmq dici di fare cosi :

    millis()=memotempo // memorizzo il valore di mills al controllo
    if(millis() – memotempo)>5000 //finche non passano5 secondi
    digitalWrite(luce,HIGH); //tieni la luce accesa
    else
    digitalWrite(luce,LOW); //dopo la spengo (con if cmq se e’ buio resta accesa)
    }

    1. Ciao Francesco,
      in ciò che hai scritto ci sono 2 errori: uno formale

      memotempo = millis() // non il contrario

      Che penso sia una svista.
      L’altro é un errore logico: se non inserisci una condizione che imposta il memotempo ad ogni ciclo loop() viene reimpostato e quindi i 5s non passeranno mai.

      Io metterei la condizione di memotempo = millis() impostata nell’ufficio della fotoresistenza e poi andrei a fare delle verifiche sia sul valore della fotoresistenza sia sul valore di millis() come hai fatto per decidere se i 5s servono per:

      – ritardare l’accensione della luce, evita effetto flash al passaggio di una persona;
      – ritardare lo spegnimento dopo l’accensione del led;

      dipende da come scrivi lo sketch e cosa vuoi ottenere, il bello della programmazione è che se cambi la posizione di un codice nello sketch, cambia anche la logica ed arduino non fa eccezione.

      Mauro

    • francesco il 21 Marzo 2013 alle 09:04
    • Rispondi

    Grazie mille , si il primo e’ un errore si sbaglio , scrivendo senza leggere ….
    per il secondo ho capito cosa dici e mi interesserebbe

    – ritardare l’accensione della luce, evita effetto flash al passaggio di una persona;

    non e’ per caso che puoi farmi un esempio anche a caso per capire ?purtroppo son affetto da nubbite e la funzione mills mi affascina ma non riesco propio a digerirla ….hotrovato in rete sketch molto esigui su lampeggi ma nulla di interessante , tanta roba di teoria su come funziona e sul oflw ma stringi stringi mi mancano le basi….

    1. Ciao Francesco,
      prova a leggere i miei articoli dul Dolly o RTC, faccio tanto uso della funzione millis() ed ho descritto riga per riga come funzionano.

      Mauro

  1. Ciao Mario,
    grazie per la citazione in queste pagine!

    1. Ciao Vittorio,
      di nulla, sei mitico ed il tuo blog è davvero interessante 🙂

      Mauro

    • Marco il 26 Giugno 2013 alle 19:31
    • Rispondi

    Ciao e complimenti per il sito,
    avrei una domanda da fare.
    Come posso far lampeggiare una sola riga del display arduino utilizzando la funzione millis()?

    Grazie

    1. Ciao Marco,
      quesito interessante, ti consiglio di assegnare il valore di millis al tempo T1 ad una variabile e confrontare il risultato di ( millis() – T1 ) con il valore T2 che rappresenta il tempo trascorso.
      Decidi tu se deve trascorrere più tempo o meno tempo variando T2.

      Mauro

        • marco il 27 Giugno 2013 alle 12:54
        • Rispondi

        Ciao e grazie per la risposta.
        Purtroppo non sono esperto e quanto mi hai scritto mi risulta un po’ incomprensibile.
        Sotto forma di programma come potrei scriverlo, ho provato a leggere ila guida di del sig. Zuccala ma non ne ho capito molto.
        Sono proprio inesperto.
        scusami

        1. Ciao Marco,
          ciò che vuoi realizzare non é semplicissimo ma neppure impossibile, ti occorre solo un po’ di studio magari partendo da tutorial più semplici.

          La mia Idea di Blog, come quella di altri appassionati come Zuccalá é di dare nozioni ed info perché sperimentiate ed impariate, non per servire codice bello e pronto, internet é stracolma di siti eh danno codice senza spiegazione, pronto all’uso.

          Comunque se leggi bene quello che ti ho scritto é già pronto per il tuo sketch.

          Mauro

            • marco il 29 Giugno 2013 alle 10:56

            grazie Mauro,
            hai ragione ci vuole studio, e mi sa che ci vediamo a Concorezzo….

            Grazie ancora

          1. Ciao Marco,
            so che per l’open day del 5 luglio ci sono già le liste di attesa e gli organizzatori stanno cercando di ottenere una sala più capiente, ti conviene iscriverti se vuoi partecipare.

            Mauro

    • Danilo il 1 Ottobre 2013 alle 13:01
    • Rispondi

    Ciao Mauro, il tuo blog e veramente interessante specialmente per persone alle prime armi come me. Ho un problema con il comando millis() non riesco ad associarlo come funzione. Non riesco a capire come aiuta ne conteggio. Percheè delay() quando richiamato genera un tempo di attesa mentre millis() cosa risulta?

    Ti chiedo di aiutarmi perche sto impazzendo, non riesco a trovare una spiegazione logica a questo codice.

    Chiedo a te perche e proprio grazie ai tuoi tutorial che mi sono appassionato ad arduino, questo merito del fatto che sono spiegati dettagliatamente ma in maniera molto semplice; che può essere compresa anche da un principiante come me.

    In attesa di una tua risposta ti ringrazio anticipatamente.

    1. Ciao Danilo,
      in fondo ad ogni articolo c’è scritto di non riportare codici nella pagina perché mi arrivano illeggibili.
      La differenza tra delay() e millis() è spiegata in questo articolo e trovi maggiori info nel Reference Arduino.

      delay(X): attende un tempo X in millisecondi durante il quale il tuo sketch si ferma, non esegue alcuna operazione;
      millis(): innanzitutto non accetta un tempo tra parentesi, in secondo luogo restituisce il conteggio in millisecondi passati dall’ultimo reset o spegnimento e infine non interrompe il funzionamento dello sketch;

      Capirai che sono utilizzate in ambiti diversi e con modalità indipendente.

      Mauro

    • Danilo il 1 Ottobre 2013 alle 17:11
    • Rispondi

    Grazie mille Mauro, scusa per il codice ma non avevo letto bene. Grazie per la spiegazione. Continua cosi perchè stai facendo un lavoro ottimo.

    • Michele il 11 Marzo 2014 alle 15:14
    • Rispondi

    ciao mauro,

    vorrei cosrtuire una sorta di allarme con dei pulsanti e un lcd in maniera che al premere di un pulsante appaia scritto sul display la scritta ”acceso” e incominci a suonare in modo intermittente un cicalino. Mentre se premo l’altro pulsante appaia scritto sul display la scritta ”spento” e il cicalino smetta di suonare.
    Il mio problema è far suonare il cicalino in modo intermittente on off a ripetizione all’infinito o meglio fino a che nn prema il pulsante di disattivazione,
    Sto usando un delay anziche i mills x creare l’alternanza di suono on off del cicalino e di fatti l’alternanza dura una sola volta e poi nn suona piu, nn so se è questo il mio errore, però nn ho per niente capito come utilizzare i mills. Se posso ti invierei pure lo skech , cmq dimmi te.
    Se puoi darmi una mano a capire te ne sono grato.
    grazie
    Michele

    1. Ciao Michele,
      non riesco a correggere gli sketch che scrivete.
      Posso suggerirti di verificare dove hai inserito i controlli dei pulsanti, probabilmente dopo la pressione del primo pulsante non ti sei salvato lo stato del tuo allarme, ossia inserito o acceso, per cui al loop() successivo il cicalino si ferma.

      Non è un problema di millis in questo caso.

    • Michele il 11 Marzo 2014 alle 19:35
    • Rispondi

    ciao mauro,
    alla meglio sono riuscito , almeno in parte nel mio progetto grazie alle variabili sìdi stato.
    premendo un pulsante attivo il cicalino e mi appare sul lcd la scritta acceso, se però volessi premere l’altro pulsante x disattivarlo nn succede niente e nn mi appare nessuna scritta sul lcd. ti posto lo skech, se puoi dargli un occhiata ti ringrazio gia da ora, altrimenti fa niente, grazie lo stesso!

    1. Ciao Michele,
      non correggo gli sketch perché mi ci vorrebbe troppo tempo e mi scrivete in tanti, per cui ho un plugin che cancella gli sketch postati sul blog in automatico.
      Ti consiglio di verificare che la variabile di stato che hai impostato per accendere il cicalino sia posizionata correttamente nel codice perché la pressione del pulsante di spegnimento riesca a reimpostarla

    • Stefano il 16 Aprile 2014 alle 22:25
    • Rispondi

    Ciao Mauro,
    Sto seguendo con entusiasmo i tuoi tutorial che mi hanno portato qui ad affrontare il MILLIS vs DELAY 🙂 .
    Ho seguito la tua guida sul led rgb comandato da 3 potenziometri e tutto va perfettamente (INTEL GALILEO), il mio problema nasce sulla lettura del monitor seriale cioè, troppo veloce o troppo lenta in base a come modifico il delay e di conseguenza anche la risposta alle variazioni che faccio con il potenziometro. Arrivando al dunque, come posso eseguire lo sketch in “multitasking” dove la scheda lavora sui pin 3,5,6 a 100ms mentre il Serial lavora a 5000ms ?

    Grazie mille

    1. Ciao Stefano, purtroppo non é possibile, arduino non é multitask.

  2. Salve,io ho realizzato un labirinto basculante comandato da due servi,quest’ultimi sono pilotati tramite il nunchuck della wii.
    una volta che la pallina cade in un buco,segue un percorso e finisce per attaccarsi su un a calamita,la quale è incollata su un suporto collegato ad un servo,il quale ruotando la alza e la fa cadere in un percorso che la fa arrivare ancora nel labirinto ed il gioco ricomincia….
    ora come ora ho pilotato il servo che alza la pallina tramite un pulsante dicendo che see il pulsante è a valore logico basso(pulsante normalmente aperto in condizione di riposo) il servo sarà a “TOT” gradi,ossia la pallina giu,se il pulsante è premuto,il servo ruoterà e la pallina andrà su…
    il problema che mi si presenta è che se io premo il pulsante per 1 sec. il servo inizia a ruotare ma appena rilascio il pulsante,ritorna giu…
    volevo inserire il comando millis() per fare in modo che anche se premo il pulsante una frazione di secondo,il servo compie tutta la rotazione,rimane su per 2 secondi e poi ritorna in condizione di riposo in basso per attendere la pallina … ma mi sta fumando la testa,mi perdo per strada..
    non capisco piu quante variabili devo inserire…
    se non erro dovrei averne una per il pulsante,una per il servo…
    quella del pulsante mi rimane alta per tutta la durata del ciclo,comandata dal pulsante,in modo che anche se rilascio il pulsante il servo continua a salre…ma me ne servirebbe un’altra che mantenga il servo su per X millisecondi per poi lasciarlo ricadere giu…
    non riesco a fare una stesura di tutto cio,per cortesia,mi potete aiutare a farlo ???
    grazie mille,un saluto Teocreo

    ecco il link al video del mio labirinto autocostruito con il mio taglio laser autocostruito 🙂
    https://www.youtube.com/watch?v=CPYMlHXZQq4

    1. Ciao Teocreo,
      il tuo progetto è molto interessante e mi piacerebbe pubblicarlo, se ti va puoi seguire cosa inviarmi in questo link:

      https://www.mauroalfieri.it/collabora.html

      Per la tua richiesta non comprendo perchè tu voglia usare millis() se devi fermare il servo in una posizione per un tempo X puoi usare delay();
      Se vuoi che lo sketch non si interrompa non devi far altro che memorizzare in una variabile il valore di mills() quando il servo è nella posizione in cui vuoi si fermi e confrontare ( if ) la differenza tra mills e questo valore con il tempo che vuoi attendere.

      1. Ciao…
        ho letto un po in giro e mi sembra di capire che millis è un po piu completo qundo non si vuole arrestare il tutto…
        visto che ho i servi pilotati dal nunchuck,mi sembra di aver capito che se uso delay per il servo che carica,i servi del piano mobile non seguono piu il nunchuck,per questo motivo volevo usare millis()

        ti allego il programma che ho usato,fatto copiando qua e la pezzi di altri programmi finchè a furia di tentativi non mi sono piu usciti errori,poi ho iniziato con le piccole regolazioni dei servi…

        ora,come dicevo,vorrei solo togliere un po di cose che non mi piacciono ed aggiungere qualche miglioria,ora ti spiego:
        Mi piacerebbe molto fare in maniera che premendo start,abbia la funzione di “dare 5 crediti” nel senso che posso caricare su la pallina N volte,e caricarla con il pulsante del nunchuck…raggiunti i N caricamenti,non caricherà piu fino a quando non verrà ripremuto il pulsante start…

        sarebbe bello che la parte del caricamento della pallina sia un ciclo a se,in modo che anche se premo per poco tempo il pulsante(che sia start o quello del nunchuck) il sevo vada su,attenda su X secondi e poi torni giu…

        la parte del pulsante start e dei crediti l’ho pensata da poco,non è necessaria,ma di certo tutti i miei problemi ora sono riguardo il servo che caria e il pulsante…

        ecco il prgramma:

        — codice rimosso in automatico —

        spero mi possiate insegnare come fare ,perchè ora arduio mi sta proprio affascinando e coinvolgendo…

        P.S. ho guardato su "collabora" ma non sono attivi i commenti.

        ciao ciao e grazie mille

        1. Ciao Teocreo,
          come avrai letto non è possibile incollare codice nei comemnti.
          Ti ho consigliato la lettura della pagina collabora non per inserire un commento di richiesta ma per indicarti le modalità con cui puoi inviarmi il tuo progetto per condividerlo ( prima voce in alto ) ritenendolo un bel progetto.

          Il blog è nato per dare spunti e insegnare ad appassionati come realizzare i progetti per cui puoi prendere tutti gli spunti e le parti di codiche che desideri.

          Se vuoi delegare la scrittura del codice puoi chiedermi un preventivo per commissionarmi il lavoro.

    • walter il 29 Maggio 2014 alle 19:29
    • Rispondi

    ciao a tutti
    la funzione millis() e’ interessante .In effetti in qualsiasi tutorial di microcontrolli , arduino compreso , usano spesso la funzione delay(x) che e’ bloccante .Ora , dipende sempre tutto dall’applicazione ;se per esempio devo gestire una tastiera di introduzione password per accessi o uno strumento codice morse o un semaforo potrei anche usare delay …ma per il resto , essendo una funzione bloccante direi proprio che sia il caso di usare millis().
    Poniamo un esemoio di applciazone embdedd, una lavatrice ….il programmatore inizia un certo ciclo , riscalda l’acqua e nel frattempo controlla che il tempo di intruduzione detersivo sia trascorso .Usando delay diventerebbe una procheria senza controllo e senza senso .Dico cosi perche essendo un esperto programmatore di plc in automazione industriale , non esiste proprio che un microprocessore stia li fermo ad attendere che un tempo scada.Penso sia utile creare una libreria di timer TON e TOF con la funzione millis().
    La libreria dovrebbe poter settare quanti timer usare nell’applciazione e quale tipo
    TON -> lo start deve rimanere attivo per tutto il tempo di preset impostato dopo di che si attiva un’uscita o meglio un bit che rimane a 1 finche lo start e’ attivo .Quando lo start cade si spegne il tmer TON.
    In sostanza e’ un timer di ritardo all’eccitazione …esempio ….ho un certa fotocellula impegnata e dopo 3 secondi che e’ in questo stato attivo una pompa o accendo una luce o attivo un motore .Quando la fotocellula non e’ piu impegnata si spegne il carico colelgato al Done di questo timer e si ricarica il cotnatore del timer .
    TOF -> la fotocellula e’ impegnata e l’uscita e’ attivata , quando la fotocellual non e’ piu impegnata l’uscita rimane ancora attivata per un certo tempo definito nel preset .Poi esistono anche timer impulsivi o che lavorano su fronte del trigger .Per cui si ptorebbe creare un array di timer strutturati cosi

    typedef struct{
    unsigned int Start:1 ; // si usa un solo bit se possibile
    unsigned int Counter: // e’ il contatore che viene incrementato con millis()
    unsigned int Preset; // viene settato per scegliere il periodo del timer
    unsigned int Done:1; // risultato del timer quando il counter e’ >= preset
    } Timer ;

    extern Timer timer[N_timers] ;

    Anche se la funzione millis() restituisce in modo asincrono il tempo di esecuzione questo tipo di timers va piu che bene per temporizzare attuatori , valvole ect motori ….
    Oppure si potrebbe usare un timer all’itnerno del quale gestire la logica di aggiornamento dei timer , solo che con arduno i timer sono usati per alcune periferiche ….on saprei ….
    Cosa ne pensate ?

    1. Ciao Walter, ottima esposizione. Forse sarebbe più chiara con qualche esempio e permetterebbe a tanti di esprimere un parere. Se ti va di inviarmi degli esempi io li pubblico volentieri, usa l’email del blog x inviarmi i codici.

    • richard zerpa il 22 Giugno 2014 alle 13:23
    • Rispondi

    hola Mauro estoy realizando un proyecto con arduino y quiero desplazar tres señales pwm 10 us entre ellas pmepuedes orientar????

    gracias

    1. Hola Richard,
      buscar en el blog hay muchos artículos.

    • Ernesto il 29 Aprile 2015 alle 19:29
    • Rispondi

    ciao Mauro, sto applicando un progetto dove i miei risultati devono essere poi riportati su display.., siccome devo misurare la temperatura e luminosità vorrei riportare tutto nell’LCD senza utilizzare un pulsante che separi le 2 misure.. è possibile farlo con questa funzione millis?
    ad esempio,
    temperatura….
    10 sec
    luminosità….
    10 sec
    e poi ricominciare con la misura.
    Ciao e grazie in anticipo

    1. Ciao Ernesto,
      per visualizzare i dati come vuoi tu puoi usare anche il delay( 10000 ) con il millis devi eseguire un confronto tra millisecondi trascorsi, come descritto nell’articolo.

    • Andrea Esbo il 16 Giugno 2015 alle 17:30
    • Rispondi

    Ciao mauro, avrei un problema su questo sketch, sto progettando un impianto stradale miniaturizzato, in poche parole sono due semafori temporizzati e un passaggio a livello utilizzando solamente un servo motore con il sistema di carrucole per permettere il movimento delle sbarre, inizialmente i semafori funzionano regolarmente, ma successivamente al ciclo del servo (quindi avvio e ritorno) i due semafori danno combinazioni a caso, vorrei chiederti se gentilmente riusciresti a darci un occhiata. In conclusione vorrei capire se lo sketch presenta errori che causano le combinazioni casuali dei led.
    Sketch:

    [[ codice rimosso in automatico ]]

    ti chiedo gentilmente se potresti rispondermi tramite e mail. grazie

    1. Ciao Andrea,
      alcune semplici regole:
      1. come leggi in ogni articolo ” NON è consentito incollare sketch nei commenti ” questo a causa del fatto che non correggo i codici di altri, non ho il tempo di testarli e non sono in grado di correggere codice solo leggendolo.

      2. non inserire la tua casella email nel testo dei commenti, non è una regola scritta ma di buonsenso: il blog è oggetto di visite continue da bot di spam e se trovano il tuo indirizzo nel testo ti distruggono la casella con email di spam.

      3. per i motivi indicati sopra ed il testo scritto nella pagina “sostieni il blog” l’email e le riposte via email sono riservate ai progetti su commissione.

      Venendo a quello che mi chiedi il comportamento è anomalo ma possibile se hai degli errori logici nello sketch, la cosa migliore che posso suggerirti è di utilizzare il Serial.print() nei punti cardini per capire cosa varia nelle variabili o nel loop() prima e dopo l’introduzione del servo.

    • Marco il 18 Settembre 2015 alle 15:08
    • Rispondi

    Ciao Mauro 🙂
    sono uno studente che progetta un dispositivo medico. Mi potresti aiutare? dovrei semplicemente calcolare il tempo che trascorre tra una volta che premo l’interruttore posto nella breadboard collegato ad arduino alla volta successiva per un massimo di 5 click e a parte vedere anche il tempo che ci impiego a premere complessivamente 5 volte il pulsante.
    Te ne sarei immensamente grato e complimenti per il sito 🙂

    1. Ciao Marco,
      quello che ti occorre è la funzione millis()

        • Marco il 18 Settembre 2015 alle 16:17
        • Rispondi

        Grazie per la tempestiva risposta ma dato che sono un principiante mi potrebbe aiutare cortesemente con la stesura del programma??? spero che mi puoi aiutare. Sto leggendo tutte le sue lezioni e le trovo molto dettagliate
        ed interessanti ma devo ancora entrare nell’ottica pratica.
        Grazie mille

        1. Ciao Marco,
          il miglior aiuto che posso darti è il blog, trovi tutto quello che ti occorre e se hai dei dubbi sui listati o sui passaggi che scrivo negli sketch puoi usare i commenti.
          Realizzo progetti su commissione a scopo professionale, tuttavia penso che il tuo progetto necessiti solo di un po di studio e prove.

    • Mario il 25 Settembre 2015 alle 17:03
    • Rispondi

    Ciao, il seguente sketch che ho creato con la funzione FOR mi permette di far accendere le frecce direzionali (prima tutte e quattro, poi quelle di sinistra e infine quelle di destra) per il mio modellino di auto e contemporaneamente all’apertura delle portiere si accende la luce interna dell’abitacolo, però sorge un problema, cioè la luce interna si accende dopo che ha completato tutto il ciclo delle “frecce direzionali”.
    So che per risolvere questo inconveniente dovrei usare la funzione millis(), però dopo qualche giorno di studio e prove su questa funzione non riesco ha fare questo sketch. Mi puoi dare qualche consiglio dove dovrei correggere il mio sketch? Grazie.

    P.S. questo sketch verrà caricato poi sull’attiny45.

    [[ codice rimosso in automatico ]]

    1. Ciao Mario,
      innanzitutto ti chiedo di rispettare le 2 semplici regole scritte in fondo ad ogni articolo del blog.
      Incollare codice nei commenti non è consentito e non correggo sketch scritti da altri perché non possiedo il tempo necessario ed il materiale per riprodurre il progetto e testarlo.

      Per il tuo problema ti consiglio di evitare l’uso della funzione millis() combinata al ciclo for( .. ) { … } in quanto l’uso di questo tipo di ciclo impedisce comunque il corretto svolgersi dello sketch.

    • Mario il 26 Settembre 2015 alle 13:33
    • Rispondi

    Ciao Mauro, studiando un po’ la funzione millis() ho rifatto lo sketch col ciclo FOR che avevo postato ieri inserendo la funzione millis(), però ho sempre un problema, cioè dopo che ha terminato il ciclo delle “frecce direzionali” i led rimangono spenti e non riparte da capo il ciclo.
    Mi potresti indicarmi dove devo correggere?

    Grazie e perdonami per il doppio post. 🙂

    [[ codice rimosso in automatico ]]

    1. Ciao Mario,
      ti consiglio di leggere la risposta che ti ho dato per il precedente post.

    • Luca il 22 Maggio 2016 alle 16:44
    • Rispondi

    Ciao, io ho un modulo bluetooth, che comandato con un’app, accende o spegne un led. a me però è venuta un’idea… vorrei far sì che se schiaccio una volta il tasto ON sull’app si accende il led verde, due volte il blu e tre volte il rosso. immagino debba usare millis, ma come?

    1. Ciao Luca,
      ti consiglierei di intervenire sull’App inviando segnali differenti se registri un singolo, doppio o triplo click.
      Gestendolo lato arduino rischi di perdere l’effettivo conteggio a causa della comunicazione bluetooth

    • Davide il 19 Luglio 2016 alle 19:08
    • Rispondi

    Ciao, io vorrei realizzare un programmino in modo che premendo un pulsante parta un conteggio di 5 minuti dopo di che mi dia un impulso ad un relè. (tutto questo deve essere multitasking).
    Questo sketch permette di leggere un pulsante ed attivare una determinata cosa, che poi ho adattato per lo scopo, ma non riesco ad inserire la funzione per cui quando state=HIGH parte il tempo ed al termine dà l’impulso al relè

    [[ codice rimosso in automatico ]]

    Mi puoi dare una dritta. Grazie

    1. Ciao Davide,
      innanzitutto ti invito a leggere le due semplici regole del blog riportate in ogni articolo.
      In merito alla tua richiesta sarò onesto: non ho capito cosa tu desideri fare.

        • Davide il 21 Luglio 2016 alle 18:57
        • Rispondi

        chiedo scusa ma non capisco cosa ci sia di così strano nella mia richiesta: 1) Premo il pulsante. 2) parte il countdown di 5 minuti. 3) dò un impulso di 350 ms ad un relè. (tutto questo deve funzionare senza delay all’interno dello sketch) Grazie

        1. Ciao Davide,
          adesso è più chiaro, desideri realizzare un pulsante temporizzato.
          Trovi molti articoli su come gestire i pulsanti, i delay e l’invio di output sui pin.

  3. Buongiorno signor Muaro Alfieri io stavo creando un programma con Arduino e ho usato la funzione millis per fare lampeggiare due led con due switch differenti. Solo che sbaglio,perchè non so bene il funzionamento di questa funzione millis.
    Questo è quello che io ho scritto:
    [ codice rimosso in automatico ]

    1. Ciao Ferry,
      in primo luogo ti invito a rispettare le regole del blog che leggi in fondo ad ogni articolo.
      In merito alla funzione trovi numersi esempi e spiegazioni nel mio Blog, a partire da questo articolo.

    • Antonio il 19 Gennaio 2017 alle 10:45
    • Rispondi

    Gentile Mauro Alfieri, buonasera. Smanettando su internet, cercando degli esempi di sketch su arduino, mi sono imbattuto nel tuo sito e devo farti i miei complimenti perché è certamente di grande aiuto per chi, come me, vuole iniziare a realizzare qualcosa con questo strumento fantastico. A tal proposito, ti scrivo perché vorrei realizzare uno sketch per dire ad arduino di eseguire delle istruzioni, in base al tempo di rilevazione di un sensore. Esempio: se pin sensore = alto, fai… istruzioni; se pin sensore = basso devo contare per quanto tempo rimane basso. se basso per meno di 5 secondi, fai questo… se invece rimane basso per più di 5 secondi, fai quest’altro… come posso fare? Grazie mille in anticipo, sei un grande

    Antonio

    1. Ciao Antonio,
      puoi usare il millis() per conteggiare il tempo ed in base al risultato puoi eseguire le istruzioni desiderate.

    • Antonio il 23 Gennaio 2017 alle 13:03
    • Rispondi

    Puoi essere un pò più preciso per favore? Scusami, sono un dilettante che vuole imparare. Grazie

    1. Certo Antonio, in merito a quale aspetto del millis() desideri maggiore definizione e precisione?

    • Daniele il 24 Marzo 2017 alle 16:45
    • Rispondi

    Buongiorno Mauro

    ti ringrazio per tutto il lavoro presentato nel sito, mi ha veramente aiutato in moltissime occasioni,

    purtroppo però mi sono imbattuto in un problema, magari anche semplice, però dal quale non riesco ad uscire.

    Ho un impianto idroponico con quattro elettrovalvole. Ho preso già tutti gli accorgimenti per evitare problemi di blocco processore e problemi di visualizzazione sul display.

    Le elettrovalvole attualmente si accendo e si spengono regolarmente, ma con dei delay, e con le future implementazioni di sensori, questo mi crea grandi problemi perchè arduino si ferma a contare!!!

    avrei necessità della seguente sequenza:

    Elettrovalvola uno accesa per esempio per cinque minuti e poi spenta, in sequenza si accende la successiva e si spegne la precedente, fino a quando la quarta si accende, passano i cinque minuti e si spegne, facendo reiniziare il loop con la prima elettrovalvola.

    Con delay tutto bene, ma con millis un disastro, non riesco a creare questa sequenza.

    [[ codice rimosso in automatico ]]

    Spero veramente che tu mi possa aiutare.
    Ti ringrazio anticipatamente

    1. Ciao Daniele,
      in primo luogo ti chiedo il rispetto delle due semplici regole scritte in fondo ad ogni articolo, che avrai letto.
      Gli sketch nei commenti vengono automaticamente cancellati come i link a siti di aste/generalisti/ecc..

      In merito al tuo problema con il millis() se mi spieghi meglio quale difficoltà incontri posso darti un suggerimento.
      Considera che non puoi sostituire il delay con il millis ma devi rivisitare tutto il codice sul concetto di conteggio del pempo trascorso ed adeguarne la logica.

    • Daniele il 28 Marzo 2017 alle 23:11
    • Rispondi

    Buonasera Mauro, ti ringrazio per la risposta. Provo a descrivere il mio problema, al quale sto ancora lavorando purtroppo con lievi risultati.Per quanto possa sembrare semplice dovrei ottenere il seguente risultato.
    Relè uno acceso esempio due minuti.
    Relè uno spento dopo.due minuti.
    Relè due acceso per due minuti successivamente allo spegnimento del primo relè.
    Relè due spento dopo due minuti
    Relè tre acceso per due minuti successivamente allo spegnimento del relè due.
    Relè tre spento dopo due minuti.
    Relè quattro acceso per due minuti successivamente allo spegnimento del relè tre.
    Fine del loop e rinizio del ciclo con gli stessi parametri.
    Il tempo di accensione è uguale per tutti e anche il tempo di spegnimento è uguale per tutti anche se i due tempi potrebbero essere diversi.
    In parte adesso.funziona ma solo per singoli relè quindi non saprei cosa fare adesso anche perché mi.sto ostinando su soluzioni che non mi.fanno vedere altre possibilità.
    Sono a tua disposizione per qualsiasi ulteriore chiarimento.
    Ti.ringrazio per l’aiuto.

    1. Ciao Daniele,
      cosa intendi per “In parte adesso.funziona ma solo per singoli relè” ?
      Come lo descrivi è proprio quello che deve fare, attivare un relay alla volta…metti tutti i relè nel loop() in sequenza.

    • alessandro il 8 Luglio 2017 alle 21:31
    • Rispondi

    Mauro Buonasera, ho un problema proprio di delay o millis,
    scrivo su lcd un valore di temperatura, a seguire do un delay di 200ms se no il valore sfarfalla molto e diventa quasi illeggibile , il problema e’ che cio mi rallenta di 200ms tutto il loop, ossia se in quei 200ms cambia lo stato di un ingresso anche per un istante questo non viene rilevato… come posso fare?

    1. Ciao Alessandro,
      usa il millis() per valutare il tempo che passa ed aggiorna il display solo se cambia qualcosa sugli ingressi o quando vuoi modificare l’info visualizzata.

  4. Buonasera Alessandro,
    Mi chiamo Gianfranco. (Piacere)
    Forse sbaglio tema… Credo proprio di si…
    In che modo potrei usare mills() per fingere il multitasking per usare IRremote per cambiare SUBITO fascette di luci?
    Grazie e perdonami per il disturbo

    1. Ciao Gianfranco,
      sbagli nome .. mi chiamo Mauro, come l’url del blog 🙂 Svista perdonata.
      Partendo dal concetto che Arduino Uno non è multitasking esistono delle librerie che sfruttano i TIMER interni per simulare questa funzionalità via software.
      Se ciò che desideri è solo eseguire una operazione intanto che un’altra sia in attesa puoi seguire il tutorial di Vittorio, il cui link è nell’articolo, che spiega molto bene come usare millis().

    • marco il 19 Dicembre 2018 alle 19:13
    • Rispondi

    Ciao, scusa una domanda ma come potrei applicare un millis() per attendere l’invio di un sms? cioè se mi va in allarme un sensore vorrei inviare un sms ogni 5minuti sarebbe fattibile? come?
    Grazie mille

    1. Ciao Marco,
      si certo è possibile. puoi conteggiare il tempo trascorso dal precedente invio memorizzando il valore di millis() all’invio dell’SMS e se sussistono le condizioni di allarme e sono passati 5 minuti invii l’sms

    • Matteo il 1 Aprile 2020 alle 17:17
    • Rispondi

    Buonasera Sig. Alfieri, volevo ringraziarla per la Sua guida. Molto interessante. Grazie

    1. Grazie Matteo, sono contento che ti sia stata utile.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.