multitasking-ul a condus computerele la o revoluție în care unul sau mai multe programe pot rula simultan, ceea ce crește eficiența, flexibilitatea, adaptabilitatea și productivitatea. În sistemele încorporate, microcontrolerele pot gestiona, de asemenea, Multitasking și efectuează două sau mai multe sarcini simultan fără a opri instrucțiunile curente.

aici, în acest tutorial, vom afla cum Arduino efectuează multitasking cu funcția Arduino millis. În general, o funcție delay() este utilizată în Arduino pentru o sarcină periodică, cum ar fi LED-ul care clipește, dar această funcție delay() oprește programul pentru o perioadă definitivă și nu permite efectuarea altor operații. Deci, acest articol explică modul în care putem evita utilizarea funcției delay() și înlocuiți-o cu millis() pentru a efectua mai multe sarcini simultan și a face din Arduino un controler Multitasking. Înainte de a intra în detalii, să începem cu subestimarea Multitasking-ului.

ce este Multitasking-ul?

Multitasking înseamnă pur și simplu executarea mai multor sarcini sau programe simultan în același timp. Aproape toate sistemele de operare au multitasking. Acest tip de sisteme de operare sunt cunoscute sub numele de MOS (sistem de operare multitasking). MOS poate fi un sistem de operare pentru PC mobil sau desktop. Exemplul bun de multitasking în computere este atunci când utilizatorii rulează aplicația de e-mail, browserul de internet, playerul media, jocurile, în același timp și dacă utilizatorii nu doresc utilizați aplicația pe care o rulează în fundal dacă nu este închisă. Utilizatorul final utilizează toate aceste aplicații în același timp, dar OS ia acest concept un pic diferit. Să discutăm despre modul în care sistemul de operare gestionează multitasking-ul.

ce este multitasking în Arduino

după cum se vede în imagine, CPU împarte timpul în cele trei părți egale și atribuie fiecare parte fiecărei sarcini / aplicații. Acesta este modul în care se face multitasking-ul în majoritatea sistemelor. Conceptul va fi aproape același pentru multitasking-ul Arduino, cu excepția faptului că distribuția timpului va fi puțin diferită. Deoarece Arduino rulează în frecvență joasă și RAM se compară cu Laptop / mobil / PC, timpul acordat fiecărei sarcini va fi, de asemenea, diferit. Arduino are, de asemenea, o întârziere() funcție care este utilizat pe scară largă. Dar înainte de a începe să discutăm de ce nu ar trebui să folosim funcția delay() în niciun proiect.

de ce să săriți întârziere() în Arduino?

dacă documentația de referință a Arduino este considerată atunci există două tipuri de funcții de întârziere, prima este întârziere() și a doua este delayMicroseconds(). Ambele funcții sunt identice în ceea ce privește generarea întârzierii. Singura diferență este că, în funcția delay (), parametrul întreg trecut este în milisecunde, adică dacă scriem întârziere(1000), atunci întârzierea va fi de 1000 milisecunde, adică 1 secundă. În mod similar în funcția delayMicroseconds (), parametrul trecut este în microsecunde, adică dacă scriem delaymicrosecunde (1000), atunci întârzierea va fi de 1000 microsecunde, adică 1 milisecunde.

aici vine punctul, ambele funcții întrerupe programul pentru cantitatea de timp a trecut în funcție de întârziere. Deci, dacă dăm o întârziere de 1 secundă, atunci procesorul nu poate merge la următoarea instrucțiune până când a trecut 1 secundă. În mod similar, dacă întârzierea este de 10 secunde, atunci programul se va opri timp de 10 secunde, iar procesorul nu va permite să meargă pentru următoarele instrucțiuni până când au trecut cele 10 secunde. Acest lucru împiedică performanța microcontrolerului în ceea ce privește viteza și executarea instrucțiunilor.

cel mai bun exemplu pentru a explica dezavantajul funcției de întârziere este utilizarea a două butoane. Luați în considerare dorim să comutați două LED-uri folosind două butoane. Deci, dacă un buton este apăsat, atunci LED-ul corespunzător ar trebui să strălucească timp de 2 secunde, în mod similar, dacă al doilea este împins, atunci LED-ul ar trebui să strălucească timp de 4 secunde. Dar când folosim delay (), dacă utilizatorul apasă primul buton, Atunci programul se va opri timp de 2 secunde și dacă utilizatorul apasă al doilea buton înainte de întârzierea de 2 secunde, atunci microcontrolerul nu va accepta intrarea, deoarece programul se află în stadiul de oprire.

documentația oficială a Arduino menționează în mod clar acest lucru în notele și avertismentele de întârziere() descrierea funcției. Puteți trece prin și a verifica acest lucru pentru a face mai clar.

