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?
- Arduino-viiveen toteuttaminen koodissa
- Arduino-viive () – funktio
- tee Arduino-viive 1 minuutin ajan
- Arduino delayMicroseconds () – funktio
- Estoton viive – miksi viiveen () käyttöä kannattaa välttää
- Code example-Arduino delay without delay()
- alustus
- Arduino-viivetoiminnon toteuttaminen silmukkafunktiossa
- toimeenpano
- 2 toimintoa ”samaan aikaan”
- Recap
- kun on ok käyttää viivettä () ja viivemikrosekuntia ()
- johtopäätös-käytä Arduino-viivettä() varoen
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ä:
- teho LEDillä
- käytä
delay(500)
saadaksesi ohjelman nukahtamaan 500 millisekuntia tai 0,5 sekuntia - Sammuta LED
- käytä
delay(500)
saadaksesi ohjelman nukahtamaan uudelleen 0,5 sekuntia - 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()
:
- luo globaali muuttuja tallentaa viimeksi teit tietyn toiminnon.
- luo toinen globaali muuttuja tallentaaksesi haluamasi keston kahden toiminnon välille.
-
loop()
funktiossa luetaan nykyinen aikamillis()
. - heti sen jälkeen käytetään if-rakennetta ja käytetään ehtoa
(timeNow - lastTimeActionWasExecuted > delayBetweenActions)
. - kun olet astunut
if()
, toimi. - 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äminensetup()
funktiossa on täysin ok. Periaatteessa mikä tahansadelay()
Arduino-ohjelmasisetup()
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.