delay() Funzione Arduino: Loop stretti e codice di blocco

Giu 28, 2021
admin

Hai mai fatto un progetto Arudino e vuoi che qualcosa si verifichi ad un intervallo di tempo? Forse ogni 3 secondi vuoi che un servo si muova, o forse ogni 1 minuto vuoi inviare un aggiornamento di stato a un server web.

Come si fa? C’è una funzione semplice e diretta che ci aiuta in questo? Sì, c’è! Discuteremo la funzione delay, così come la funzione millis(), nel video qui sotto:

Questa è la parte 2 della nostra mini-serie sulla funzione millis(). La parte 1 ci aiuta a capire cosa fa la funzione millis(), la parte 2 discute i loop stretti e il codice bloccante, e la parte 3 discute quando la funzione millis() supera la funzione delay().

Temi di questa lezione

  • Circuiti stretti
  • Codice bloccante
  • Ricetta antica per ispirare la musica

Millis() contro Delay()

Vuoi che qualcosa accada ad un intervallo prefissato e stai cercando una soluzione. Se la vostra risposta è usare la funzione di ritardo, beh, avete più o meno ragione. Ma c’è un altro modo.

L’opzione più fredda e più elegante è la funzione Arduino millis(). E più avete familiarità con l’uso della funzione millis, per aiutarvi a cronometrare gli eventi nel vostro codice Arduino, più facile sarà incorporare altre parti nel vostro programma in seguito.

Una volta che inizierai ad usare la funzione millis(), sarai più felice, più allegro, e perbacco, piacerai alla gente.

Funzione Arduino Millis()

Funzione Arduino Millis()

Tight Loops

Prima parliamo del concetto di tight loop. E quando diciamo un ciclo stretto, cosa significa?

Diamo un’occhiata a uno schizzo Arduino per una dimostrazione di un ciclo stretto. Partendo dallo sketch più semplice, abbiamo solo due funzioni: void setup e void loop. E come forse sapete, void setup viene eseguito solo una volta, e poi passa lo spettacolo a void loop.

Arduino void setup loop

Arduino void setup loop

Void loop quindi passa attraverso ogni linea di codice che potrebbe essere all’interno del loop (dentro queste parentesi graffe).

Esegue la prima linea, poi esegue la seconda, e poi la terza, e così via, finché non arriva in fondo. E poi torna all’inizio.

Quanto velocemente esegue il ciclo? Dipende dalla scheda Arduino che stai usando, ma un Arduino Uno ha una velocità di clock di 16 megahertz. Questo significa che 16 milioni di istruzioni avvengono ogni secondo su Arduino! Velocità di clock Arduino

Velocità di clock Arduino

Ogni linea di codice non è necessariamente un’istruzione. Infatti, è più probabile che si tratti di più istruzioni. Ma comunque, è relativamente veloce (il processore del tuo computer probabilmente gira a velocità di Gigahertz… sono miliardi).

Quindi considereresti quello sketch vuoto un ciclo stretto? Certamente, è il più veloce e il più stretto che si possa fare un loop. Dato che non c’è nulla da eseguire all’interno del ciclo, il tempo necessario per passare attraverso lo sketch è praticamente nullo. Detto altrimenti, l’intervallo dall’inizio del ciclo alla fine è breve (quindi è veloce, o “stretto”).

Aggiungiamo alcune linee di codice. Avvieremo la comunicazione seriale, e poi stamperemo qualcosa nella finestra del monitor seriale.

Arduino tight loop serial communication

Arduino tight loop serial communication

È un loop stretto? Cioè, dall’inizio del loop alla fine del loop, ci vuole molto tempo? Ci vuole pochissimo tempo, quindi è un loop veloce e stretto.

Va bene notare, però, che questo loop non è così stretto come l’esempio precedente. Nell’esempio precedente, non avevamo codice. Quindi era solo una corsa attraverso il ciclo. Ora che abbiamo una funzione qui, serial print, ci vorrà (poco) tempo per stampare “Ice Ice Baby” sul monitor seriale.

Ma questo è ancora un ciclo abbastanza veloce. Quindi aggiungiamo un po’ di codice in più. Faremo controllare al programma se un pulsante è premuto, e se lo è, avremo qualcosa di nuovo inviato al monitor seriale

Arduino tight loop serial monitor with button push

Arduino tight loop serial monitor with button push

Abbiamo quindi dichiarato un pulsante e usato una dichiarazione if per controllare se il pulsante è stato premuto. La tensione al pin 5 è alta? Se sì, allora stampiamo qualcos’altro nella finestra del monitor seriale.

È un ciclo stretto? Quindi, dall’inizio del ciclo, alla fine del ciclo, è abbastanza veloce?

Sì, è ancora abbastanza veloce. Questo è un ciclo abbastanza stretto. Abbiamo quattro righe di codice. Stiamo stampando sul monitor seriale, e poi stiamo facendo un rapido controllo per vedere se un pulsante è stato premuto. E se lo è, stampiamo qualcosa. Ancora stretto, ancora veloce.

Prossimo aggiungiamo un ritardo a questo programma usando la funzione Arduino delay(). Potete vedere qui sotto che abbiamo aggiunto un ritardo di mille millisecondi (1 secondo) al loop.

Arduino tight loop con ritardo

Arduino tight loop con ritardo

È ancora un loop stretto? Il tempo, dall’inizio del loop alla fine del loop, è molto tempo? No, questo non è sicuramente un ciclo stretto. Il codice inizia velocemente, facciamo la stampa seriale, ma poi ci fermiamo proprio lì alla funzione di ritardo.

