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?
- az Arduino késleltetés végrehajtása a kódban
- az Arduino delay () funkció
- Készítsen Arduino késleltetést 1 percig
- az Arduino delayMicroseconds() függvény
- nem blokkoló késleltetés – miért érdemes elkerülni a delay () használatát
- Kód példa – Arduino késleltetés késedelem nélkül()
- inicializálás
- az Arduino késleltetési funkció végrehajtása a hurokfunkcióban
- a művelet végrehajtása
- 2 műveletek “ugyanabban az időben”
- összefoglaló
- amikor rendben van a delay() és a delayMicroseconds () használata
- következtetés – óvatosan használja az Arduino delay () – t
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:
- kapcsolja be a LED-et
- a
delay(500)
használatával 500 milliszekundumig vagy 0,5 másodpercig alvó üzemmódba állíthatja a programot - kapcsolja ki a LED-et
- használja a
delay(500)
lehetőséget, hogy a program 0,5 másodpercig újra alvó üzemmódba lépjen - é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()
:
- hozzon létre egy globális változót, amely tárolja az utolsó műveletet.
- 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.
- a
loop()
függvényben olvassa el az aktuális időt amillis()
gombbal. - közvetlenül ezután használjon if struktúrát, és használja a
(timeNow - lastTimeActionWasExecuted > delayBetweenActions)
feltételt. - miután beírta a
if()
értéket, hajtsa végre a műveletet. - é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 asetup()
függvényben teljesen rendben van. Alapvetően bármelydelay()
az Arduino programsetup()
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 adelayMicroseconds()
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.