- Mikä on moniajo?
- Miksi ohittaa viive () Arduinossa?
- Miksi käyttää millis ()?
- Tarvittavat komponentit
- Piirikaavio
- Arduino UNO: n ohjelmointi moniajoa varten
Moniajo on johtanut tietokoneiden vallankumouksen, jossa yksi tai useampia ohjelmia voidaan käyttää samanaikaisesti mikä lisää tehokkuutta, joustavuutta, sopeutumiskykyä ja tuottavuutta. Sulautetuissa järjestelmissä mikro-ohjaimet voivat myös hoitaa moniajoa ja suorittaa kaksi tai useampia tehtäviä samanaikaisesti pysäyttämättä nykyisiä ohjeita.
Täällä opetusohjelmassa me opimme miten Arduino esiintyy Moniajo kanssa Arduino MILLIS toiminnolla. Yleensä delay () -toimintoa käytetään Arduinossa jaksolliseen tehtävään, kuten LED-merkkivalo vilkkuu, mutta tämä delay () -toiminto pysäyttää ohjelman tietyn lopullisen ajan eikä salli muiden toimintojen suorittamista. Joten tässä artikkelissa kerrotaan, miten voimme välttää delay () -toiminnon käytön ja korvata sen millisillä (), jos haluat suorittaa useamman kuin yhden tehtävän samanaikaisesti ja tehdä Arduinosta moniajo-ohjaimen. Ennen kuin menemme yksityiskohtiin, aloitetaan aliarvioimalla moniajoa.
Mikä on moniajo?
Moniajo tarkoittaa yksinkertaisesti useamman kuin yhden tehtävän tai ohjelman suorittamista samanaikaisesti samanaikaisesti. Lähes kaikissa käyttöjärjestelmissä on moniajo. Tällaiset käyttöjärjestelmät tunnetaan nimellä MOS (moniajo-käyttöjärjestelmä). MOS voi olla mobiili- tai pöytätietokoneen käyttöjärjestelmä. Hyvä esimerkki tietokoneiden moniajoista on, kun käyttäjät käyttävät samanaikaisesti sähköpostisovellusta, Internet-selainta, mediasoitinta, pelejä ja jos käyttäjät eivät halua käyttää sitä taustalla toimivaa sovellusta, ellei niitä ole suljettu. Loppukäyttäjä käyttää kaikkia näitä sovelluksia samanaikaisesti, mutta käyttöjärjestelmä ottaa tämän käsitteen hieman erilaiseksi. Keskustellaan siitä, kuinka käyttöjärjestelmä hallitsee moniajoa.
Kuten kuvasta näkyy, keskusyksikkö jakaa ajan kolmessa yhtä suuressa osassa ja määrittää jokaisen osan jokaiselle tehtävälle / sovellukselle. Tällä tavoin moniajo suoritetaan useimmissa järjestelmissä. Konsepti on lähes sama Arduino Multitaskingille, paitsi että ajanjako on hieman erilainen. Koska Arduino toimii matalalla taajuudella ja RAM-muistilla verrattuna kannettavaan tietokoneeseen / mobiililaitteeseen / tietokoneeseen, myös jokaiselle tehtävälle annettu aika on erilainen. Arduinolla on myös delay () -toiminto, jota käytetään laajasti. Mutta ennen aloittamista keskustellaan siitä, miksi meidän ei pitäisi käyttää delay () -toimintoa missään projektissa.
Miksi ohittaa viive () Arduinossa?
Jos Arduinon viiteasiakirjat otetaan huomioon, viivetoimintoja on kahden tyyppisiä, ensimmäinen on delay () ja toinen delayMicroseconds (). Molemmat toiminnot ovat identtisiä viiveen muodostamisen kannalta. Ainoa ero on, että delay () -funktiossa välitetty parametrin kokonaisluku on millisekunteissa, ts. Jos kirjoitamme viive (1000), viive on 1000 millisekuntia eli 1 sekunti. Vastaavasti delayMicroseconds () -toiminnossa välitetty parametri on mikrosekunnissa, ts. Jos kirjoitamme delayMicroseconds (1000), viive on 1000 mikrosekuntia eli 1 millisekuntia.
Tässä tulee kohta, molemmat toiminnot keskeyttävät ohjelman viivetoiminnossa kuluneen ajan. Joten jos annamme 1 sekunnin viiveen, prosessori ei voi siirtyä seuraavaan ohjeeseen ennen kuin 1 sekunti on kulunut. Vastaavasti, jos viive on 10 sekuntia, ohjelma pysähtyy 10 sekunniksi ja prosessori ei salli seuraavien ohjeiden suorittamista ennen kuin 10 sekuntia on kulunut. Tämä haittaa mikro-ohjaimen suorituskykyä nopeuden ja ohjeiden suorittamisen suhteen.
Paras esimerkki viivetoiminnon haittojen selittämisestä on kahden painikkeen käyttö. Harkitse, että haluamme vaihtaa kaksi LEDiä kahdella painikkeella. Joten jos yhtä painonappia painetaan, vastaavan LED-valon tulisi palaa 2 sekunnin ajan, vastaavasti, jos sekuntia painetaan, LEDin pitäisi palaa 4 sekunnin ajan. Mutta kun käytämme viivettä (), jos käyttäjä painaa ensimmäistä painiketta, ohjelma pysähtyy 2 sekunniksi ja jos käyttäjä painaa toista painiketta ennen 2 sekunnin viivettä, mikro-ohjain ei hyväksy syötettä, koska ohjelma on pysähtyneessä vaiheessa.
Arduinon virallisessa dokumentaatiossa se mainitaan selvästi huomautuksissa ja varoituksissa viiveestä (). Voit käydä läpi ja tarkistaa tämän, jotta se olisi selkeämpi.
Miksi käyttää millis ()?
Viiveen aiheuttaman ongelman voittamiseksi kehittäjän tulisi käyttää millis () -funktiota, jota on helppo käyttää, kun sinusta tulee tavallinen, ja se käyttää 100%: n suorittimen suorituskykyä aiheuttamatta viivettä komentojen suorittamisessa. millis () on funktio, joka palauttaa vain millisekuntien määrän, joka on kulunut siitä lähtien, kun Arduino-kortti aloitti nykyisen ohjelman suorittamisen jäädyttämättä ohjelmaa. Tämä aikanumero ylittyy (ts. Palaa nollaan) noin 50 päivän kuluttua.
Aivan kuten Arduinolla on delayMicroseconds (), sillä on myös millis () -mikroversio mikroina (). Mikrosolujen ja millien ero on se, että mikrot () täyttyvät noin 70 minuutin kuluttua verrattuna millis (50) päiviin. Joten sovelluksesta riippuen voit käyttää millis () tai micros ().
Millien () käyttäminen viiveen () sijaan:
Millien () käyttämiseksi ajastukseen ja viiveeseen on kirjattava ja tallennettava aika, jona toiminto tapahtui, ajan aloittamiseksi ja tarkistettava sitten välein, onko määritetty aika kulunut. Joten kuten todettiin, tallenna nykyinen aika muuttujaan.
allekirjoittamaton pitkä virtaMillis = millis ();
Tarvitsemme vielä kaksi muuttujaa saadaksesi selville, onko vaadittu aika kulunut. Olemme tallentaneet nykyisen ajankohta currentMillis- muuttujaan, mutta meidän on myös tiedettävä, milloin ajanjakso alkoi ja kuinka kauan jakso on. Joten intervalli ja edellinenMillis ilmoitetaan. Aikaväli kertoo meille aikaviiveen ja previosMillis tallentaa viimeisen kerran tapahtuman tapahtuneen.
allekirjoittamaton pitkä edellinenMillis; allekirjoittamaton pitkä jakso = 1000;
Tämän ymmärtämiseksi ottakaamme esimerkki yksinkertaisesta vilkkuvasta LEDistä. Piste = 1000 kertoo meille, että LED vilkkuu yhden sekunnin tai 1000 ms.
const int ledPin = 4; // kytketty LED-tappi numero ledState = LOW; // käytetään asettamaan LED-tila allekirjoittamaton pitkä edellinenMillis = 0; // tallentaa viimeisen kerran, kun LED vilkkuu const pitkä jakso = 1000; // ajanjakso, jona vilkkuu ms void setup () { pinMode (ledPin, OUTPUT); // aseta ledpin lähtöön } void loop () { unsigned long currentMillis = millis (); // tallenna nykyinen aika if (currentMillis - previousMillis> = ajanjakso) {// tarkista onko 1000ms kulunut edellisenMillis = currentMillis; // tallenna viimeinen LED-merkkivalon vilkkumistapa, jos (ledState == LOW) {// jos LED ei pala, sytytä se ja päinvastoin ledState = HIGH; } else { ledState = LOW; } digitalWrite (ledPin, ledState); // aseta ledState-merkkivalo uudelleen vilkkumaan } }
Tässä lausunto
Arduinon keskeytykset toimivat samalla tavalla kuin muissa mikrokontrollereissa. Arduino UNO -taulussa on kaksi erillistä nastaa keskeytysten kiinnittämiseen GPIO-nastoihin 2 ja 3. Olemme käsitelleet sitä yksityiskohtaisesti Arduino-keskeytysoppaassa, jossa voit oppia lisää keskeytyksistä ja niiden käytöstä.
Tässä näytetään Arduino Multitasking käsittelemällä kahta tehtävää samanaikaisesti. Tehtävät sisältävät kahden LED-valon vilkkumisen eri aikaviiveellä sekä painikkeen, jota käytetään LED: n ON / OFF-tilan ohjaamiseen. Joten kolme tehtävää suoritetaan samanaikaisesti.
Tarvittavat komponentit
- Arduino UNO
- Kolme LEDiä (kaikki värit)
- Vastukset (470, 10k)
- Neulepuserot
- Leipälauta
Piirikaavio
Piirikaavio Arduino Millis () -tuotannon käytön osoittamiseksi on erittäin helppoa, eikä siinä ole paljon kiinnitettäviä komponentteja, kuten alla on esitetty.
Arduino UNO: n ohjelmointi moniajoa varten
Arduino UNO: n ohjelmoiminen moniajoihin vaatii vain edellä selitetyn logiikan millis (): n toiminnasta. On suositeltavaa harjoitella vilkkuvaa LEDiä millisillä uudestaan ja uudestaan, jotta logiikka olisi selkeä ja tuntisit olosi mukavaksi millien () kanssa, ennen kuin aloitat Arduino UNO: n ohjelmoinnin moniajoihin. Tässä opetusohjelmassa keskeytystä käytetään myös millis (): n kanssa samanaikaisesti moniajoissa. Painike on keskeytys. Joten aina kun keskeytys syntyy eli painetaan painiketta, LED vaihtaa ON- tai OFF-tilaan.Ohjelmointi alkaa ilmoittamalla pin-numerot, joihin LEDit ja painike on kytketty.
int led1 = 6; int led2 = 7; int toggleLed = 5; int-painike = 2;
Seuraavaksi kirjoitamme muuttujan LEDien tilan tallentamiseksi tulevaa käyttöä varten.
int ledState1 = MATALA; int ledState2 = MATALA;
Aivan kuten yllä vilkkuesimerkissä selitettiin, jakson ja edellisen miljoonan muuttujien ilmoitetaan vertaavan ja generoivan viiveitä LEDeille. Ensimmäinen LED vilkkuu sekunnin välein ja toinen LED vilkkuu 200 ms kuluttua.
allekirjoittamaton pitkä edellinenMillis1 = 0; const pitkä jakso1 = 1000; allekirjoittamaton pitkä edellinenMillis2 = 0; const pitkä jakso2 = 200;
Toista millis-toimintoa käytetään tuottamaan poistumisviive, jotta vältetään painikkeen moninkertaiset painallukset. Tulee olemaan samanlainen lähestymistapa kuin edellä.
int debouncePeriod = 20; int debounceMillis = 0;
Näitä kolmea muuttujaa käytetään painikkeen tilan tallentamiseen keskeytykseksi, LED-valinnan vaihtamiseksi ja painikkeen tilaksi.
bool buttonPushed = false; int ledChange = LOW; int lastState = KORKEA;
Määritä tapin toiminta siitä, mikä tappi toimii INPUT tai OUTPUT.
pinMode (led1, OUTPUT); pinMode (led2, OUTPUT); pinMode (toggleLed, OUTPUT); pinMode (painonappi, INPUT);
Määritä nyt keskeytystappi liittämällä keskeytys ISR: n ja keskeytystilan määrittelyyn. Huomaa, että on suositeltavaa käyttää digitalPinToInterrupt (pin_number) julistaessaan attachInterrupt () funktio kääntää todellinen digitaalinen pin tietyn keskeytyksen numeron.
attachInterrupt (digitalPinToInterrupt (pushButton), pushButton_ISR, CHANGE);
Keskeytys-aliohjelma on kirjoitettu ja se muuttaa vain buttonPushed- lippua. Huomaa, että keskeytysalirutiinin on oltava mahdollisimman lyhyt, joten yritä kirjoittaa se ja minimoida ylimääräiset ohjeet.
void pushButton_ISR () { buttonPushed = true; }
Silmukka alkaa millis-arvon tallentamisesta currentMillis-muuttujaan, joka tallentaa kuluneen ajan arvon joka kerta, kun silmukka toistaa.
allekirjoittamaton pitkä virtaMillis = millis ();
Monitoimityössä on kaikkiaan kolme toimintoa, vilkaise yksi LED sekunnissa, Vilkuta toinen LED 200 ms: ssä ja jos painetaan painiketta, kytke sitten OFF / ON LED-valo päälle. Joten kirjoitamme kolme osaa tämän tehtävän suorittamiseksi.
Ensimmäinen on vaihtaa LED tila jälkeen 1 sekunnin välein vertaamalla Millis kulunut.
if (currentMillis - edellinenMillis1> = jakso1) { previousMillis1 = currentMillis; if (ledState1 == LOW) { ledState1 = KORKEA; } else { ledState1 = LOW; } digitalWrite (led1, ledState1); }
Vastaavasti toiseksi se vaihtaa LEDiä 200 ms: n välein vertaamalla kuluneita millisarjoja. Selitys on jo selitetty aiemmin tässä artikkelissa.
if (currentMillis - edellinenMillis2> = jakso2) { previousMillis2 = currentMillis; if (ledState2 == LOW) { ledState2 = KORKEA; } else { ledState2 = LOW; } digitalWrite (led2, ledState2); }
Lopuksi buttonPushed- lippua valvotaan ja 20 ms: n purkuviiveen muodostamisen jälkeen se vain vaihtaa LED-tilan vastaavan keskeytykseksi liitettyä painonappia.
if (buttonPushed = true) // tarkista, kutsutaanko ISR: ää { if ((currentMillis - debounceMillis)> debouncePeriod && buttonPushed) // luo 20 ms: n poistumisviive moninkertaisten painallusten välttämiseksi { debounceMillis = currentMillis; // tallenna viimeinen poistumisviive, jos (digitalRead (pushButton) == LOW && lastState == HIGH) // vaihda lediä painikkeen painamisen jälkeen { ledChange =! ledMuutos; digitalWrite (toggleLed, ledChange); lastState = matala; } else if (digitalRead (pushButton) == HIGH && lastState == LOW) { lastState = KORKEA; } buttonPushed = false; } }
Tämä viimeistelee Arduino millis () -opetusohjelman. Huomaa, että saadaksesi tavan millis (): n kanssa, harjoittele vain tämän logiikan toteuttamista joissakin muissa sovelluksissa. Voit myös laajentaa sitä käyttämään moottoreita, servomoottoreita, antureita ja muita oheislaitteita. Jos sinulla on epäilyksiä, kirjoita foorumillemme tai kommentoi alla.
Täydellinen koodi ja video millis-toiminnon osoittamiseksi Arduinossa on alla.