de ce să folosiți millis() ?

pentru a depăși problema cauzată de utilizarea întârziere, un dezvoltator ar trebui să utilizeze funcția millis (), care este ușor de utilizat odată ce ați devenit obișnuită și se va folosi de performanță CPU 100%, fără a genera nici o întârziere în executarea instrucțiunilor. millis () este o funcție care returnează doar cantitatea de milisecunde care au trecut de când placa Arduino a început să ruleze programul curent fără a îngheța programul. Acest număr de timp se va revărsa (adică va reveni la zero), după aproximativ 50 de zile.

la fel ca Arduino au delayMicroseconds(), ea are, de asemenea, versiunea micro de millis() ca micros(). Diferența dintre micros și millis este că micros () se va revărsa după aproximativ 70 de minute, comparativ cu millis () care este de 50 de zile. Deci, în funcție de aplicație, puteți utiliza millis () sau micros ().

Using millis() instead of delay():

pentru a utiliza millis() pentru sincronizare și întârziere, trebuie să înregistrați și să stocați ora la care a avut loc acțiunea pentru a începe ora și apoi verificați la intervale dacă timpul definit a trecut. Deci, după cum sa menționat, stoca ora curentă într-o variabilă.

unsigned long currentMillis = millis();

avem nevoie de încă două variabile pentru a afla dacă a trecut timpul necesar. Am stocat ora curentă în variabila currentMillis, dar trebuie să știm și când a început perioada de sincronizare și cât timp este perioada. Deci intervalul și precedentulmillis este declarat. Intervalul ne va spune întârzierea și previosMillis va stoca ultima dată când a avut loc evenimentul.

unsigned long previousMillis;unsigned long period = 1000;

pentru a înțelege acest lucru, să luăm un exemplu de LED simplu care clipește. Perioada = 1000 ne va spune că LED – ul va clipi timp de 1 secundă sau 1000ms.

const int ledPin = 4; // the LED pin number connectedint ledState = LOW; // used to set the LED stateunsigned long previousMillis = 0; //will store last time LED was blinkedconst long period = 1000; // period at which to blink in msvoid setup() { pinMode(ledPin, OUTPUT); // set ledpin as output}void loop() { unsigned long currentMillis = millis(); // store the current time if (currentMillis - previousMillis >= period) { // check if 1000ms passed previousMillis = currentMillis; // save the last time you blinked the LED if (ledState == LOW) { // if the LED is off turn it on and vice-versa ledState = HIGH; } else {ledState = LOW;} digitalWrite(ledPin, ledState);//set LED with ledState to blink again }}

aici, declarația <if (currentMillis-previousMillis >= period)> verifică dacă 1000ms a trecut. Dacă a trecut 1000ms, atunci LED-ul clipește și din nou ajunge la aceeași stare. Și asta continuă. Asta e, am învățat să folosim millis în loc de întârziere. În acest fel nu va opri programul pentru un anumit interval.

întrerupe în Arduino funcționează la fel ca în alte microcontrolere. Placa Arduino UNO are doi pini separați pentru atașarea întreruperilor pe pinul GPIO 2 și 3. L-am acoperit în detaliu în tutorialul Arduino întrerupe, unde puteți afla mai multe despre întreruperi și cum să le utilizați.

aici vom arăta Arduino multitasking prin gestionarea a două sarcini în același timp. Sarcinile vor include clipirea a două LED-uri cu întârziere de timp diferită, împreună cu un buton care va fi utilizat pentru a controla starea de pornire/oprire a LED-ului. Deci, trei sarcini vor fi efectuate simultan.

diagrama circuitului pentru Arduino Multitasking

componente necesare

  • Arduino UNO
  • Trei LED-uri(Orice culoare)
  • rezistențe (470, 10k)
  • jumperi
  • Breadboard

diagrama circuitului

diagrama circuitului pentru demonstrarea utilizării Arduino Millis() Fuction este foarte ușoară și nu are prea multe componente de atașat așa cum se arată mai jos.

diagrama circuitului pentru Arduino Multitasking folosind funcția Arduino Millis ()

programare Arduino UNO pentru Multitasking

programare Arduino UNO pentru multitasking va necesita doar logica din spatele modului în care funcționează millis (), care este explicat mai sus. Este recomandat să exersați Blink LED folosind millis din nou și din nou pentru a clarifica logica și a vă face confortabil cu millis() înainte de a începe să programați Arduino UNO pentru multitasking. În acest tutorial întreruperea este, de asemenea, utilizat cu millis() simultan pentru multitasking. Butonul va fi o întrerupere. Deci, ori de câte ori este generată o întrerupere, adică este apăsat butonul, LED-ul va trece la starea ON sau OFF.

