Arduino Delay [Tutorial]

tässä tutorialissa opit käyttämään delay() – toimintoa oikein lisätäksesi viivettä 2 toiminnon välillä Arduino-ohjelmissasi. Sitten, huomaat, miksi käyttämällä delay() ei usein ole hyvä idea, kun haluat tehdä ohjelmia mittakaavassa,ja miten korjata.

No niin, aloitetaan!

Sisällysluettelo

miksi tarvitset viivästyksiä Arduino-ohjelmissasi?

No, Arduino-ohjelma nojaa paljon ulkoisiin tuloihin/lähtöihin toimiakseen.

yksinkertainen esimerkki: kannattaa tarkkailla painikkeen tilaa 100 kertaa sekunnissa tai tehdä LED-vilkkua 0,5 sekunnin välein.

nyt, miten voit saavuttaa sen? Arduino ohjelmat toimii näin:

  • ensin setup() funktio suoritetaan kerran.
  • sitten loop() funktiota suoritetaan yhä uudelleen, kunnes sammutat arduinosi.

kaikki kirjoittamasi ohjelmat suoritetaan täydellä nopeudella. Joten jos teet LED vilkkua koodin, mitä tulee tapahtumaan on, että LED vilkkuu erittäin suurella nopeudella (useita tuhansia kertoja sekunnissa vähintään).

opetteletko Arduinon käyttöä omien projektien rakentamisessa?

Tutustu Arduinoon aloittelijoille ja opi vaihe vaiheelta.

jos haluat hallita aikaa – eli varmista, että LED vilkkuu vain 0,5 sekunnin välein eikä täydellä nopeudella – sinun on lisättävä viivettä koodiisi.

Arduino-viiveen toteuttaminen koodissa

Arduino-viive () – funktio

tässä koodi LED-välähdyksen tekemiseksi (tässä valitaan sisäänrakennettu LED, ei tarvitse lisätä mitään ulkoista lediä) 0,5 sekunnin välein-tämä on yksi yleisimmistä esimerkeistä, jonka näet, jos aloitat Arduinolla.

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

Joten, miten tämä koodi toimii?

ensin käytetään ”määrittele”-koodia, jotta numeroa ”13” ei tarvitse kovertaa useaan kertaan koodissa ja se tekee ohjelmasta luettavamman.

asetat pin-tilan ulostuloon pinMode() – toiminnolla.

sitten loop() funktiossa Sinä:

  1. teho LEDillä
  2. käytä delay(500) saadaksesi ohjelman nukahtamaan 500 millisekuntia tai 0,5 sekuntia
  3. Sammuta LED
  4. käytä delay(500) saadaksesi ohjelman nukahtamaan uudelleen 0,5 sekuntia
  5. ja palaa vaiheeseen 1, koska loop() funktio suoritetaan jatkuvasti uudelleen.

delay() funktio odottaa sinun antavan uneen useita millisekunteja – ei sekunteja. Joten, jos ajattelet sekunneissa, niin kerro luku 1000: lla ja sinulla on tarvittava arvo.

tee Arduino-viive 1 minuutin ajan

jos haluat saada Arduino-unesi 1 minuutin tai useita minuutteja, se on melko helppoa.

otetaan minuuttimäärä, kerrotaan se 60: llä, jotta saadaan sekuntimäärä, ja sitten kerrotaan se 1000: lla, jotta saadaan millisekuntien määrä.

Ex: delay(3 * 60 * 1000); saa ohjelman nukkumaan 3 minuuttia.

Arduino delayMicroseconds () – funktio

jos haluat olla tarkempi, saatat joutua käyttämään delayMicroseconds() – funktiota. Kun delayMicroseconds() voit antaa useita mikrosekunteja uneen. Vähimmäiskesto delay() on 1 millisekunti, joten jos tarvitset unta vain 400 mikrosekuntia, tässä on uusi ratkaisu.

tämä toiminto voi olla erittäin hyödyllinen kommunikoitaessa joidenkin laitteistokomponenttien kanssa. Esimerkiksi, Arduino täytyy lähettää joitakin tietoja komponentti ja sitten lukea joitakin vastauksia. Sanotaan, että komponentti tarvitsee 6 mikrosekuntia pyynnön käsittelyyn ja tarkkojen tietojen toimittamiseen.

silloin ohjelmassasi voi olla jotain tällaista:

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

Estoton viive – miksi viiveen () käyttöä kannattaa välttää

