delay() Arduino Function: Tight Loops and Blocking Code
Have you ever made an Arudino project and you want something to occur at a timed interval? Talán 3 másodpercenként akarod, hogy egy szervó mozogjon, vagy talán 1 percenként szeretnél egy állapotfrissítést küldeni egy webszerverre.
Hogyan csinálod ezt? Van olyan egyszerű és egyértelmű függvény, ami segít ebben? Igen van! A delay függvényt, valamint a millis() függvényt az alábbi videóban tárgyaljuk:
Ez a millis() függvény minisorozatunk 2. része. Az 1. rész segít megérteni, hogy mit csinál a millis() függvény, a 2. rész a szoros ciklusokat és a blokkoló kódot tárgyalja, a 3. rész pedig azt, hogy a millis() függvény mikor múlja felül a delay() függvényt.
Témák ebben a leckében
- Feszes hurkok
- Blokkoló kód
- A zene inspirálásának ősi receptje
Millis() kontra Delay()
Szóval azt szeretnénk, hogy valami meghatározott időközönként történjen, és erre keresünk megoldást. Ha a válaszod a delay függvény használata, nos, akkor nagyjából igazad van. De van más megoldás is.
A menőbb, elegánsabb lehetőség az Arduino millis() függvénye. És minél jobban ismered a millis függvény használatát, hogy segítsen az események időzítésében az Arduino kódodban, annál könnyebb lesz később más részeket is beépíteni a programodba.
Ha egyszer elkezded használni a millis() függvényt, boldogabb, vidámabb leszel, és a fene egye meg, az emberek kedvelni fognak.
![Arduino Millis() függvény](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/people_like_you.png)
Feszes hurok
Először is tárgyaljuk a szoros hurok fogalmát. És amikor azt mondjuk, hogy szoros hurok, mit jelent ez?
Nézzünk meg egy Arduino vázlatot a szoros hurok bemutatására. A legalapvetőbb szkeccsel kezdve csak két függvényünk van: void setup és void loop. És mint talán tudjátok, a void setup csak egyszer fut le, majd átadja a műsort a void loopnak.
![Arduino void setup loop](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/void_setup_loop_2.png)
A void loop ezután végigmegy minden olyan kódsoron, amely a cikluson belül (ezekben a szögletes zárójelekben) lehet.
Elvégzi az első sort, majd végrehajtja a másodikat, majd a harmadikat, és így tovább és így tovább, amíg a végére nem ér. Aztán visszamegy a tetejére.
Milyen gyorsan hajtja végre a hurkot? Ez attól függ, hogy melyik Arduino lapot használod, de egy Arduino Uno 16 megahertzes órajelsebességgel rendelkezik. Ez tehát azt jelenti, hogy másodpercenként 16 millió utasítás történik az Arduinón!
![Arduino órajele](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/16-Mhz.png)
Minden kódsor nem feltétlenül egy utasítás. Valójában a legvalószínűbb, hogy több utasításról van szó. De ettől még ez viszonylag gyors (a számítógéped processzora valószínűleg gigahertzes sebességgel működik… ez milliárdok).
Szóval ezt az üres vázlatot szoros huroknak tekintenéd? Határozottan, ez olyan gyors és szoros, amennyire csak lehet hurkot csinálni. Mivel a cikluson belül nincs semmi, amit végre kellene hajtani, a skiccen való átfutás ideje gyakorlatilag nulla. Másképp fogalmazva, a ciklus elejétől a végéig tartó intervallum rövid (ezért gyors, vagyis “feszes”).
Adjunk hozzá néhány sor kódot. Elindítjuk a soros kommunikációt, majd kiírunk valamit a soros monitorablakba.
![Arduino szoros hurok soros kommunikáció](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/tight_loop.png)
Ez egy szoros hurok? Vagyis a hurok elejétől a hurok végéig sokáig tart? Nagyon kevés időbe telik, tehát ez egy gyors, szoros hurok.
Azt azonban érdemes megjegyezni, hogy ez a hurok nem olyan szoros, mint az előző példa. Az előző példában nem volt kódunk. Tehát csak száguldott a cikluson keresztül. Most, hogy itt van egy függvényünk, a serial print, egy (aprócska) kis időbe telik, amíg a “Ice Ice Baby”-t kiírjuk a soros monitorra.
De ez még mindig egy elég gyors ciklus. Szóval adjunk hozzá egy kicsit több kódot. Ellenőrizzük a programmal, hogy megnyomtak-e egy gombot, és ha igen, akkor valami újat küldünk a soros monitorra
![Arduino tight loop serial monitor with button push](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/tight_loop_2.png)
Szóval deklaráltunk egy gombot, és egy if utasítással ellenőriztük, hogy megnyomták-e a gombot. Magas a feszültség az ötös pin-en? Ha igen, akkor kiírunk valami mást a soros monitor ablakába.
Ez egy szoros hurok? Tehát a ciklus elejétől a ciklus végéig, ez elég gyors?
Igen, még mindig elég gyors. Ez egy elég szoros hurok. Négy sornyi kódunk van. A soros monitorra nyomtatunk, majd egy gyors ellenőrzést végzünk, hogy megnyomunk-e egy gombot. És ha igen, akkor kiírunk valamit. Még mindig szoros, még mindig gyors.
A következőkben adjunk egy késleltetést a programhoz az Arduino delay() függvény segítségével. Alább láthatod, hogy ezer ezredmásodperces (1 másodperces) késleltetést adtunk a ciklushoz.
![Arduino szoros hurok késleltetéssel](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/tight_loop_3.png)
Ez még mindig egy szoros hurok? Sok az idő, a hurok kezdetétől a hurok végéig? Nem, ez határozottan nem egy szűk hurok. A kód gyorsan indul, megcsináljuk a soros nyomtatást, de aztán pont itt, a delay függvénynél megállunk.
Az egész program megáll, amíg várjuk, hogy ez a delay kód befejeződjön.
Amikor az Arduino eljut ehhez a kódsorhoz, olyan, mintha a közértbe mennénk. Eljutsz a legfeljebb 12 tételes sorba, de aztán az előtted lévő fickó előveszi a csekkfüzetét, és elkezd írni egy csekket. Tudod, hogy ott leszel egy percig. Itt is ugyanez a helyzet.
![Amikor valaki előhúz egy csekket az expressz sorban](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/checkout.png)
Szóval ez nem egy szűk kör. A hurok elejétől a hurok végéig eltelt idő elég jelentős. Főleg az előző pár programhoz képest. Az idő nagyságrendje óriási.
Most azt próbáltuk itt bemutatni, hogy ez az egész elképzelés a szoros hurokról relatív. Minden az alkalmazástól függ. Ha 10 milliomod másodpercenként kell ellenőrizni egy érzékelő állapotát, akkor egy három sornyi kódot tartalmazó program nem biztos, hogy elég feszes, ez csak attól függ.
A másik szempont, hogy nem minden kódsor végrehajtása ugyanannyi időt vesz igénybe. Ha egy olyan függvényt hívsz meg, ami egy csomó dolgot csinál, mint például a soros nyomtatás, akkor az az egy kódsor sokkal tovább tarthat, mint 10 másik kódsor.
Szóval a ciklus szorossága egy relatív elképzelés.
![Az Arduino ciklus szorossága relatív - Einstein](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/The-tightness-of-a-loop-is-relative.png)
Blokkoló kód
Amikor egy program egy ponton megáll, és némi időt vesz igénybe valamilyen kód végrehajtása, akkor ezt a kódot blokkoló kódnak nevezhetjük. Ez egy általános kifejezés.
A programunkban a delay függvény blokkoló kódként viselkedik. A delay utáni kódok egyike sem futhat le, amíg a delay véget nem ér, tehát blokkolva van.
Blokkoló kód azonban nem csak akkor van, ha a delay() függvényt használjuk.
Vegyük a programunkat, és szabaduljunk meg a delaytől, de adjunk hozzá egy for-hurkot. A for ciklusunk számokat és szöveget fog kiírni a soros portra.
![Arduino szűk for ciklus](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/tight_loop_4.png)
Hát meddig fut ez a ciklus? Egy darabig fog futni, mert 100 iteráción kell végigmennie, mielőtt megáll.
És mi a helyzet a for ciklus utáni kóddal? Az is képes lefutni? Nem, várnia kell, mert a for ciklus blokkolja.
Ez a for ciklus a fő hurokba van beágyazva. A for ciklus egy “szoros” ciklus? Mielőtt válaszolnál, hangsúlyozzuk újra, hogyan kell erről gondolkodni: sok időbe telik végigmenni ezen a for cikluson, a tetejétől az aljáig?
Hát, nem igazán. Csak két sornyi kód van benne. Tehát ez egy elég szoros hurok.
De ez egy szoros hurok, amelynek sok iteráción kell keresztülmennie, mielőtt a program eljut az alatta lévő kódhoz. Tehát még egy szoros hurok is, ha több iteráción keresztül kényszerül lefutni, blokkolhatja a kódunkat.
Bővebben a delay() függvényről
Beszéljünk még egy kicsit erről a delay függvényről. Mit állapítottunk meg eddig?
Először is azt mondtuk, hogy a delay függvény csökkenti a ciklus feszességét. Ha van egy feszes hurok, és hozzáadjuk a késleltetési függvényt, akkor az több időt vesz igénybe, és kevésbé lesz feszes. Vagyis a késleltetési függvénnyel nőni fog az az idő, ami a ciklus elejétől a végéig tart.
Azt is tudjuk, hogy a késleltetési függvény blokkolja a kódot. Ez kéz a kézben jár azzal, amit az előbb mondtunk. Amikor a késleltetési függvény fut, blokkolja más kód futását, amíg késleltet.
Azt gondolhatnánk, hogy ez a késleltetési függvény egy totális lazsáló! Soha nem fog semmit sem érni a projektjeinkben. De sok egyszerű programhoz, amit írunk, a delay függvény fantasztikusan működik. Egyszerű a használata, nagyon egyszerű a helyesírása, és pontosan azt teszi, amit mond.
![AzArduino delay függvény egy kanapé krumpli](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/Is-the-delay-function-a-total-slacker__.png)
Nem kell tehát feltétlenül kiközösítenünk a delay() függvényt a programozási eszköztárunkból. Csak azt kell felismernünk, hogy ez egy egyszerű programozási függvény, amely sok esetben működhet.
Van azonban egy idő, amikor elkezdünk problémákba ütközni. Ez azzal a blokkoló hatással függ össze, amit a delay függvény a programunkban kifejt.
A sorozat következő leckéjében, a 3. részben azt fogjuk azonosítani, hogy ez hol válik igazán problémává. Megtudhatjuk, mikor van értelme a delay() függvényt használni egy programban, és mikor van itt az ideje áttérni a millis() függvény használatára.
Áttekintés
Először a ciklus feszességéről beszéltünk. Azt mondtuk, hogy egy ciklus feszessége relatív. Attól függ, hogy milyen az alkalmazásunk.
Második, beszéltünk a blokkoló kódról, vagyis a blokkoló kódról. Lényegében ez egy általános kifejezés, amit olyan kódra adhatunk, amelynek a végrehajtása bizonyos időt vesz igénybe, és a programunk más részeinek a futását leállítja, amíg az végrehajtódik.
Reméljük, tetszett ez a lecke! A sorozat következő részében folytatjuk utunkat, hogy megtanuljuk, hogyan használjuk a millis függvényt, hogy időzített, ismétlődő eseményeket hozzunk létre az Arduino kódunkban. Legközelebb találkozunk!
![Arduino ősi recept az inspiráló zenéhez](https://programmingelectronics.com/wp-content/uploads/2019/04/ancient-recipe-gif.gif)