- Hvad er multitasking?
- Hvorfor springe forsinkelse () over i Arduino?
- Hvorfor bruge millis ()?
- Komponenter, der kræves
- Kredsløbsdiagram
- Programmering af Arduino UNO til multitasking
Den multitasking har ført computerne til en revolution, hvor et eller flere programmer kan køre samtidigt, hvilket øger effektivitet, fleksibilitet, tilpasningsevne og produktivitet. I integrerede systemer kan mikrokontrollere også håndtere multitasking og udfører to eller flere opgaver samtidigt uden at stoppe de nuværende instruktioner.
Her i denne vejledning lærer vi, hvordan Arduino udfører multitasking med Arduino millis-funktion. Generelt bruges en forsinkelsesfunktion () i Arduino til en periodisk opgave som LED blinker, men denne forsinkelsesfunktion () standser programmet i en bestemt periode og tillader ikke andre operationer at udføre. Så denne artikel forklarer, hvordan vi kan undgå brugen af forsinkelse () -funktionen og erstatte den med millis () for at udføre mere end en opgave samtidigt og gøre Arduino til en multitasking-controller. Før vi går i detaljer, lad os starte med at undervurdere Multitasking.
Hvad er multitasking?
Multitasking betyder simpelthen at udføre mere end en opgave eller et program samtidigt på samme tid. Næsten alle operativsystemer har multitasking. Denne type operativsystemer er kendt som MOS (multitasking-operativsystem). MOS kan være mobil eller stationær pc-operativsystem. Det gode eksempel på multitasking på computere er, når brugere kører e-mail-applikationen, internetbrowser, medieafspiller, spil på samme tid, og hvis brugerne ikke vil bruge applikationen, kører den i baggrunden, hvis den ikke er lukket. Slutbrugeren bruger alle disse applikationer på samme tid, men OS tager dette koncept lidt anderledes. Lad os diskutere, hvordan OS styrer multitasking.
Som det ses på billedet, opdeler CPU tiden i de tre lige store dele og tildeler hver del til hver opgave / applikation. Sådan udføres multitasking i de fleste systemer. Konceptet vil være næsten det samme for Arduino Multitasking, undtagen tidsfordelingen vil være lidt anderledes. Da Arduino kører i lav frekvens og RAM sammenlignes med bærbar / mobil / pc, så den tid, der gives til hver opgave, vil også være anderledes. Arduino har også en forsinkelsesfunktion () , som bruges meget. Men inden vi begynder, lad os diskutere, hvorfor vi ikke skal bruge delay () -funktionen i ethvert projekt.
Hvorfor springe forsinkelse () over i Arduino?
Hvis man betragter referencedokumentationen til Arduino, er der to typer forsinkelsesfunktioner, den første er forsinkelse () og anden er forsinkelseMikrosekunder (). Begge funktioner er identiske med hensyn til generering af forsinkelse. Den eneste forskel er, at i forsinket () -funktionen er parameteren heltal, der er gået, i millisekunder, dvs. hvis vi skriver forsinkelse (1000), vil forsinkelsen være på 1000 millisekunder, dvs. 1 sekund. På samme måde i funktionen delayMicroseconds () er den valgte parameter i mikrosekunder, dvs. hvis vi skriver delayMicroseconds (1000), vil forsinkelsen være på 1000 mikrosekunder, dvs. 1 millisekunder.
Her kommer pointen, begge funktioner sætter programmet på pause i den tid, der er gået i forsinkelsesfunktionen. Så hvis vi giver en forsinkelse på 1 sekund, kan processoren ikke gå til næste instruktion, før 1 sekund er gået. På samme måde, hvis forsinkelsen er 10 sekunder, stopper programmet i 10 sekunder, og processoren tillader ikke at gå til de næste instruktioner, før de 10 sekunder er gået. Dette hæmmer mikrocontrollerens ydeevne med hensyn til hastighed og udførelse af instruktionerne.
Det bedste eksempel til at forklare ulempen ved forsinkelsesfunktionen er at bruge to trykknapper. Overvej, at vi vil skifte to lysdioder ved hjælp af to trykknapper. Så hvis der trykkes på en trykknap, skal den tilsvarende lysdiode lyse i 2 sekunder, ligesom hvis der trykkes på et sekund, skal lampen lyse i 4 sekunder. Men når vi bruger forsinkelse (), hvis brugeren trykker på den første knap, stopper programmet i 2 sekunder, og hvis brugeren trykker på den anden knap inden 2 sekunders forsinkelse, accepterer mikrokontrolleren ikke input, da programmet er i standsning.
Den officielle dokumentation for Arduino nævner dette tydeligt i dens beskrivelser af noter og advarsler om forsinkelse (). Du kan gå igennem og tjekke dette for at gøre det mere klart.
Hvorfor bruge millis ()?
For at overvinde problemet forårsaget af forsinkelse, skal en udvikler bruge millis () -funktionen, som er let at bruge, når du er vant til, og den bruger 100% CPU-ydeevne uden at generere nogen forsinkelse i udførelsen af instruktionerne. millis () er en funktion, der netop returnerer det antal millisekunder, der er gået siden Arduino-kortet begyndte at køre det aktuelle program uden at fryse programmet. Dette tidsnummer overløber (dvs. går tilbage til nul) efter ca. 50 dage.
Ligesom Arduino har delayMicroseconds (), har den også mikroversionen af millis () som micros (). Forskellen mellem micros og millis er, at micros () vil løbe over efter ca. 70 minutter sammenlignet med millis (), som er 50 dage. Så afhængigt af applikationen kan du bruge millis () eller micros ().
Brug af millis () i stedet for forsinkelse ():
For at bruge millis () til timing og forsinkelse skal du registrere og gemme det tidspunkt, hvor handlingen fandt sted for at starte tiden og derefter kontrollere med intervaller, om den definerede tid er gået. Så som sagt, gem det aktuelle tidspunkt i en variabel.
usigneret langstrømMillis = millis ();
Vi har brug for to flere variabler for at finde ud af, om den krævede tid er gået. Vi har gemt den aktuelle tid i currentMillis- variablen, men vi skal også vide, hvornår startede tidsperioden, og hvor lang er perioden. Så Intervallet og forrige Millis erklæres. Intervallet fortæller os tidsforsinkelsen, og previosMillis gemmer sidste gang begivenheden har fundet sted.
usigneret længe tidligereMillis; usigneret lang periode = 1000;
For at forstå dette, lad os tage et eksempel på en simpel blinkende LED. Perioden = 1000 fortæller os, at LED'en blinker i 1 sekund eller 1000 ms.
const int ledPin = 4; // LED-pin nummer tilsluttet int ledState = LAV; // bruges til at indstille LED-tilstanden usigneret lang forrige Millis = 0; // gemmer sidste gang LED blev blinket const lang periode = 1000; // periode hvor den skal blinke i ms ugyldig opsætning () { pinMode (ledPin, OUTPUT); // sæt ledpin som output } ugyldig sløjfe () { usigneret lang strømMillis = millis (); // gem det aktuelle tidspunkt, hvis (currentMillis - previousMillis> = periode) {// tjek, om 1000 ms passerede previousMillis = currentMillis; // gem sidste gang du blinkede LED, hvis (ledState == LOW) {// hvis LED er slukket, skal du tænde den og omvendt ledState = HIGH; } andet { ledState = LAV; } digitalWrite (ledPin, ledState); // indstil LED med ledState til at blinke igen } }
Her udsagnet
Afbrydelser i Arduino fungerer på samme måde som i andre mikrocontrollere. Arduino UNO-kortet har to separate ben til fastgørelse af afbrydelser på GPIO pin 2 og 3. Vi har dækket det detaljeret i Arduino Interrupts Tutorial, hvor du kan lære mere om Interrupts og hvordan du bruger dem.
Her viser vi Arduino Multitasking ved at håndtere to opgaver på samme tid. Opgaverne inkluderer blinke af to lysdioder i forskellig tidsforsinkelse sammen med en trykknap, som vil blive brugt til at styre ON / OFF-tilstanden for LED. Så tre opgaver udføres samtidigt.
Komponenter, der kræves
- Arduino UNO
- Tre lysdioder (enhver farve)
- Modstande (470, 10k)
- Jumpere
- Brødbræt
Kredsløbsdiagram
Kredsløbsdiagrammet til demonstration af brugen af Arduino Millis () -funktion er meget let og har ikke meget komponenter at fastgøre som vist nedenfor.
Programmering af Arduino UNO til multitasking
Programmering af Arduino UNO til multitasking kræver kun logikken bag, hvordan millis () fungerer, som forklaret ovenfor. Det anbefales at øve blink-LED ved hjælp af millis igen og igen for at gøre logikken klar og gøre dig fortrolig med millis () inden du begynder at programmere Arduino UNO til multitasking. I denne vejledning bruges afbrydelsen også med millis () samtidigt til multitasking. Knappen afbryder. Så når der genereres en afbrydelse, dvs. at der trykkes på en knap, skifter LED'en til ON eller OFF-tilstand.Programmeringen starter med at deklarere pin-numre, hvor lysdioder og trykknap er tilsluttet.
int led1 = 6; int led2 = 7; int toggleLed = 5; int trykknap = 2;
Dernæst skriver vi en variabel for at gemme status for lysdioder til fremtidig brug.
int ledState1 = LAV; int ledState2 = LAV;
Ligesom forklaret ovenfor i blinkeksemplet erklæres variablerne for periode og tidligere millis for at sammenligne og generere forsinkelse for lysdioder. Den første LED blinker efter hvert 1. sekund, og en anden LED blinker efter 200 ms.
usigneret lang forrigeMillis1 = 0; const lang periode1 = 1000; usigneret lang forrigeMillis2 = 0; const lang periode2 = 200;
En anden millis-funktion vil blive brugt til at generere afvisningsforsinkelsen for at undgå flere tryk på trykknappen. Der vil være en lignende tilgang som ovenfor.
int debouncePeriod = 20; int debounceMillis = 0;
De tre variabler vil blive brugt til at gemme status på trykknap som afbrydelse, skift mellem LED og trykknaptilstand.
bool buttonPushed = false; int ledChange = LAV; int lastState = HIGH;
Definer handlingen af pin, hvilken pin fungerer som INPUT eller OUTPUT.
pinMode (led1, OUTPUT); pinMode (led2, OUTPUT); pinMode (toggleLed, OUTPUT); pinMode (trykknap, INPUT);
Definer nu interrupt pin ved at fastgøre interrupt med definition af ISR og interrupt Mode. Bemærk, at det anbefales at bruge digitalPinToInterrupt (pin_number), når du erklærer attachInterrupt () -funktion til at oversætte den aktuelle digitale pin til det specifikke interruptnummer.
attachInterrupt (digitalPinToInterrupt (pushButton), pushButton_ISR, CHANGE);
Interrupt-afbrydelsen skrives, og den ændrer kun knappen Pushed flag. Bemærk, at afbryd subrutine skal være så kort som muligt, så prøv at skrive det og minimer de ekstra instruktioner.
ugyldigt pushButton_ISR () { buttonPushed = sandt; }
Loop begynder med at gemme millis-værdien i en currentMillis-variabel, der gemmer værdien af den forløbne tid, hver gang sløjfen gentages.
usigneret langstrømMillis = millis ();
Der er i alt tre funktioner i multitasking, blink en LED på 1 sekund, Blink sekund LED ved 200 ms, og hvis der trykkes på trykknappen, skal du slå OFF / ON LED til. Så vi skriver tre dele for at udføre denne opgave.
Den første skifter LED-tilstand efter hvert 1 sekund ved at sammenligne de forløbne millis.
hvis (currentMillis - previousMillis1> = period1) { previousMillis1 = currentMillis; hvis (ledState1 == LOW) { ledState1 = HIGH; } andet { ledState1 = LAV; } digitalWrite (led1, ledState1); }
Tilsvarende skifter den for det andet LED'en efter hver 200 ms ved at sammenligne de forløbne millis. Forklaringen er allerede forklaret tidligere i denne artikel.
hvis (currentMillis - previousMillis2> = period2) { previousMillis2 = currentMillis; hvis (ledState2 == LOW) { ledState2 = HIGH; } andet { ledState2 = LAV; } digitalWrite (led2, ledState2); }
Endelig, den buttonPushed er flaget overvåges, og efter at generere en Debounce forsinkelse på 20ms det bare skifter tilstanden af LED svarer til trykknap vedhæftet som interrupt.
if (buttonPushed = true) // check if ISR is called { if ((currentMillis - debounceMillis)> debouncePeriod && buttonPushed) // generere 20 ms debounce forsinkelse for at undgå flere tryk { debounceMillis = currentMillis; // gem den sidste forsinkelsestid, hvis (digitalRead (pushButton) == LOW && lastState == HIGH) // skift LED, når der trykkes på trykknappen { ledChange =! ledændring; digitalWrite (toggleLed, ledChange); lastState = LAV; } ellers hvis (digitalRead (pushButton) == HIGH && lastState == LOW) { lastState = HIGH; } buttonPushed = false; } }
Dette afslutter Arduino millis () -vejledningen. Bemærk, at for at blive sædvanlig med millis (), skal du bare øve dig at implementere denne logik i nogle andre applikationer. Du kan også udvide den til at bruge motorer, servomotorer, sensorer og andet perifert udstyr. I tvivlstilfælde bedes du skrive til vores forum eller kommentere nedenfor.
Komplet kode og video til demonstration af brugen af millis-funktionen i Arduino findes nedenfor.