Arduino Zpoždění [Tutorial]

V tomto tutoriálu se naučíte, jak správně používat delay() funkce přidat nějaké zpoždění mezi 2 činnosti v Arduino programy. Pak zjistíte, proč použití delay() často není dobrý nápad, když chcete, aby vaše programy škálovaly, a jak to opravit.

dobře, začněme!

Obsah

Proč potřebujete zpoždění v Arduino programy?

program Arduino se hodně spoléhá na externí vstupy / výstupy.

Vezměme si jednoduchý příklad: možná budete chtít sledovat stav tlačítka 100krát za sekundu nebo každých 0,5 sekundy blikat LED.

jak toho můžete dosáhnout? Programy Arduino fungují takto:

  • nejprve se funkce setup() provede jednou.
  • pak se funkce loop() provádí znovu a znovu, dokud nevypnete Arduino.

jakýkoli program, který napíšete, bude spuštěn plnou rychlostí. Pokud tedy ve svém kódu blikáte LED, stane se to, že LED bude blikat velmi vysokou rychlostí (alespoň několik tisíckrát za sekundu).

učíte se, jak používat Arduino k vytváření vlastních projektů?

podívejte se na Arduino Pro začátečníky a učit se krok za krokem.

pokud chcete řídit čas – to znamená, že se ujistěte, že LED bliká pouze každých 0,5 sekundy a ne při plné rychlosti – je třeba přidat určité zpoždění v kódu.

Prováděcí Arduino zpoždění v kódu

Arduino zpoždění funkce ()

Zde je kód, aby se LED blikat (zde volíme vestavěné LED, není potřeba přidávat žádné externí LED) každých 0,5 sekund – to je jeden z nejběžnějších příkladů uvidíte, když začnete s Arduino.

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

jak tedy tento kód funguje?

První použití „definovat“, takže nemusíte mít pevný kód číslo „13“ se několikrát v kódu, a to dělá váš program čitelnější.

režim pinu nastavíte na výstup pomocí funkce pinMode().

v loop() funkce:

  1. Napájení na LED
  2. Použití delay(500) aby program spát po dobu 500 milisekund, nebo 0,5 sekundy
  3. Power off LED
  4. Použití delay(500), aby se program znovu usnout po dobu 0,5 sekundy
  5. A přejděte zpět na krok 1, protože loop() funkce může být proveden znovu a znovu.

funkce delay() očekává, že budete spát několik milisekund – ne sekund. Takže pokud si myslíte, že v sekundách, vynásobte číslo 1000 a máte hodnotu, kterou potřebujete.

proveďte zpoždění Arduino po dobu 1 minuty

pokud chcete, aby vaše Arduino spalo 1 minutu nebo více minut, pak je to docela snadné.

vezměte počet minut, vynásobte jej 60, abyste získali počet sekund, a poté jej vynásobte 1000, abyste získali počet milisekund.

Ex: delay(3 * 60 * 1000); způsobí, že program bude spát po dobu 3 minut.

funkce Arduino delayMicroseconds ()

pokud potřebujete být přesnější, možná budete muset použít funkci delayMicroseconds(). S delayMicroseconds() můžete poskytnout několik mikrosekund na spánek. Minimální doba trvání delay() je 1 milisekunda, takže pokud potřebujete spát pouze 400 mikrosekund, máte zde nové řešení.

Tato funkce může být velmi užitečná při komunikaci s některými hardwarovými komponentami. Například Arduino potřebuje odeslat některá data do komponenty a poté přečíst nějakou odpověď. Řekněme, že komponenta potřebuje 6 mikrosekund, aby zpracovala požadavek a dodala přesná data.

pak ve vašem programu můžete mít něco takového:

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

Non blokování zpoždění – proč byste se měli vyhnout používání delay()

Tak, teď, že jste pochopili, co je zpoždění v Arduino, a jak to provést s delay() a delayMicroseconds(), pojďme se podívat, jak používat zpoždění funkce – ale bez těchto funkcí.

proč?

při použití delay() se provádění programu zastaví a obnoví se až po dokončení zpoždění.

to je v pořádku, pokud máte k dispozici pouze jednu akci-příklad: blikat jednu LED-ale co když se potřebujete postarat o více hardwarových komponent nebo komunikovat s jinými zařízeními, jako jsou desky Arduino nebo vlastní počítač?

pomocí předchozího příkladu, jak byste mohli udělat jednu LED blikat každých 0,5 sekundy, a další jeden blikat každých 0,8 sekundy?

v takovém případě budete uvíznuti poměrně rychle. Pokud stále chcete používat delay(), můžete najít řešení, kde používáte kratší zpoždění mezi více akcemi, ale to komplikuje váš program pokaždé, když přidáte novou akci.

řešením je jednoduše sledovat čas bez použití funkce delay(), v podstatě najít způsob, jak reprodukovat chování delay() bez použití.

příklad kódu-Arduino delay without delay ()

přepíšeme náš příklad Blink LED bez použití delay().

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

pojďme analyzovat tento kód řádek po řádku.

Inicializace

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

Nejprve inicializovat 3 proměnné v globálním oboru:

  • lastTimeLedBlinked: tato proměnná bude použita k ukládání naposledy VEDL zamrkal. V podstatě pokaždé, když uděláme LED blikat, budeme aktualizovat tuto proměnnou s aktuálním časem – pomocí funkce millis ().
  • delayBetweenBlink: toto je čas, kdy chcete počkat mezi 2 akcemi – zde je akce blikat LED.
  • ledState: budeme muset uložit aktuální stav LED (vysoký nebo nízký), abychom mohli vědět, jaký byl předchozí stav, a podle toho jednat.

