- Što je multitasking?
- Zašto preskočiti kašnjenje () u Arduinu?
- Zašto koristiti milis ()?
- Komponente potrebne
- Kružni dijagram
- Programiranje Arduina UNO za multitasking
Multitasking dovela računala do revolucije u kojoj jedan ili više programa istovremeno može raditi što povećava učinkovitost, fleksibilnost, prilagodljivost i produktivnost. U ugrađenim sustavima mikrokontroleri također mogu rukovati multitaskingom i istodobno izvode dva ili više zadataka bez zaustavljanja trenutnih uputa.
Ovdje ćemo u ovom uputstvu naučiti kako Arduino izvodi multitasking s funkcijom Arduino millis. Općenito se funkcija delay () koristi u Arduinu za povremene zadatke poput treptanja LED-a, ali ova funkcija delay () zaustavlja program na određeno vrijeme i ne dopušta izvođenje drugih operacija. Stoga ovaj članak objašnjava kako možemo izbjeći upotrebu funkcije delay () i zamijeniti je milisom () za istodobno izvršavanje više zadataka i učiniti Arduino multitasking kontrolerom. Prije nego što krenemo u detalje, krenimo s podcjenjivanjem multitaskinga.
Što je multitasking?
Multitasking jednostavno znači istodobno izvršavanje više zadataka ili programa. Gotovo svi operativni sustavi imaju višezadaćnost. Ovakvi operativni sustavi poznati su kao MOS (multitasking operativni sustav). MOS može biti mobilni ili stolni operativni sustav. Dobar primjer multitaskinga na računalima je kada korisnici istodobno pokreću aplikaciju za e-poštu, internetski preglednik, media player, igre i ako korisnici ne žele koristiti aplikaciju, ona se pokreće u pozadini ako nije zatvorena. Krajnji korisnik istovremeno koristi sve ove aplikacije, ali OS ovaj koncept uzima malo drugačije. Razgovarajmo o tome kako OS upravlja multitaskingom.

