Arduino Delay [Tutorial]

In questo tutorial imparerete come utilizzare correttamente la funzione delay() per aggiungere qualche ritardo tra 2 azioni nei vostri programmi Arduino. Quindi, scoprirai perché usare delay() spesso non è una buona idea quando vuoi ridimensionare i tuoi programmi e come risolverlo.

Va bene, cominciamo!

Indice

Perché hai bisogno di ritardi nei tuoi programmi Arduino?

Bene, un programma Arduino si basa molto su ingressi/uscite esterni per funzionare.

Facendo un semplice esempio: si potrebbe desiderare di monitorare lo stato di un pulsante 100 volte al secondo, o fare un LED lampeggia ogni 0,5 secondi.

Ora, come puoi ottenerlo? Un programma Arduino funziona in questo modo:

  • Innanzitutto, la funzione setup() viene eseguita una volta.
  • Poi il loop() funzione viene eseguita più e più volte, fino a quando si spegne il vostro Arduino.

Qualsiasi programma che scrivi verrà eseguito alla massima velocità. Quindi, se stai facendo lampeggiare un LED nel tuo codice, quello che succederà è che il LED lampeggerà ad una velocità molto alta (più migliaia di volte al secondo almeno).

Stai imparando come usare Arduino per costruire i tuoi progetti?

Scopri Arduino per i principianti e imparare passo dopo passo.

Se si desidera controllare il tempo, ovvero assicurarsi che il LED lampeggi solo ogni 0,5 secondi e non a piena velocità, è necessario aggiungere un ritardo nel codice.

Implementazione del ritardo Arduino nel codice

La funzione Arduino delay ()

Ecco un codice per far lampeggiare un LED (qui scegliamo il LED integrato, non è necessario aggiungere alcun LED esterno) ogni 0,5 secondi-questo è uno degli esempi più comuni che vedrai se inizi con Arduino.

#define LED_PIN 13void setup() { pinMode(LED_PIN, OUTPUT);}void loop() { digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); delay(500);}

Quindi, come funziona questo codice?

Per prima cosa usi un “define” in modo da non dover codificare il numero “13” più volte nel tuo codice e rende il tuo programma più leggibile.

Si imposta la modalità del pin in USCITA con la funzione pinMode().

Quindi, in loop() la funzione è:

  1. accendere il LED
  2. Uso delay(500) per rendere il programma di sonno per 500 millisecondi, o 0,5 secondi
  3. spegnere il LED
  4. Uso delay(500) per rendere il programma di dormire ancora per 0,5 secondi
  5. E tornare al passo 1, perché il loop() funzione continua ad essere eseguito di nuovo e di nuovo.

La funzione delay() si aspetta che tu dia un numero di millisecondi – non secondi – per dormire. Quindi, se pensi in pochi secondi, moltiplica il numero per 1000 e hai il valore che ti serve.

Fai un ritardo Arduino per 1 minuto

Se vuoi far dormire il tuo Arduino per 1 minuto o per più minuti, allora è abbastanza facile.

Prendi il numero di minuti, moltiplicalo per 60 per ottenere il numero di secondi, quindi moltiplicalo per 1000 per ottenere il numero di millisecondi.

Ex: delay(3 * 60 * 1000); farà dormire il programma per 3 minuti.

La funzione Arduino delayMicroseconds ()

Se è necessario essere più precisi, potrebbe essere necessario utilizzare la funzione delayMicroseconds(). Con delayMicroseconds() è possibile fornire un numero di microsecondi per dormire. La durata minima per delay() è di 1 millisecondo, quindi se hai bisogno di dormire solo per 400 microsecondi, qui hai una nuova soluzione.

Questa funzione può essere molto utile quando si comunica con alcuni componenti hardware. Ad esempio, Arduino deve inviare alcuni dati al componente e quindi leggere alcune risposte. Supponiamo che il componente abbia bisogno di 6 microsecondi per elaborare la richiesta e fornire dati accurati.

Quindi nel tuo programma potresti avere qualcosa del genere:

...void loop() { // send data to component delayMicroseconds(6); // reach out to component again to read data}

Ritardo non bloccante – perché dovresti evitare di usare delay ()

Quindi, ora che capisci cos’è un ritardo in Arduino e come implementarlo con delay() e delayMicroseconds(), vediamo come utilizzare la funzionalità delay – ma senza quelle funzioni.

Perché?

Quando si utilizza delay(), l’esecuzione del programma si interromperà e riprenderà solo al termine del ritardo.

Questo è OK se hai solo un’azione da fare-esempio: blink un singolo LED-ma cosa succede se avete bisogno di prendersi cura di più componenti hardware o comunicare con altri dispositivi come schede Arduino o il proprio computer?

Usando l’esempio precedente, come potresti far lampeggiare un LED ogni 0,5 secondi e un altro lampeggiare ogni 0,8 secondi?

In tal caso sarai bloccato abbastanza rapidamente. Se si desidera ancora utilizzare delay(), è possibile trovare una soluzione in cui si utilizzano ritardi più brevi tra più azioni, ma ciò renderà il programma più complicato ogni volta che si aggiunge una nuova azione.

La soluzione a questo è semplicemente monitorare il tempo senza usare la funzione delay(), fondamentalmente per trovare un modo per riprodurre il comportamento di delay() senza usarlo.

Esempio di codice-Arduino delay without delay ()

Riscriviamo il nostro esempio blink LED senza utilizzare delay().

#define LED_PIN 13unsigned int lastTimeLedBlinked = millis();unsigned int delayBetweenBlink = 500;byte ledState = LOW;void setup() { pinMode(LED_PIN, OUTPUT);}void loop() { unsigned int timeNow = millis(); if (timeNow - lastTimeLedBlinked > delayBetweenBlink) { if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(LED_PIN, ledState); lastTimeLedBlinked = timeNow; }}

Analizziamo questo codice riga per riga.

Inizializzazione

#define LED_PIN 13unsigned int lastTimeLedBlinked = millis();unsigned int delayBetweenBlink = 500;byte ledState = LOW;

Innanzitutto, si inizializzano 3 variabili nell’ambito globale:

  • lastTimeLedBlinked: questa variabile verrà utilizzata per memorizzare l’ultima volta che il LED ha lampeggiato. Fondamentalmente, ogni volta che faremo lampeggiare il LED, aggiorneremo questa variabile con l’ora corrente – usando la funzione millis ().
  • delayBetweenBlink: questo è il tempo che si desidera attendere tra 2 azioni – qui l’azione è quella di lampeggiare il LED.
  • ledState: dovremo memorizzare lo stato corrente del LED (ALTO o BASSO) in modo da poter sapere quale era lo stato precedente e agire di conseguenza.

Perché nell’ambito globale? Bene, quello che intendiamo fare è aggiornare quelle variabili nella funzione loop() e accedervi di nuovo la prossima volta che entriamo in loop(). Se creiamo le variabili all’interno di loop(), le variabili saranno variabili locali e quindi verranno distrutte quando si esce dalla funzione loop(). Pertanto, la prossima volta che loop() viene richiamato di nuovo, tutti i valori andranno persi e creerai nuovamente le variabili senza alcun valore precedente all’interno. Qui, creando le variabili al di fuori della funzione possiamo farle “sopravvivere” e mantenere il loro valore ogni volta che entriamo in loop().

Implementazione della funzionalità di ritardo Arduino nella funzione loop

Ora, vediamo cosa succede nella funzione loop().

void loop() { unsigned int timeNow = millis();

Innanzitutto, si legge l’ora corrente con la funzione millis().

 if (timeNow - lastTimeLedBlinked > delayBetweenBlink) {

E ora si confronta l’ora corrente che hai appena letto, con la volta precedente il LED lampeggia. Se è passato abbastanza tempo (più del valore memorizzato in delayBetweenBlink), significa che è possibile inserire if().

Questa struttura di codice – leggendo l’ora e confrontandola con la volta precedente in cui hai eseguito un’azione – è il modo in cui sostituisci la funzione delay(). Fondamentalmente stai solo calcolando una durata qui. E come puoi vedere significa che il tuo programma contiene più righe per una semplice applicazione, ma ti dà molto più controllo ed è molto più scalabile.

Quindi, cosa succederà? Bene, loop() continuerà ad essere eseguito a piena velocità. Ogni volta, il tuo programma controllerà se è passato abbastanza tempo. In caso contrario, loop() termina qui, perché non entrerà nella struttura if.

E, quando è passato abbastanza tempo, entriamo in if().

Eseguendo l’azione

 if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(LED_PIN, ledState);

OK, hai appena inserito if(), e questo dove farai qualsiasi azione che devi fare.

Qui facciamo lampeggiare il LED. E poiché non possiamo sapere direttamente quale fosse lo stato precedente per il LED (dal momento che abbiamo inserito loop() molte volte e perso tutte le variabili locali create all’interno), otteniamo quello stato da una variabile globale.

Quello che facciamo con questa variabile globale è semplice: se era BASSA, la impostiamo su ALTA, e se era ALTA, la impostiamo su BASSA. E poi, naturalmente, aggiorniamo lo stato fisico del LED di conseguenza, con digitalWrite().

 lastTimeLedBlinked = timeNow; }}

Infine, e questo è super importante, salviamo il tempo corrente come l’ultima volta che abbiamo battuto le palpebre il LED. Se non lo facciamo, il programma lampeggerà il LED a tutta velocità perché la condizione all’interno di if() sarà sempre vera.

Impostando l’ora precedente all’ora corrente “resettiamo il timer”.

Quindi, in quell’esempio, if() verrà inserito solo ogni 500 millisecondi o 0,5 secondi.

E ora questo è fantastico perché il tuo programma non si ferma, quindi puoi continuare a eseguire diverse azioni indipendenti mentre ancora “aspetta” di lampeggiare il LED.

2 azioni “allo stesso tempo”

Ad esempio, diciamo che vuoi lampeggiare un LED ogni 0.5 secondi, e un altro ogni 0,8 secondi.

#define LED_1_PIN 13#define LED_2_PIN 10unsigned int lastTimeLed1Blinked = millis();unsigned int delayBetweenBlink1 = 500;byte led1State = LOW;unsigned int lastTimeLed2Blinked = millis();unsigned int delayBetweenBlink2 = 800;byte led2State = LOW;void setup() { pinMode(LED_1_PIN, OUTPUT); pinMode(LED_2_PIN, OUTPUT);}void loop() { unsigned int timeNow = millis(); // Action 1 - Blink LED 1 if (timeNow - lastTimeLed1Blinked > delayBetweenBlink1) { if (led1State == LOW) { led1State = HIGH; } else { led1State = LOW; } digitalWrite(LED_1_PIN, led1State); lastTimeLed1Blinked = timeNow; } // Action 2 - Blink LED 2 if (timeNow - lastTimeLed2Blinked > delayBetweenBlink2) { if (led2State == LOW) { led2State = HIGH; } else { led2State = LOW; } digitalWrite(LED_2_PIN, led2State); lastTimeLed2Blinked = timeNow; }}

Come puoi vedere, ripetiamo la struttura del codice per la seconda azione che abbiamo aggiunto. E entrambe le azioni non si disturberanno a vicenda!

Recap

Se si vuole fare un Arduino ritardo senza utilizzare delay():

  1. Crea una variabile globale per memorizzare l’ultima volta che hai eseguito un’azione specifica.
  2. Crea un’altra variabile globale per memorizzare la durata desiderata tra 2 azioni.
  3. Nella funzione loop(), leggere l’ora corrente con millis().
  4. Subito dopo, usa una struttura if e usa la condizione (timeNow - lastTimeActionWasExecuted > delayBetweenActions).
  5. Una volta inserito il if(), eseguire l’azione.
  6. E ancora in if(), memorizza l’ora corrente come l’ora precedente.

È possibile ripetere questi passaggi per ogni azione per la quale è necessario un ritardo Arduino.

Quando è ok usare delay () e delayMicroseconds ()

Ci sono occasioni specifiche in cui l’uso di delay() nel tuo codice è ancora OK.

Ecco 2 di quelli:

  • È necessario inizializzare un componente durante la configurazione del programma e questo componente richiede un po ‘ di tempo per essere inizializzato, ad esempio 1,5 secondi. In questo caso, l’utilizzo di delay(1500) nella funzione setup() va perfettamente bene. Fondamentalmente, qualsiasi delay() nella funzione setup() del tuo programma Arduino non sarà un problema.
  • Come spiegato nella parte delayMicroseconds(), è necessario attendere alcuni microsecondi (non millisecondi!) quando si comunica con un componente esterno. Se trovi che usare delayMicroseconds() con un numero piccolo (ad esempio 10) non disturba il resto del tuo programma, puoi comunque usarlo senza doverti preoccupare troppo. Ma consideralo come un’eccezione, non la regola comune.

Conclusione – Usa Arduino delay() con cura

A causa della natura dei programmi Arduino, dovrai spesso aggiungere ritardi nel tuo codice, in modo da poter scegliere quando eseguire alcune azioni e quanto spesso vuoi eseguirle.

Le funzioni delay() e delayMicroseconds() sono funzioni molto semplici da usare e sono state aggiunte al linguaggio Arduino in modo che i principianti completi possano iniziare con qualcosa di semplice.

Tuttavia, come hai visto in questo tutorial, l’utilizzo di delay() può farti rimanere bloccato molto rapidamente. Quindi, è meglio prima capire perché ne hai bisogno, come usarlo e quindi come ottenere lo stesso comportamento senza utilizzare direttamente la funzione Arduino delay().

Una volta che hai capito la struttura del codice per sbarazzarsi di delay(), sarai in grado di migliorare molto i tuoi programmi Arduino e il multitasking diventerà abbastanza facile.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.