programarea începe cu declararea numerelor pin la care sunt conectate LED-urile și butonul de apăsare.

int led1 = 6;int led2 = 7;int toggleLed = 5;int pushButton = 2;

în continuare scriem o variabilă pentru a stoca starea LED-urilor pentru utilizare ulterioară.

int ledState1 = LOW;int ledState2 = LOW;

așa cum am explicat mai sus în exemplul clipi, variabilele pentru perioada și previousmillis este declarat pentru a compara și de a genera întârziere pentru LED-uri. Primul LED clipește la fiecare 1 secundă și un alt LED clipește la după 200ms.

unsigned long previousMillis1 = 0; const long period1 = 1000;unsigned long previousMillis2 = 0;const long period2 = 200; 

o altă funcție millis va fi utilizată pentru a genera întârzierea debounce pentru a evita apăsarea multiplă a butonului. Va exista o abordare similară ca mai sus.

int debouncePeriod = 20; int debounceMillis = 0;

cele trei variabile vor fi utilizate pentru a stoca starea butonului de apăsare ca întrerupere, comutare LED și starea butonului de apăsare.

bool buttonPushed = false;int ledChange = LOW; int lastState = HIGH;

definiți acțiunea pinului care pin va funcționa ca intrare sau ieșire.

 pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(toggleLed, OUTPUT); pinMode(pushButton, INPUT);

acum definiți pinul de întrerupere prin atașarea întreruperii cu definiția ISR și a modului de întrerupere. Rețineți că este recomandat să utilizați digitalPinToInterrupt(pin_number) atunci când declarați funcția attachInterrupt() pentru a traduce pinul digital real la numărul specific de întrerupere.

attachInterrupt(digitalPinToInterrupt(pushButton), pushButton_ISR, CHANGE); 

subrutina de întrerupere este scrisă și va schimba doar butonul. Rețineți că întreruperea subrutinei ar trebui să fie cât mai scurtă posibil, așa că încercați să o scrieți și să minimalizați instrucțiunile suplimentare.

void pushButton_ISR(){ buttonPushed = true; }

bucla începe cu stocarea valorii millis într-o variabilă currentMillis care va stoca valoarea timpului scurs de fiecare dată când bucla iterează.

unsigned long currentMillis = millis();

există în total trei funcții în multitasking, clipește un LED la 1 secundă, clipește al doilea LED la 200ms și dacă este apăsat butonul, atunci opriți / porniți LED-ul. Deci, vom scrie trei părți pentru a face această sarcină.

primul este comută condus de stat după fiecare 1 secundă prin compararea Milis scurs.

 if (currentMillis - previousMillis1 >= period1) { previousMillis1 = currentMillis; if (ledState1 == LOW) { ledState1 = HIGH; } else { ledState1 = LOW; } digitalWrite(led1, ledState1); }

în mod similar, în al doilea rând comută LED-ul după fiecare 200ms prin compararea milisului scurs. Explicația este deja explicată mai devreme în acest articol.

 if (currentMillis - previousMillis2 >= period2) { previousMillis2 = currentMillis; if (ledState2 == LOW) { ledState2 = HIGH; } else { ledState2 = LOW; } digitalWrite(led2, ledState2); }

În cele din urmă, steagul buttonPushed este monitorizat și după generarea unei întârzieri de debounce de 20ms doar comută starea LED-ului corespunde butonului atașat ca întrerupere.

 if (buttonPushed = true) // check if ISR is called { if ((currentMillis - debounceMillis) > debouncePeriod && buttonPushed) // generate 20ms debounce delay to avoid multiple presses { debounceMillis = currentMillis; // save the last debounce delay time if (digitalRead(pushButton) == LOW && lastState == HIGH) // change the led after push button is pressed { ledChange = ! ledChange; digitalWrite(toggleLed, ledChange); lastState = LOW; } else if (digitalRead(pushButton) == HIGH && lastState == LOW) { lastState = HIGH; } buttonPushed = false; } }

aceasta termină Arduino millis() Tutorial. Rețineți că, în scopul de a obține obișnuită cu millis (), doar practica pentru a pune în aplicare această logică în alte aplicații. De asemenea, îl puteți extinde pentru a utiliza motoare, servomotoare, senzori și alte periferice. În caz de îndoială, vă rugăm să scrieți pe forumul nostru sau să comentați mai jos.

Codul complet și Video pentru demonstrarea utilizării funcției millis în Arduino sunt furnizate mai jos.

Lasă un răspuns

Adresa ta de email nu va fi publicată.