delay() Arduino Function: Tight Loops and Blocking Code
Oletko koskaan tehnyt Arudino-projektia ja haluat, että jotain tapahtuu ajoitetulla aikavälillä? Ehkä 3 sekunnin välein haluat servon liikkuvan, tai ehkä 1 minuutin välein haluat lähettää tilapäivityksen web-palvelimelle.
Miten se tehdään? Onko olemassa yksinkertaista ja suoraviivaista funktiota, joka auttaa meitä tässä? Kyllä on! Keskustelemme delay-funktiosta sekä millis()-funktiosta alla olevalla videolla:
Tämä on osa 2 millis()-funktio-minisarjastamme. Osa 1 auttaa meitä ymmärtämään, mitä millis()-funktio tekee, osa 2 käsittelee tiukkoja silmukoita ja estävää koodia, ja osa 3 käsittelee sitä, milloin millis()-funktio päihittää delay()-funktion.
Tämän oppitunnin aiheet
- Kireät silmukat
- Salpaava koodi
- Vanha resepti inspiroivaan musiikkiin
Millis() vs. Delay()
Tahdot siis, että jokin asia tapahtuisi määrätyllä aikavälien väliajalla ja etsit ratkaisua. Jos vastauksesi on delay-funktion käyttäminen, olet tavallaan oikeassa. Mutta on olemassa toinenkin tapa.
Viileämpi ja tyylikkäämpi vaihtoehto on Arduinon millis()-funktio. Ja mitä tutummin osaat käyttää millis-funktiota, joka auttaa sinua ajoittamaan tapahtumia Arduino-koodissasi, sitä helpompaa on myöhemmin sisällyttää muita osia ohjelmaasi.
Kun alat käyttää millis()-funktiota, olet onnellisempi, iloisempi ja hitto vie, ihmiset pitävät sinusta.
![Arduino Millis()-funktio](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/people_like_you.png)
Kireät silmukat
Keskustellaan ensin tiukan silmukan käsitteestä. Ja kun puhutaan tiukasta silmukasta, mitä sillä tarkoitetaan?
Katsotaanpa Arduino-sketsiä tiukan silmukan demonstroimiseksi. Aloittaen kaikkein yksinkertaisimmasta luonnoksesta, meillä on vain kaksi funktiota: void setup ja void loop. Ja kuten ehkä tiedät, void setup suoritetaan vain kerran, ja sitten se luovuttaa esityksen void loopille.
![Arduino void setup loop](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/void_setup_loop_2.png)
Void loop käy sen jälkeen läpi jokaisen koodirivin, joka saattaa olla silmukan sisällä (näiden sulkeiden sisällä).
Se suorittaa ensimmäisen rivin, sitten toisen, sitten kolmannen ja niin edelleen ja niin edelleen, kunnes se pääsee loppuun. Ja sitten se palaa takaisin alkuun.
Miten nopeasti se suorittaa silmukan? Se riippuu siitä, mitä Arduino-korttia käytät, mutta Arduino Unon kellotaajuus on 16 megahertsiä. Se tarkoittaa siis, että Arduinossa tapahtuu 16 miljoonaa ohjetta joka sekunti!
![Arduinon kellonopeus](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/16-Mhz.png)
Jokainen koodirivi ei välttämättä ole yksi ohje. Itse asiassa on todennäköisintä, että se on useita ohjeita. Mutta silti, se on suhteellisen nopeaa (tietokoneesi prosessori toimii todennäköisesti gigahertsin nopeudella… se on miljardeja).
Katsoisitko siis tuota tyhjää luonnosta tiukaksi silmukaksi? Ehdottomasti, se on niin nopea ja tiukka kuin silmukasta voi tehdä. Koska silmukan sisällä ei ole mitään suoritettavaa, sketsin läpikäymiseen kuluva aika on käytännössä nolla. Toisin sanoen väli silmukan alusta loppuun on lyhyt (siksi se on nopea eli ”tiukka”).
Lisätään muutama koodirivi. Käynnistetään sarjaliikenne ja tulostetaan sitten jotain sarjavalvontaikkunaan.
![Arduino tiukka silmukka sarjaliikenne](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/tight_loop.png)
Onko tämä tiukka silmukka? Eli silmukan alusta silmukan loppuun, kestääkö tuo paljon aikaa? Siihen menee hyvin vähän aikaa, joten kyseessä on nopea, tiukka silmukka.
On kuitenkin syytä huomata, että tämä silmukka ei ole yhtä tiukka kuin edellinen esimerkki. Edellisessä esimerkissä meillä ei ollut koodia. Joten se vain ryntäsi silmukan läpi. Nyt kun meillä on tässä funktio, serial print, kestää (vähän) aikaa tulostaa ”Ice Ice Baby” sarjamonitoriin.
Mutta tämä on silti aika nopea silmukka. Lisätään siis hieman lisää koodia. Laitamme ohjelman tarkistamaan, onko nappia painettu, ja jos on, lähetämme sarjamonitoriin jotain uutta
![Arduino tight loop serial monitor with button push](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/tight_loop_2.png)
Olemme siis julistaneet napin ja käyttäneet if-lauseketta tarkistamaan ja katsomaan, onko nappia painettu. Onko jännite nastassa viisi korkea? Jos on, niin tulostamme jotain muuta sarjamonitori-ikkunaan.
Onko tämä tiukka silmukka? Eli silmukan alusta silmukan loppuun, onko se aika nopeaa?
Kyllä, se on silti aika nopeaa. Tämä on aika tiukka silmukka. Meillä on neljä riviä koodia. Tulostamme sarjamonitoriin, ja sitten teemme nopean tarkistuksen, onko painiketta painettu. Ja jos painetaan, tulostamme jotain. Edelleen tiukka, edelleen nopea.
Lisätään seuraavaksi viive tähän ohjelmaan käyttämällä Arduinon delay()-funktiota. Alla näet, että olemme lisänneet silmukkaan tuhannen millisekunnin (1 sekunnin) viiveen.
![Arduinon tiukka silmukka viiveellä](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/tight_loop_3.png)
Onko tämä yhä tiukka silmukka? Onko aika, silmukan alusta silmukan loppuun, paljon aikaa? Ei, tämä ei todellakaan ole tiukka silmukka. Koodi alkaa nopeasti, teemme sarjatulostuksen, mutta sitten pysähdymme juuri tähän viivefunktioon.
Koko ohjelma pysähtyy odottamaan, että tämä viivekoodi loppuu.
Kun Arduino pääsee tälle koodiriville, se on vähän kuin menisi ruokakauppaan. Pääset enintään 12 tuotteen jonoon, mutta sitten edessäsi oleva kaveri ottaa esiin shekkivihkonsa ja alkaa kirjoittaa shekkiä. Tiedät, että joudut olemaan siellä hetken. Sama juttu täällä.
![Kun joku vetää shekin ulos pikavuorossa](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/checkout.png)
Tämä ei siis ole tiukka kierre. Aika silmukan alusta silmukan loppuun on aika merkittävä. Varsinkin verrattuna pariin edelliseen ohjelmaan. Ajan suuruusluokka on valtava.
Nyt mitä olemme yrittäneet tässä osoittaa on se, että koko tämä ajatus tiukoista silmukoista on suhteellinen. Kaikki riippuu sovelluksesta. Jos sinun täytyy tarkistaa anturin tila 10 miljoonasosasekunnin välein, silloin ohjelma, jossa on kolme riviä koodia, ei ehkä ole tarpeeksi tiukka, se vain riippuu.
Toinen seikka on se, että kaikkien koodirivien suorittaminen ei vie yhtä paljon aikaa. Jos kutsut funktiota, joka tekee joukon asioita, kuten esimerkiksi sarjatulostuksen, niin se yksi koodirivi voi kestää paljon kauemmin kuin 10 muuta koodiriviä.
Silmukan tiukkuus on siis suhteellinen ajatus.
![Arduinon silmukan tiukkuus on suhteellista - Einstein](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/The-tightness-of-a-loop-is-relative.png)
Salpaava koodi
Kun ohjelma pysähtyy jossakin vaiheessa ja kestää jonkin aikaa jonkin koodin suorittamiseen, voidaan tuota koodia kutsua estäväksi koodiksi. Tämä on yleinen termi.
Ohjelmassamme viivefunktio toimii estokoodina. Mikään viiveen jälkeinen koodi ei voi suorittaa ennen kuin viive on ohi, joten se estyy.
Blokkaavaa koodia ei kuitenkaan ole vain silloin, kun käytämme funktiota delay().
Viedään ohjelmastamme viive pois, mutta lisätään for-silmukka. For-silmukkamme tulostaa numeroita ja tekstiä sarjaporttiin.
![Arduino tiukka for-silmukka](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/tight_loop_4.png)
Kuinka kauan tämä silmukka kestää? Se pyörii jonkin aikaa, koska sen täytyy käydä läpi 100 iteraatiota ennen kuin se pysähtyy.
Ja entä tämän for-silmukan jälkeinen koodi? Pystyykö se suorittamaan? Ei, sen on odotettava, koska for-silmukka estää sen suorittamisen.
Tämä for-silmukka on sisäkkäin pääsilmukan sisällä. Onko for-silmukka ”tiukka” silmukka? Ennen kuin vastaat, korostetaan vielä kerran, miten sinun pitäisi ajatella asiaa: viekö tämän for-silmukan läpikäyminen ylhäältä alaspäin paljon aikaa?
No, ei oikeastaan. Siinä on vain kaksi riviä koodia. Tämä on siis aika tiukka silmukka.
Mutta se on tiukka silmukka, jonka on käytävä läpi monta iteraatiota ennen kuin ohjelma pääsee sen alapuolella olevaan koodiin. Joten jopa tiukka silmukka, jos se joutuu käymään läpi useita iteraatioita, voi estää koodimme.
Lisää delay()-funktiosta
Puhutaanpa hieman lisää tästä delay-funktiosta. Mitä olemme tähän mennessä todenneet?
Ensin sanoimme, että delay-funktio vähentää silmukan tiukkuutta. Jos sinulla on tiukka silmukka ja lisäät viivefunktion, se vie enemmän aikaa ja tekee siitä vähemmän tiiviin. Eli aika, joka kuluu silmukan alusta loppuun, kasvaa viivefunktion myötä.
Tiedämme myös, että viivefunktio estää koodia. Tämä kulkee käsi kädessä sen kanssa, mitä juuri sanoimme. Kun viivefunktio on käynnissä, se estää muun koodin suorittamisen viiveen aikana.
Voisit ajatella, että tämä viivefunktio on totaalisen löysä! Sillä ei tule koskaan olemaan mitään merkitystä projekteissamme. Mutta monissa kirjoittamissamme yksinkertaisissa ohjelmissa viivefunktio toimii fantastisesti. Sitä on helppo käyttää, se on todella helppo kirjoittaa, ja se tekee juuri sen, mitä se sanoo.
![Arduino-viivytysfunktio on sohvaperuna](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/Is-the-delay-function-a-total-slacker__.png)
Meidän ei siis välttämättä kannata hyljeksiä delay()-funktiota ohjelmointityökalupakistamme. Meidän pitäisi vain tunnustaa, että se on yksinkertainen ohjelmointifunktio, joka voi toimia monissa tapauksissa.
Jossain vaiheessa alkaa kuitenkin tulla ongelmia. Se liittyy estovaikutukseen, joka delay-funktiolla on ohjelmassamme.
Sarjan seuraavalla oppitunnilla, osassa 3, selvitämme, missä tästä todella tulee ongelma. Opit, milloin on järkevää käyttää ohjelmassa delay()-funktiota ja milloin on aika siirtyä käyttämään millis()-funktiota.
Katsaus
Aluksi puhuimme silmukan tiukkuudesta. Sanoimme, että silmukan tiukkuus on suhteellista. Se riippuu sovelluksestasi.
Toiseksi puhuimme estävästä koodista eli koodista, joka estää. Pohjimmiltaan se on yleisnimitys, jonka voimme antaa koodille, jonka suorittaminen kestää jonkin aikaa ja joka pysäyttää ohjelman muiden osien suorittamisen sen suorittamisen ajaksi.
Toivottavasti nautimme tästä oppitunnista! Tämän sarjan seuraavassa osassa jatkamme matkaamme oppimalla, miten millis-funktiota käytetään luomaan ajoitettuja, toistuvia tapahtumia Arduino-koodissamme. Nähdään ensi kerralla!
![Arduinon muinainen resepti inspiroivaan musiikkiin](https://programmingelectronics.com/wp-content/uploads/2019/04/ancient-recipe-gif.gif)