L’intero programma si ferma mentre aspettiamo che questo codice di ritardo finisca.

Quando Arduino arriva a questa linea di codice, è un po’ come andare a fare la spesa. Entri nella linea dei 12 articoli o meno, ma poi il tizio di fronte a te tira fuori il suo libretto degli assegni e inizia a scrivere un assegno. Sai che starai lì per un minuto. È lo stesso qui.

Quando qualcuno tira fuori un assegno nella linea espressa

Quando qualcuno tira fuori un assegno nella linea espressa

Quindi questo non è un ciclo stretto. Il tempo dall’inizio del ciclo alla fine del ciclo è piuttosto significativo. Soprattutto rispetto agli ultimi due programmi. L’ordine di grandezza del tempo è enorme.

Ora quello che abbiamo cercato di dimostrare qui è che tutta questa idea dei loop stretti è relativa. Tutto dipende dalla vostra applicazione. Se avete bisogno di controllare lo stato di un sensore ogni 10 milionesimi di secondo, allora un programma che ha tre linee di codice potrebbe non essere abbastanza stretto, dipende.

Un altro punto da fare è che non tutte le linee di codice richiedono la stessa quantità di tempo per essere eseguite. Se state chiamando una funzione che fa un mucchio di cose, come la stampa seriale per esempio, allora quella linea di codice può richiedere molto più tempo di altre 10 linee di codice.

Quindi la tenuta di un ciclo è un’idea relativa.

La tenuta di un loop Arduino è relativa - Einstein

La tenuta di un loop Arduino è relativa - Einstein

Codice bloccante

Quando un programma si ferma ad un certo punto, e impiega del tempo per eseguire del codice, quel codice può essere chiamato codice bloccante. Questo è un termine generale.

Nel nostro programma abbiamo la funzione delay che agisce come codice bloccante. Nessuno del codice dopo il ritardo può essere eseguito finché il ritardo non è finito, quindi viene bloccato.

Il codice bloccante non è, comunque, solo quando usiamo la funzione delay().

Prendiamo il nostro programma e liberiamoci del ritardo, ma aggiungiamo un ciclo for. Il nostro ciclo for stamperà numeri e testo sulla porta seriale.

Arduino tight for loop

Arduino tight for loop

Quindi per quanto tempo gira questo ciclo? Funzionerà per un po’ perché deve passare attraverso 100 iterazioni prima di fermarsi.

E che dire del codice dopo questo ciclo for? È in grado di funzionare? No, deve aspettare perché è bloccato dal ciclo for.

Questo ciclo for è annidato nel ciclo principale. Il ciclo for è un ciclo “stretto”? Prima di rispondere, ribadiamo come si dovrebbe pensare: ci vuole molto tempo per passare attraverso questo ciclo for, dall’inizio alla fine?

Beh, non proprio. Ha solo due linee di codice. Quindi questo è un ciclo abbastanza stretto.

Ma è un ciclo stretto che deve passare attraverso molte iterazioni prima che il programma possa arrivare al codice sottostante. Quindi, anche un ciclo stretto, se costretto a passare attraverso diverse iterazioni, può bloccare il nostro codice.

Più sulla funzione delay()

Parliamo un po’ di più su questa funzione delay. Cosa abbiamo stabilito finora?

Prima di tutto abbiamo detto che la funzione delay diminuisce la tenuta di un ciclo. Se avete un ciclo stretto e aggiungete la funzione di ritardo, ci vorrà più tempo e lo renderà meno stretto. Cioè, la quantità di tempo necessaria per andare dall’inizio del ciclo al fondo, aumenterà con la funzione di ritardo.

Sappiamo anche che la funzione di ritardo blocca il codice. Questo va di pari passo con quello che abbiamo appena detto. Quando la funzione di ritardo è in esecuzione, blocca l’esecuzione di altro codice mentre sta ritardando.

Potreste pensare che questa funzione di ritardo sia un totale fannullone! Non servirà mai a nulla nei nostri progetti. Ma per molti semplici programmi che scriviamo, la funzione delay funziona in modo fantastico. È semplice da usare, è davvero facile da scrivere, e fa proprio quello che dice.La funzione delay di Arduino è un couch potato

La funzione delay di Arduino è un couch potato

Quindi non dovremmo necessariamente ostracizzare la funzione delay() dalla nostra cassetta degli attrezzi. Dovremmo solo riconoscere che è una semplice funzione di programmazione che può funzionare in un sacco di casi.

C’è un momento in cui si iniziano a incontrare problemi, tuttavia. Questo ha a che fare con l’effetto di blocco che la funzione di ritardo ha nel nostro programma.

Nella prossima lezione della serie, parte 3, identificheremo dove questo diventa davvero un problema. Imparerete quando ha senso usare la funzione delay() in un programma, e quando è il momento di passare ad usare la funzione millis().

Rassegna

Prima abbiamo parlato della tenuta di un ciclo. Abbiamo detto che la tenuta di un ciclo è relativa. Dipende dalla vostra applicazione.

Secondo, abbiamo parlato di codice bloccante, o codice che si blocca. Essenzialmente, è un termine generico che possiamo dare al codice che impiegherà del tempo per essere eseguito, e che fermerà altre parti del nostro programma mentre viene eseguito.

Speriamo che questa lezione ci sia piaciuta! Nella prossima parte di questa serie, continueremo il nostro viaggio imparando come usare la funzione millis per creare eventi temporizzati e ripetitivi nel nostro codice Arduino. Ci vediamo la prossima volta!

Arduino antica ricetta per ispirare la musica

Arduino antica ricetta per ispirare la musica

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.