proč v globálním měřítku? No, to, co plánujeme udělat, je aktualizovat tyto proměnné ve funkci loop() a znovu k nim přistupovat při příštím vstupu do loop(). Pokud vytvoříme proměnné uvnitř loop(), proměnné budou lokální proměnné, a proto budou zničeny při ukončení funkce loop(). Takže při příštím volání loop() budou všechny hodnoty ztraceny a znovu vytvoříte proměnné bez předchozí hodnoty uvnitř. Zde vytvořením proměnných mimo funkci je můžeme „přežít“ a udržet jejich hodnotu pokaždé, když zadáme loop().

implementace funkce Arduino delay ve funkci smyčky

nyní se podívejme, co se stane ve funkci loop().

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

nejprve si přečtete aktuální čas pomocí funkce millis().

 if (timeNow - lastTimeLedBlinked > delayBetweenBlink) {

a nyní porovnáte aktuální čas, který jste právě četli, s předchozím blikáním LED. Pokud uplynulo dostatek času (více než hodnota uložená v delayBetweenBlink), znamená to, že můžete zadat if().

Této struktury kódu – čtení čas a jeho porovnání s předchozím času jste udělali akci – je, jak nahradit delay() funkce. V podstatě zde jen počítáte dobu trvání. A jak vidíte, znamená to, že váš program obsahuje více řádků pro jednoduchou aplikaci, ale dává vám mnohem větší kontrolu a je mnohem škálovatelnější.

takže, co se stane? No, loop() bude pokračovat v plné rychlosti. Pokaždé, váš program zkontroluje, zda uplynulo dost času. Pokud ne, pak loop() zde končí, protože nevstoupí do struktury if.

a když uplynulo dost času, zadáme if().

Provedení akce

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

OK, právě jsi vstoupil do if() a to, kde budete dělat cokoliv, co je třeba udělat.

zde LED bliká. A protože nemůžeme přímo vědět, jaký byl předchozí stav pro LED (protože jsme mnohokrát vstoupili do loop() a ztratili jsme všechny místní proměnné vytvořené uvnitř), dostaneme tento stav z globální proměnné.

co děláme s touto globální proměnnou, je jednoduché: pokud byla nízká, nastavili jsme ji na vysokou a pokud byla vysoká, nastavili jsme ji na nízkou. A pak samozřejmě aktualizujeme fyzický stav LED odpovídajícím způsobem s digitalWrite().

 lastTimeLedBlinked = timeNow; }}

konečně, a to je velmi důležité, uložíme aktuální čas jako naposledy, kdy jsme blikali LED. Pokud to neuděláme, program bude blikat LED při plné rychlosti, protože stav uvnitř if() bude vždy pravdivý.

nastavením předchozího času na aktuální čas „resetujeme časovač“.

takže v tomto příkladu bude if() zadáno pouze každých 500 milisekund nebo 0,5 sekundy.

A teď to je skvělé, protože svůj program nezastaví, takže můžete i nadále provádět jiné nezávislé činnosti, zatímco je stále „čeká“ blikat LED.

2 akce „současně“

Například řekněme, že chcete blikat LED každých 0.5 sekund a další každých 0,8 sekundy.

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

jak vidíte, opakujeme strukturu kódu pro druhou akci, kterou jsme přidali. A obě akce se nebudou rušit!

Rekapitulace

pokud chcete provést zpoždění Arduino bez použití delay():

  1. Vytvořte globální proměnnou pro uložení naposledy, kdy jste provedli konkrétní akci.
  2. vytvořte další globální proměnnou pro uložení požadované doby trvání mezi 2 akcemi.
  3. ve funkci loop() si přečtěte aktuální čas pomocí millis().
  4. těsně poté použijte strukturu if a použijte podmínku (timeNow - lastTimeActionWasExecuted > delayBetweenActions).
  5. jakmile zadáte if(), proveďte akci.
  6. a stále v if() uložte aktuální čas jako předchozí čas.

tyto kroky můžete opakovat pro každou akci, pro kterou potřebujete zpoždění Arduino.

když je v pořádku použít delay() a delayMicroseconds()

existují určité případy, kdy je použití delay() ve vašem kódu stále v pořádku.

zde jsou 2 z nich:

  • musíte inicializovat součást během instalace programu, a tato komponenta potřebuje nějaký čas k inicializaci – například 1,5 sekundy. V tomto případě je použití delay(1500) ve vaší funkci setup() naprosto v pořádku. V podstatě žádný delay() ve funkci setup() vašeho programu Arduino nebude problém.
  • jak je vysvětleno v části delayMicroseconds(), musíte počkat několik mikrosekund (ne milisekund!) při komunikaci s externí komponentou. Pokud zjistíte, že použití delayMicroseconds() s malým číslem (například 10) neruší zbytek programu, můžete jej stále používat, aniž byste se museli příliš obávat. Ale považujte to za výjimku, ne za běžné pravidlo.

Závěr – Použití Arduino zpoždění() s péčí

Vzhledem k povaze Arduino programy, budete často muset přidat zpoždění v kódu, takže si můžete zvolit, kdy chcete provádět některé akce, a jak často chcete spouštět je.

funkce delay() a delayMicroseconds() jsou velmi jednoduché a byly přidány do jazyka Arduino, aby úplní začátečníci mohli začít s něčím jednoduchým.

nicméně, jak jste viděli v tomto tutoriálu, pomocí delay() můžete uvíznout opravdu rychle. Takže je nejlepší nejprve pochopit, proč ji potřebujete, jak ji používat,a pak jak získat stejné chování bez použití funkce Arduino delay() přímo.

jakmile pochopíte strukturu kódu, abyste se zbavili delay(), budete moci hodně vylepšit své programy Arduino a multitasking bude docela snadný.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.