joten nyt kun ymmärrät mikä on viive Arduinossa, ja miten se toteutetaan delay() ja delayMicroseconds(), katsotaan miten viivetoimintoa käytetään-mutta ilman näitä toimintoja.

miksi?

kun käytät delay(), ohjelmasi suoritus pysähtyy ja jatkuu vasta viiveen päätyttyä.

tämä on OK, jos sinulla on vain yksi toiminto tehtävänä-esimerkki: blink yksi LED – mutta mitä jos sinun täytyy huolehtia useita laitteiston osia tai kommunikoida muiden laitteiden, kuten Arduino levyt tai oman tietokoneen?

edellisen esimerkin avulla, miten yhden LED-valon voisi saada vilkkumaan 0,5 sekunnin välein ja toisen vilkkumaan 0,8 sekunnin välein?

siinä tapauksessa jäät melko nopeasti jumiin. Jos haluat edelleen käyttää delay(), saatat löytää ratkaisun, jossa käytät lyhyempiä viiveitä useiden toimintojen välillä, mutta tämä tekee ohjelmastasi monimutkaisemman aina, kun lisäät uuden toiminnon.

ratkaisu tähän on yksinkertaisesti seurata aikaa käyttämättä delay() funktiota, periaatteessa löytää tapa toistaa delay() käyttäytyminen käyttämättä sitä.

Code example-Arduino delay without delay()

kirjoitetaan Blink LED example ilman 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; }}

analysoidaan tämä koodi rivi riviltä.

alustus

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

ensin alustetaan 3 muuttujaa globaalissa mittakaavassa:

  • lastTimeLedBlinked: tätä muuttujaa käytetään tallentamaan viimeinen kerta, kun LED vilkkui. Periaatteessa joka kerta, kun teemme LED blink, päivitämme tämän muuttujan nykyisen ajan – käyttäen millis () – toimintoa.
  • delayBetweenBlink: tämä on aika, jonka haluat odottaa 2 toiminnon välillä-tässä toiminto on vilkkua LED.
  • ledState: meidän on tallennettava nykyinen LED-tila (korkea tai matala), jotta voimme tietää, mikä oli edellinen tila, ja ryhtyä toimiin sen mukaisesti.

miksi koko maailmassa? No, mitä aiomme tehdä, on päivittää nämä muuttujat funktiossa loop() ja käyttää niitä uudelleen seuraavan kerran, kun menemme loop(): n sisälle. Jos luomme muuttujat loop(): n sisälle, muuttujat ovat paikallisia muuttujia ja siten tuhoutuvat, kun loop() – funktiosta poistuu. Näin ollen seuraavan kerran loop() kutsutaan uudelleen, kaikki arvot menetetään ja luot muuttujia uudelleen ilman aikaisempaa arvoa sisällä. Tässä luomalla funktion ulkopuoliset muuttujat voimme saada ne ”säilymään” ja pitämään arvonsa aina, kun astumme loop().

Arduino-viivetoiminnon toteuttaminen silmukkafunktiossa

nyt katsotaan, mitä tapahtuu loop() – funktiossa.

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

ensin luetaan nykyinen aika funktiolla millis().

 if (timeNow - lastTimeLedBlinked > delayBetweenBlink) {

ja nyt vertaat juuri lukemaasi ajankohtaa, edellisen kerran LED vilkkui. Jos aikaa on kulunut tarpeeksi (enemmän kuin delaybetweenblinkiin tallennettu arvo), niin se tarkoittaa, että voit syöttää if().

tämä koodirakenne-ajan lukeminen ja sen vertaaminen edelliseen toimintoon-korvaa delay() funktion. Lasket vain kestoa. Ja kuten näette, se tarkoittaa, että ohjelma sisältää enemmän rivejä yksinkertaiselle sovellukselle, mutta se antaa sinulle paljon enemmän hallintaa ja se on paljon skaalautuvampi.

niin, mitä tapahtuu? loop() tulee jatkumaan täydellä vauhdilla. Joka kerta, Ohjelma tarkistaa, jos tarpeeksi aikaa on kulunut. Jos ei, niin loop() päättyy tähän, koska se ei tule if-rakenteeseen.

ja kun aikaa on kulunut juuri tarpeeksi, astutaan if().

toimeenpano

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

OK, olet juuri tullut if(): iin, ja tässä teet kaiken tarvittavan.

tässä tehdään LED-välähdys. Ja koska emme voi suoraan tietää, mikä oli LED: n edellinen tila (koska olemme tulleet loop() monta kertaa ja kadottaneet kaikki sisällä luodut paikalliset muuttujat), saamme kyseisen tilan globaalista muuttujasta.

se, mitä teemme tällä globaalilla muuttujalla, on yksinkertaista: jos se oli alhainen, asetimme sen korkeaksi, ja jos se oli korkea, asetimme sen matalaksi. Ja sitten tietysti päivitämme fyysisen LED-tilan sen mukaisesti, jossa on digitalWrite().

 lastTimeLedBlinked = timeNow; }}

