Mikroprosessoritekniikassa rinnakkain kulkevia tehtäviä kutsutaan säikeiksi. Tämä on erittäin kätevää, koska usein on tarpeen suorittaa useita toimintoja samanaikaisesti. Onko mahdollista saada Arduino-mikrokontrolleri suorittamaan useita tehtäviä kerralla, kuten todellinen prosessori? Katsotaan.
Se on välttämätöntä
- - Arduino;
- - 1 LED;
- - 1 pietsosummeri.
Ohjeet
Vaihe 1
Yleisesti ottaen Arduino ei tue todellista rinnakkaistamista tai monisäikeisyyttä.
Mutta voit pyytää mikrokontrolleria tarkistamaan, onko aika suorittaa jokin ylimääräinen taustatehtävä jokaisessa "loop ()" -syklin toistossa. Tässä tapauksessa käyttäjälle näyttää siltä, että useita tehtäviä suoritetaan samanaikaisesti.
Esimerkiksi, vilkaistaan LED tietyllä taajuudella ja samanaikaisesti emittoivat ääniä, jotka nousevat ja putoavat kuin sireeni pietsosähköisestä lähettimestä.
Olemme yhdistäneet sekä LEDin että pietsosäteilijän Arduinoon useammin kuin kerran. Kootaan piiri kuvassa esitetyllä tavalla. Jos kytket LEDin muuhun digitaaliseen nastaan kuin "13", muista, että virtaa rajoittava vastus on noin 220 ohmia.
Vaihe 2
Kirjoitetaan tällainen luonnos ja lähetetään se Arduinoon.
Laudan lataamisen jälkeen voit nähdä, että luonnosta ei suoriteta täsmälleen niin kuin tarvitsemme: kunnes sireeni on täysin toiminnassa, LED ei vilku, ja haluaisimme, että LED vilkkuu sireenin soidessa. Mikä tässä ongelma on?
Tosiasia on, että tätä ongelmaa ei voida ratkaista tavalliseen tapaan. Mikrokontrolleri suorittaa tehtävät tiukasti peräkkäin. "Delay ()" - operaattori viivästyttää ohjelman suorittamista tietyn ajanjakson ajan, ja kunnes tämä aika on kulunut, seuraavia ohjelmakomentoja ei suoriteta. Tämän vuoksi emme voi asettaa eri suorituksen kestoa kullekin tehtävälle ohjelman "silmukassa ()".
Siksi sinun on jotenkin simuloitava moniajo.
Vaihe 3
Arduino-kehittäjät ehdottavat vaihtoehtoa, jossa Arduino suorittaa tehtäviä näennäisesti rinnakkain artikkelissa
Menetelmän ydin on, että jokaisen "loop ()" -silmukan toistamisen yhteydessä tarkistamme, onko aika vilkuttaa LEDiä (suorittaa taustatehtävä) vai ei. Ja jos se tapahtuu, käännämme LED-tilan. Tämä on eräänlainen "delay ()" -operaattorin ohittaminen.
Tämän menetelmän merkittävä haittapuoli on, että LED-ohjausyksikön edessä oleva koodiosio on suoritettava nopeammin kuin "ledInterval" -merkkivalon vilkkuva aikaväli. Muussa tapauksessa vilkkuminen tapahtuu harvemmin kuin on välttämätöntä, emmekä saa aikaan tehtävien rinnakkaisen suorittamisen vaikutusta. Erityisesti piirustuksessamme sireenin äänenvaihdon kesto on 200 + 200 + 200 + 200 = 800 ms, ja asetamme LED-merkkivalon vilkkumisväliksi 200 ms. Mutta LED vilkkuu 800 ms: n jaksolla, joka on 4 kertaa erilainen kuin asetimme. Yleensä, jos koodissa käytetään "delay ()" -operaattoria, näennäissamanaalisuutta on vaikea simuloida, joten on suositeltavaa välttää sitä.
Tässä tapauksessa sireenin äänenohjausyksikön tulisi myös tarkistaa, onko aika tullut vai ei, eikä käyttää viivettä (). Mutta tämä lisäisi koodin määrää ja heikentäisi ohjelman luettavuutta.
Vaihe 4
Tämän ongelman ratkaisemiseksi käytämme upeaa ArduinoThread-kirjastoa, jonka avulla voit helposti luoda pseudo-rinnakkaisia prosesseja. Se toimii samalla tavalla, mutta sen avulla et voi kirjoittaa koodia ajan tarkistamiseksi - onko tehtävä suoritettava tässä silmukassa vai ei. Tämä vähentää koodin määrää ja parantaa luonnoksen luettavuutta. Katsotaanpa kirjasto toiminnassa.
Lataa ensin kirjaston arkisto viralliselta sivustolta https://github.com/ivanseidel/ArduinoThread/archive/master.zip ja pura se Arduino IDE: n "kirjastot" -hakemistoon. Nimeä sitten "ArduinoThread-master" -kansio uudelleen "ArduinoThread" -kansioon.
Vaihe 5
Liitäntäkaavio pysyy samana. Vain ohjelmakoodi muuttuu. Nyt se on sama kuin sivupalkissa.
Ohjelmassa luomme kaksi virtaa, joista kukin suorittaa oman toimintansa: yksi vilkkuu LEDillä, toinen ohjaa sireenin ääntä. Silmukan jokaisessa iteroinnissa tarkistamme jokaiselle säikeelle, onko sen suorittamisen aika tullut vai ei. Jos se saapuu, se käynnistetään suoritettavaksi "run ()" -menetelmällä. Tärkeintä on olla käyttämättä "delay ()" - operaattoria.
Yksityiskohtaisemmat selitykset annetaan koodissa.
Ladataan koodi Arduino-muistiin, suoritetaan se. Nyt kaikki toimii juuri niin kuin sen pitäisi!