Arduino Delay [Tutorial]

ebben az oktatóanyagban megtudhatja, hogyan kell megfelelően használni a delay() funkciót, hogy adjunk némi késleltetést 2 művelet között az Arduino programokban. Ezután rájössz, hogy a delay() használata gyakran nem jó ötlet, amikor a programokat méretezni szeretné, és hogyan lehet ezt kijavítani.

rendben, kezdjük!

Tartalomjegyzék

miért van szüksége késésekre az Arduino programokban?

Nos, egy Arduino program sokat támaszkodik a külső bemenetekre/kimenetekre.

Vegyünk egy egyszerű példát: érdemes figyelni a nyomógomb állapotát másodpercenként 100-szor, vagy 0,5 másodpercenként LED-et villogni.

most, hogyan lehet elérni, hogy? Az Arduino programok így működnek:

  • először a setup() függvény egyszer kerül végrehajtásra.
  • ezután a loop() funkció újra és újra végrehajtásra kerül, amíg ki nem kapcsolja az Arduino-t.

Minden program, amit írsz, teljes sebességgel lesz végrehajtva. Tehát, ha LED-et villogtat a kódjában, akkor az fog történni, hogy a LED nagyon nagy sebességgel villog (legalább másodpercenként több ezer alkalommal).

megtanulod, hogyan kell használni az Arduino-t saját projektek készítéséhez?

nézd meg az Arduino-t kezdőknek és tanulj lépésről lépésre.

ha ellenőrizni szeretné az időt – Vagyis győződjön meg arról, hogy a LED csak 0,5 másodpercenként villog, nem pedig teljes sebességgel -, akkor hozzá kell adnia némi késleltetést a kódban.

az Arduino késleltetés végrehajtása a kódban

az Arduino delay () funkció

itt van egy kód, amellyel LED villog (itt választjuk a beépített LED-et, nincs szükség külső LED hozzáadására) 0,5 másodpercenként – ez az egyik leggyakoribb példa, amelyet látni fog, ha Arduino-val kezdi.

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

Szóval, hogyan működik ez a kód?

először egy “define”-t használsz, így nem kell többször kódolnod a “13” számot a kódban, és ez olvashatóbbá teszi a programot.

a pin-kód módját a pinMode() funkcióval állíthatja be.

ezután a loop() függvényben:

  1. kapcsolja be a LED-et
  2. a delay(500) használatával 500 milliszekundumig vagy 0,5 másodpercig alvó üzemmódba állíthatja a programot
  3. kapcsolja ki a LED-et
  4. használja a delay(500) lehetőséget, hogy a program 0,5 másodpercig újra alvó üzemmódba lépjen
  5. és térjen vissza az 1.lépéshez, mert a loop() funkció újra és újra végrehajtásra kerül.

a delay() függvény arra számít, hogy több milliszekundumot – nem másodpercet – ad az alváshoz. Tehát, ha másodpercek alatt gondolkodik, akkor szorozza meg a számot 1000-rel, és megkapja a szükséges értéket.

Készítsen Arduino késleltetést 1 percig

ha azt szeretné, hogy az Arduino 1 percig vagy több percig aludjon, akkor ez nagyon egyszerű.

vegye ki a percek számát, szorozza meg 60-mal, hogy megkapja a másodpercek számát, majd szorozza meg 1000-rel, hogy megkapja az ezredmásodpercek számát.

például: delay(3 * 60 * 1000); a program 3 percig alszik.

az Arduino delayMicroseconds() függvény

ha pontosabbnak kell lennie, akkor a delayMicroseconds() függvényt kell használnia. A delayMicroseconds() segítségével számos mikroszekundumot biztosíthat az alváshoz. A delay() minimális időtartama 1 milliszekundum, tehát ha csak 400 mikroszekundumot kell aludnia, itt van egy új megoldás.

ez a funkció nagyon hasznos lehet egyes hardverkomponensekkel való kommunikáció során. Például az Arduino – nak el kell küldenie néhány adatot az összetevőnek, majd el kell olvasnia néhány választ. Tegyük fel, hogy a komponensnek 6 mikroszekundumra van szüksége a kérés feldolgozásához és a pontos adatok szolgáltatásához.

akkor a programban lehet valami ilyesmi:

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