Kao što se vidi na slici, CPU dijeli vrijeme na tri jednaka dijela i svaki dio dodjeljuje svakom zadatku / aplikaciji. Tako se obavlja multitasking u većini sustava. Koncept će biti gotovo isti za Arduino Multitasking, osim što će vremenska raspodjela biti malo drugačija. Budući da Arduino radi na niskim frekvencijama i RAM-u u usporedbi s prijenosnim računalom / mobitelom / računalom, vrijeme dodijeljeno svakom zadatku također će biti različito. Arduino također ima funkciju delay () koja se široko koristi. Ali prije početka, razgovarajmo o tome zašto ne bismo trebali koristiti funkciju delay () u bilo kojem projektu.
Zašto preskočiti kašnjenje () u Arduinu?
Ako se razmotri referentna dokumentacija Arduina, postoje dvije vrste funkcija odgode, prva je delay (), a druga delayMicroseconds (). Obje su funkcije identične u smislu generiranja kašnjenja. Jedina je razlika u tome što je, u funkciji delay (), cijeli broj parametra poslan u milisekundama, tj. Ako napišemo delay (1000) tada će kašnjenje biti 1000 milisekundi, tj. 1 sekunda. Slično funkciji delayMicroseconds (), parametar se predaje u mikrosekundama, tj. Ako napišemo delayMicroseconds (1000), tada će kašnjenje biti 1000 mikrosekundi, tj. 1 milisekundi.
Evo poante, obje funkcije zaustavljaju program za vrijeme provedeno u funkciji odgode. Dakle, ako dajemo kašnjenje od 1 sekunde, procesor ne može ići na sljedeću uputu dok ne prođe 1 sekunda. Slično tome, ako je kašnjenje 10 sekundi, program će se zaustaviti na 10 sekundi, a procesor neće dopustiti da slijedi sljedeće upute dok ne prođe 10 sekundi. To koči performanse mikrokontrolera u smislu brzine i izvršavanja uputa.
Najbolji primjer za objašnjenje nedostatka funkcije odgode je uporaba dvije tipke. Uzmimo u obzir da želimo prebaciti dvije LED diode pomoću dva gumba. Dakle, ako se pritisne jedan gumb, odgovarajuća LED dioda trebala bi svijetliti 2 sekunde, slično ako se pritisne druga, LED bi trebao svijetliti 4 sekunde. Ali kada koristimo delay (), ako korisnik pritisne prvi gumb, program će se zaustaviti na 2 sekunde, a ako korisnik pritisne drugi gumb prije kašnjenja od 2 sekunde, tada mikrokontroler neće prihvatiti ulaz kao što je program u fazi zaustavljanja.
Službena dokumentacija Arduina to jasno spominje u opisu funkcije Notes and Warnings of delay (). Možete to proći i provjeriti da bi bilo jasnije.
Zašto koristiti milis ()?
Da bi prevladao problem uzrokovan odgodom, programer bi trebao koristiti funkciju millis () koja je jednostavna za upotrebu nakon što postanete uobičajena i koristit će 100% performanse CPU-a bez stvaranja kašnjenja u izvršavanju uputa. millis () je funkcija koja samo vraća količinu milisekundi proteklih od trenutka kada je ploča Arduino počela izvoditi trenutni program bez zamrzavanja programa. Taj će se vremenski broj preliti (tj. Vratiti se na nulu), nakon približno 50 dana.
Baš kao što Arduino ima delayMicroseconds (), tako ima i mikro verziju millis () kao micros (). Razlika između mikro i milisa je u tome što će se mikro () preliti nakon približno 70 minuta, u usporedbi s milisom () što je 50 dana. Dakle, ovisno o aplikaciji, možete koristiti milis () ili mikro ().
Upotreba milisa () umjesto odgode ():
Da biste milis () koristili za mjerenje vremena i kašnjenje, morate zabilježiti i pohraniti vrijeme u kojem se odvijala radnja da biste započeli vrijeme, a zatim u intervalima provjeravali je li definirano vrijeme prošlo. Dakle, kao što je navedeno, pohranite trenutno vrijeme u varijablu.
nepotpisana duga strujaMillis = milis ();
Trebamo još dvije varijable kako bismo saznali je li prošlo potrebno vrijeme. Pohranili smo trenutno vrijeme u varijablu currentMillis, ali također moramo znati kada je počelo vremensko razdoblje i koliko je dugo razdoblje. Tako je proglašen Interval i previousMillis . Interval će nam reći vremensko kašnjenje, a previosMillis će pohraniti zadnji put kada se događaj dogodio.
nepotpisano dugo previousMillis; nepotpisano dugo razdoblje = 1000;
Da bismo to razumjeli, uzmimo primjer jednostavnog trepćućeg LED-a. Razdoblje = 1000 reći će nam da će LED treptati 1 sekundu ili 1000 ms.
const int ledPin = 4; // LED pin broj povezan int ledState = LOW; // koristi se za postavljanje stanja LED-a nepotpisano long previousMillis = 0; // pohranit će zadnji put treptanje LED-a const long period = 1000; // razdoblje u kojem treba treptati u ms void setup () { pinMode (ledPin, OUTPUT); // postavimo ledpin kao izlaz } void loop () { unsigned long currentMillis = millis (); // pohranjujemo trenutno vrijeme if (currentMillis - previousMillis> = period) {// provjeravamo je li prošlo 1000ms previousMillis = currentMillis; // spremi zadnji put kad ste trepnuli LED ako (ledState == LOW) {// ako je LED isključen, uključite ga i obrnuto ledState = HIGH; } else { ledState = LOW; } digitalWrite (ledPin, ledState); // podesimo LED da ledState ponovo trepće } }
Evo, izjava
Prekidi u Arduinu djeluju kao i kod ostalih mikrokontrolera. Ploča Arduino UNO ima dva odvojena pina za pričvršćivanje prekida na GPIO pinu 2 i 3. Detaljno smo to pokrili u Vodiču za prekide Arduino, gdje možete saznati više o prekidima i kako ih koristiti.
Ovdje ćemo prikazati Arduino Multitasking rješavanjem dva zadatka istovremeno. Zadaci će uključivati treptanje dviju LED dioda u različitim vremenskim odgodama, zajedno s gumbom koji će se koristiti za upravljanje ON / OFF stanjem LED diode. Dakle, istodobno će se izvoditi tri zadatka.

Komponente potrebne
- Arduino UNO
- Tri LED (bilo koja boja)
- Otpori (470, 10k)
- Skakači
- Breadboard
Kružni dijagram
Shema spojeva za demonstraciju upotrebe fukcije Arduino Millis () vrlo je jednostavna i nema puno komponenata za pričvršćivanje, kao što je prikazano u nastavku.