vihdoin, ja tämä on supertärkeää, säästämme nykyisen ajan, kun viimeksi vilautimme lediä. Jos näin ei tehdä, ohjelma räpäyttää lediä täydellä vauhdilla, koska if(): n sisällä oleva kunto pitää aina paikkansa.

asettamalla edellisen kerran nykyiseen aikaan ”nollaamme ajastimen”.

joten tässä esimerkissä if() merkitään vain 500 millisekunnin eli 0,5 sekunnin välein.

ja nyt tämä on hienoa, koska ohjelma ei pysähdy, joten voit jatkaa erilaisten itsenäisten toimintojen suorittamista samalla kun ”odotat” ledin räpäyttämistä.

2 toimintoa ”samaan aikaan”

esimerkiksi sanotaan, että haluat räpäyttää lediä joka 0.5 sekuntia ja toinen 0,8 sekunnin välein.

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

kuten näette, toistamme koodirakenteen toiselle lisätylle toiminnolle. Ja molemmat teot eivät häiritse toisiaan!

Recap

jos haluat tehdä Arduino-viiveen käyttämättä delay():

  1. luo globaali muuttuja tallentaa viimeksi teit tietyn toiminnon.
  2. luo toinen globaali muuttuja tallentaaksesi haluamasi keston kahden toiminnon välille.
  3. loop() funktiossa luetaan nykyinen aika millis().
  4. heti sen jälkeen käytetään if-rakennetta ja käytetään ehtoa (timeNow - lastTimeActionWasExecuted > delayBetweenActions).
  5. kun olet astunut if(), toimi.
  6. ja edelleen if(), säilytä nykyinen aika kuten edellinen kerta.

voit toistaa nämä vaiheet jokaisesta toimenpiteestä, johon tarvitset Arduino-viiveen.

kun on ok käyttää viivettä () ja viivemikrosekuntia ()

on tiettyjä tilanteita, jolloin delay() käyttäminen koodissa on edelleen OK.

tässä on 2 näistä:

  • sinun täytyy alustaa komponentti ohjelman asennuksen aikana, ja tämä komponentti tarvitsee jonkin aikaa alustamiseen – esimerkiksi 1,5 sekuntia. Tällöin delay(1500) käyttäminen setup() funktiossa on täysin ok. Periaatteessa mikä tahansa delay() Arduino-ohjelmasi setup() funktiossa ei ole ongelma.
  • kuten delayMicroseconds() – osassa selitettiin, sinun täytyy odottaa muutama mikrosekunti (ei millisekunteja!) kommunikoidessaan ulkoisen komponentin kanssa. Jos huomaat, että delayMicroseconds() käyttäminen pienellä numerolla (esimerkiksi 10) ei häiritse ohjelman muita osia, voit silti käyttää sitä ilman, että sinun tarvitsee huolehtia liikaa. Mutta pidä sitä poikkeuksena, ei yleisenä sääntönä.

johtopäätös-käytä Arduino-viivettä() varoen

Arduino-ohjelmien luonteen vuoksi sinun täytyy usein lisätä viiveitä koodiisi, jotta voit valita, milloin haluat suorittaa joitakin toimintoja ja kuinka usein haluat suorittaa ne.

delay() ja delayMicroseconds() funktiot ovat hyvin yksinkertaisia funktioita, ja ne lisättiin Arduinon kieleen, jotta täydelliset aloittelijat voisivat aloittaa jostakin yksinkertaisesta.

kuitenkin, kuten näit tässä opetusohjelmassa, delay() käyttäminen voi saada sinut jumittumaan todella nopeasti. Joten, on parasta ensin ymmärtää, miksi tarvitset sitä, miten sitä käytetään,ja sitten miten saada sama käyttäytyminen käyttämättä Arduino delay() funktiota suoraan.

kun olet ymmärtänyt koodirakenteen päästäksesi eroon delay(): stä, voit parantaa Arduino-ohjelmiasi paljon, ja multitaskingista tulee melko helppoa.

Vastaa

Sähköpostiosoitettasi ei julkaista.