nem blokkoló késleltetés – miért érdemes elkerülni a delay () használatát

tehát most, hogy megértette, mi a késleltetés az Arduino – ban, és hogyan kell végrehajtani a delay() és delayMicroseconds() használatával, nézzük meg, hogyan kell használni a delay funkciót-de ezek nélkül a funkciók nélkül.

miért?

a delay() használatakor a program végrehajtása leáll, és csak a késleltetés befejezése után folytatódik.

ez rendben van, ha csak egy műveletet kell tennie – példa: villogjon egyetlen LED – et-de mi van, ha több hardverkomponensről kell gondoskodnia, vagy kommunikálnia kell más eszközökkel, például Arduino táblákkal vagy saját számítógépével?

az előző példa segítségével hogyan lehet egy LED-et villogni 0,5 másodpercenként,egy másikat pedig 0,8 másodpercenként?

ebben az esetben elég gyorsan elakad. Ha továbbra is használni szeretné a delay() értéket, találhat olyan megoldást, ahol rövidebb késéseket használ több művelet között, de ez minden alkalommal bonyolultabbá teszi a programot, amikor új műveletet ad hozzá.

erre a megoldás egyszerűen az idő monitorozása a delay() függvény használata nélkül, alapvetően a delay() viselkedésének reprodukálásának módja annak használata nélkül.

Kód példa – Arduino késleltetés késedelem nélkül()

írjuk át a blink LED példát a delay() használata nélkül.

#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; }}

elemezzük ezt a kódot soronként.

inicializálás

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

először 3 változót inicializáljon a globális hatókörben:

  • lastTimeLedBlinked: ez a változó a LED utolsó villogásának tárolására szolgál. Alapvetően minden alkalommal, amikor a LED villog, frissítjük ezt a változót az aktuális idővel – a millis() függvény használatával.
  • delayBetweenBlink: ez az az idő, amikor 2 művelet között várni kell – itt a művelet a LED villogása.
  • ledState: meg kell tárolnunk az aktuális LED állapotát (magas vagy alacsony), hogy tudjuk, mi volt az előző állapot, és ennek megfelelően cselekedjünk.

miért a globális hatókörben? Nos, azt tervezzük, hogy frissítjük ezeket a változókat a loop()függvényben, és újra elérjük őket, amikor legközelebb belépünk a loop() – ba. Ha létrehozzuk a változókat a loop() – on belül, akkor a változók helyi változók lesznek, így megsemmisülnek, amikor kilép a loop() függvényből. Így a loop() következő meghívásakor az összes érték elvész, és ismét olyan változókat hoz létre, amelyekben nincs korábbi érték. Itt a függvényen kívüli változók létrehozásával “túlélhetővé” tehetjük őket, és megtarthatjuk értéküket minden alkalommal, amikor belépünk a loop() – ba.

az Arduino késleltetési funkció végrehajtása a hurokfunkcióban

most nézzük meg, mi történik a loop() függvényben.

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

először olvassa el az aktuális időt a millis() funkcióval.

 if (timeNow - lastTimeLedBlinked > delayBetweenBlink) {

és most összehasonlítja az éppen olvasott aktuális időt az előző alkalommal, amikor a LED villogott. Ha elegendő idő telt el (több, mint a delayBetweenBlink-ben tárolt érték), akkor azt jelenti, hogy beírhatja a if()értéket.

ez a kódszerkezet – az idő leolvasása és összehasonlítása az előző művelettel – a delay() függvény helyettesítésére szolgál. Alapvetően csak egy időtartamot számítasz itt. És mint látható, ez azt jelenti, hogy a program több sort tartalmaz egy egyszerű alkalmazáshoz, de sokkal több irányítást biztosít, és sokkal skálázhatóbb.

Szóval, mi fog történni? Nos, a loop() továbbra is teljes sebességgel hajtódik végre. A program minden alkalommal ellenőrzi, hogy eltelt-e elegendő idő. Ha nem, akkor a loop() itt ér véget, mert nem lép be az if struktúrába.

és ha éppen elég idő telt el, beírjuk a if()értéket.

a művelet végrehajtása

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

OK, most lépett be a if(), és ez, ahol meg fogja tenni, amit meg kell tennie.

itt a LED villog. És mivel közvetlenül nem tudjuk, mi volt a LED előző állapota (mivel sokszor beírtuk a loop() értéket, és elvesztettük az összes benne létrehozott helyi változót), ezt az állapotot egy globális változóból kapjuk.

amit ezzel a globális változóval csinálunk, az egyszerű: ha alacsony volt, akkor magasra állítottuk, ha pedig magas volt, akkor alacsonyra állítottuk. Ezután természetesen frissítjük a fizikai LED állapotot, digitalWrite() – vel.

 lastTimeLedBlinked = timeNow; }}