Programiranje Arduina UNO za multitasking
Programiranje Arduino UNO-a za multitasking zahtijevat će samo logiku rada milisa () koja je gore objašnjena. Prije nego što počnete programirati Arduino UNO za multitasking, preporučuje se vježbanje LED-a za treptanje pomoću milisa iznova i iznova kako biste logiku učinili jasnom i ugodno se osjećali s milisom (). U ovom se priručniku prekid također koristi s milis () istovremeno za multitasking. Gumb će biti prekid. Dakle, kad god se generira prekid, tj. Pritisne tipka, LED će se prebaciti u stanje ON ili OFF.Programiranje započinje deklariranjem brojeva pinova gdje su spojene LED i tipka.
int vodio1 = 6; int vodio2 = 7; int toggleLed = 5; int pushButton = 2;
Dalje napišemo varijablu za pohranu statusa LED-a za buduću upotrebu.
int ledState1 = LOW; int ledState2 = LOW;
Kao što je gore objašnjeno u primjeru treptanja, varijable za period i previousmillis proglašene su za usporedbu i generiranje kašnjenja za LED diode. Prva LED lampica trepće nakon svake 1 sekunde, a druga LED lampica trepće nakon 200 ms.
nepotpisano dugo previousMillis1 = 0; const dugo razdoblje1 = 1000; nepotpisano dugo previousMillis2 = 0; const dugo razdoblje2 = 200;
Druga milis funkcija bit će korištena za generiranje kašnjenja prekida zvuka kako bi se izbjeglo višestruko pritiskanje tipke. Bit će sličan pristup kao gore.
int debouncePeriod = 20; int debounceMillis = 0;
U tri varijable će se koristiti za pohranu status taster za što prekida, preklopni LED i pritiskom na dugme države.
bool buttonPushed = false; int ledChange = LOW; int lastState = VISOKO;
Definirajte djelovanje pribadače koja će pribadača raditi kao ULAZ ili IZLAZ.
pinMode (led1, IZLAZ); pinMode (led2, IZLAZ); pinMode (toggleLed, OUTPUT); pinMode (pushButton, INPUT);
Sada definirajte pin prekida tako što ćete priložiti prekid s definicijom ISR-a i načina prekida. Imajte na umu da se za deklariranje funkcije attachInterrupt () preporučuje upotreba digitalPinToInterrupt (pin_number) za prevođenje stvarnog digitalnog pin-a na određeni broj prekida.
attachInterrupt (digitalPinToInterrupt (pushButton), pushButton_ISR, CHANGE);
Podprogram prekida je napisan i promijenit će samo zastavicu buttonPushed. Imajte na umu da potprogram prekida treba biti što kraći, pa ga pokušajte napisati i smanjite dodatne upute.
void pushButton_ISR () { buttonPushed = true; }
Loop započinje spremanjem milis vrijednosti u varijablu currentMillis koja će pohraniti vrijednost vremena proteklog svaki put kad se petlja ponovi.
nepotpisana duga strujaMillis = milis ();
U multitaskingu su ukupno tri funkcije, trepnite jednom LED-om u 1 sekundi, trepnite drugom LED-om na 200 ms i ako je pritisnuta tipka, isključite / uključite LED-u. Tako ćemo napisati tri dijela kako bismo izvršili ovaj zadatak.
Prvi je prijelaz LED stanje nakon svake 1 sekunde usporedbom Milisekunde prošlo.
if (currentMillis - previousMillis1> = period1) { previousMillis1 = currentMillis; ako (ledState1 == LOW) { ledState1 = HIGH; } else { ledState1 = LOW; } digitalWrite (led1, ledState1); }
Slično tome, drugo, prebacuje LED nakon svakih 200 ms uspoređujući protekle milise. Objašnjenje je već objašnjeno ranije u ovom članku.
if (currentMillis - previousMillis2> = period2) { previousMillis2 = currentMillis; ako (ledState2 == LOW) { ledState2 = HIGH; } else { ledState2 = LOW; } digitalWrite (led2, ledState2); }
I na kraju, nadzire se zastavica buttonPushed i nakon generiranja odgode odbijanja od 20 ms, samo prebacuje stanje LED-a koje odgovara gumbu pričvršćenom kao prekid.
if (buttonPushed = true) // provjeri je li pozvan ISR { if (((currentMillis - debounceMillis)> debouncePeriod && buttonPushed) // generira 20ms kašnjenja debouncea kako bi se izbjeglo višestruko pritiskanje { debounceMillis = currentMillis; // spremamo vrijeme zadnjeg kašnjenja s ponavljanjem ako je (digitalRead (pushButton) == LOW && lastState == HIGH) // promijenimo led nakon pritiska gumba { ledChange =! ledChange; digitalWrite (toggleLed, ledChange); lastState = LOW; } inače if (digitalRead (pushButton) == HIGH && lastState == LOW) { lastState = HIGH; } buttonPushed = false; } }
Time je završen vodič za Arduino millis (). Imajte na umu da, kako biste navikli na milise (), samo uvježbajte primjenu ove logike u nekim drugim aplikacijama. Možete ga proširiti i za upotrebu motora, servo motora, senzora i druge periferne opreme. U slučaju bilo kakve sumnje, pišite na naš forum ili komentirajte u nastavku.
Kompletni kod i video za demonstraciju upotrebe milis funkcije u Arduinu nalaze se u nastavku.