Végül, és ez nagyon fontos, elmentjük az aktuális időt, amikor utoljára villogtunk a LED-en. Ha ezt nem tesszük meg, akkor a program teljes sebességgel villog a LED-en, mert a if() belsejében lévő állapot mindig igaz lesz.

az előző idő aktuális időre történő beállításával “visszaállítjuk az időzítőt”.

tehát ebben a példában a if() csak 500 milliszekundumonként vagy 0,5 másodpercenként kerül beírásra.

és most ez nagyszerű, mert a program nem áll le, így továbbra is különböző független műveleteket hajthat végre, miközben továbbra is “várakozik” a LED villogására.

2 műveletek “ugyanabban az időben”

tegyük fel például, hogy minden 0-ban villogni szeretne egy LED-et.5 másodperc, és 0,8 másodpercenként egy.

#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; }}

mint látható, megismételjük a második hozzáadott művelet kódszerkezetét. És mindkét akció nem zavarja egymást!

összefoglaló

ha azt szeretnénk, hogy egy Arduino késleltetés használata nélkül delay():

  1. hozzon létre egy globális változót, amely tárolja az utolsó műveletet.
  2. hozzon létre egy másik globális változót a kívánt időtartam tárolásához 2 művelet között.
  3. a loop()függvényben olvassa el az aktuális időt a millis() gombbal.
  4. közvetlenül ezután használjon if struktúrát, és használja a (timeNow - lastTimeActionWasExecuted > delayBetweenActions) feltételt.
  5. miután beírta a if() értéket, hajtsa végre a műveletet.
  6. és még mindig a if(), tárolja az aktuális időt, mint az előző alkalommal.

ezeket a lépéseket megismételheti minden olyan műveletnél, amelyhez Arduino késleltetésre van szüksége.

amikor rendben van a delay() és a delayMicroseconds () használata

vannak olyan esetek, amikor a delay() használata a kódban még mindig rendben van.

itt vannak 2 azok közül:

  • a program beállítása során inicializálnia kell egy összetevőt, és ennek az összetevőnek némi időre van szüksége az inicializáláshoz – például 1,5 másodpercre. Ebben az esetben a delay(1500) használata a setup() függvényben teljesen rendben van. Alapvetően bármely delay() az Arduino program setup() funkciójában nem jelent problémát.
  • amint azt a delayMicroseconds() részben kifejtettük, néhány mikroszekundumot kell várni (nem milliszekundum!) külső komponenssel való kommunikáció során. Ha úgy találja, hogy a delayMicroseconds() használata kis számmal (például 10) nem zavarja a program többi részét, akkor is használhatja anélkül, hogy túl sokat kellene aggódnia. De tekintsd kivételnek, nem pedig a közös szabálynak.

következtetés – óvatosan használja az Arduino delay () – t

az Arduino programok jellege miatt gyakran késéseket kell hozzáadnia a kódban, így kiválaszthatja, hogy mikor hajtson végre néhány műveletet, és milyen gyakran szeretné végrehajtani őket.

a delay() és delayMicroseconds() funkciók nagyon egyszerű funkciókat használni, és adunk az Arduino nyelvet, hogy teljesen kezdők is kezdeni valami egyszerű.

amint azonban ebben az oktatóanyagban látta, a delay() használata nagyon gyorsan elakadhat. Tehát a legjobb, ha először megértjük, miért van szüksége rá, hogyan kell használni, majd hogyan lehet ugyanazt a viselkedést elérni az Arduino delay() funkció közvetlen használata nélkül.

miután megértette a kódszerkezetet, hogy megszabaduljon a delay() – tól, sokat javíthatja az Arduino programjait, és a multitasking meglehetősen egyszerűvé válik.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.