multitasking har lett datorerna till en revolution där ett eller flera program kan köras samtidigt vilket ökar effektiviteten, flexibiliteten, anpassningsförmåga och produktivitet. I inbyggda system kan mikrokontroller också hantera Multitasking och utföra två eller flera uppgifter samtidigt utan att stoppa de aktuella instruktionerna.

här i denna handledning lär vi oss hur Arduino utför Multitasking med Arduino millis-funktionen. I allmänhet används en fördröjning () – funktion i Arduino för en periodisk uppgift som LED-blinkning men denna fördröjning () – funktion stoppar programmet under en viss definitiv tid och tillåter inte andra operationer att utföra. Så den här artikeln förklarar hur vi kan undvika användning av delay () – funktionen och ersätta den med millis() för att utföra mer än en uppgift samtidigt och göra Arduino till en multitasking-kontroller. Innan vi går in i detalj, låt oss börja med att underskatta Multitasking.

Vad är Multitasking?

Multitasking betyder helt enkelt att utföra mer än en uppgift eller ett program samtidigt samtidigt. Nästan alla operativsystem har multitasking. Denna typ av operativsystem kallas MOS (multitasking operativsystem). MOS kan vara mobil eller stationär dator operativsystem. Det goda exemplet på multitasking i datorer är när användare kör e-postprogrammet, webbläsare, mediaspelare, spel, samtidigt och om användarna inte vill använda programmet det körs i bakgrunden om det inte stängs. Slutanvändaren använder alla dessa applikationer samtidigt men OS tar detta koncept lite annorlunda. Låt oss diskutera hur OS hanterar multitasking.

Vad är Multitasking i Arduino

som visas på bilden delar CPU tiden i de tre lika delarna och tilldelar varje del till varje uppgift/applikation. Så här görs multitasking i de flesta system. Konceptet kommer att vara nästan detsamma för Arduino Multitasking, förutom att tidsfördelningen blir lite annorlunda. Eftersom Arduino körs i låg frekvens och RAM jämför med bärbar dator / mobil / PC så kommer tiden som ges till varje uppgift också att vara annorlunda. Arduino har också en fördröjning() funktion som används i stor utsträckning. Men innan vi börjar låt oss diskutera det varför vi inte ska använda delay () – funktionen i något projekt.

varför hoppa över fördröjning () i Arduino?

om referensdokumentationen för Arduino beaktas finns det två typer av fördröjningsfunktioner, den första är delay() och den andra är delayMicroseconds(). Båda funktionerna är identiska när det gäller att generera fördröjning. Den enda skillnaden är att, i delay() funktion, parametern heltal passerade är i millisekunder dvs om vi skriver fördröjning (1000) då fördröjningen kommer att vara av 1000 millisekunder dvs 1 sekund. På samma sätt i funktionen delayMicroseconds () är parametern som skickas i mikrosekunder, dvs om vi skriver delaymicrosekunder(1000), kommer fördröjningen att vara 1000 mikrosekunder, dvs 1 millisekunder.

Här kommer punkten, båda funktionerna pausar programmet för den tid som gått i fördröjningsfunktionen. Så om vi ger en fördröjning på 1 sekund kan processorn inte gå till nästa instruktion förrän 1 sekund passerade. På samma sätt om fördröjningen är 10 sekunder sedan programmet stannar i 10 sekunder och processorn kommer inte att tillåta att gå för nästa instruktioner tills 10 sekunder passerat. Detta hindrar mikrokontrollerns prestanda när det gäller hastighet och utförande av instruktionerna.

det bästa exemplet för att förklara nackdelen med fördröjningsfunktionen är att använda Två tryckknappar. Tänk på att vi vill växla två lysdioder med två tryckknappar. Så om en tryckknapp trycks in ska motsvarande lysdiod lysa i 2 sekunder, på samma sätt om andra trycks in ska lysdioden lysa i 4 sekunder. Men när vi använder delay (), om användaren trycker på den första knappen stannar programmet i 2 sekunder och om användaren trycker på den andra knappen före 2 sekunders fördröjning, kommer mikrokontroller inte att acceptera inmatningen eftersom programmet är i stoppstadiet.

den officiella dokumentationen av Arduino nämner tydligt detta i sina anteckningar och varningar om fördröjning() funktionsbeskrivning. Du kan gå igenom och kolla in det här för att göra det tydligare.

Varför använda millis ()?

för att lösa problemet som orsakas av att använda delay, bör en utvecklare använda millis() funktion som är lätt att använda när du blir vanliga och det kommer att använda 100% CPU-prestanda utan att generera någon fördröjning i att utföra instruktionerna. millis () är en funktion som bara returnerar mängden millisekunder som har förflutit sedan Arduino-kortet började köra det aktuella programmet utan att frysa programmet. Denna tid nummer kommer att svämma över (dvs gå tillbaka till noll), efter cirka 50 dagar.

precis som Arduino har delayMicroseconds (), har den också mikroversionen av millis () som micros (). Skillnaden mellan micros och millis är att micros () kommer att flyta över efter cirka 70 minuter, jämfört med millis() som är 50 dagar. Så beroende på vilken applikation du kan använda millis () eller micros ().

Using millis() instead of delay():

för att använda millis() för timing och fördröjning måste du spela in och lagra den tid då åtgärden ägde rum för att starta tiden och sedan kontrollera med intervaller om den definierade tiden har gått. Så som sagt, lagra den aktuella tiden i en variabel.

unsigned long currentMillis = millis();

vi behöver ytterligare två variabler för att ta reda på om den önskade tiden har gått. Vi har lagrat den aktuella tiden i currentMillis variabel men vi måste också veta att när började tidsperioden och hur lång är perioden. Så intervallet och föregåendemillis deklareras. Intervallet kommer att berätta tidsfördröjningen och previosMillis kommer att lagra sista gången händelsen har inträffat.

unsigned long previousMillis;unsigned long period = 1000;

för att förstå detta, låt oss ta ett exempel på en enkel blinkande LED. Perioden = 1000 kommer att berätta för oss att lysdioden blinkar i 1 sekund eller 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 }}

här är uttalandet <if (currentMillis – previousMillis >= period)> kontrollerar om 1000ms har passerat. Om 1000ms har passerat, blinkar LED-lampan och kommer igen till samma tillstånd. Och det här fortsätter. Det är det, vi har lärt oss att använda millis istället för fördröjning. På så sätt kommer det inte att stoppa programmet för ett visst intervall.

avbrott i Arduino fungerar på samma sätt som i andra mikrokontroller. Arduino UNO-kortet har två separata stift för att fästa avbrott på GPIO-stift 2 och 3. Vi har täckt det i detalj i Arduino Interrupts Tutorial, där du kan lära dig mer om avbrott och hur du använder dem.

Här visar vi Arduino Multitasking genom att hantera två uppgifter samtidigt. Uppgifterna kommer att inkludera blinkning av två lysdioder i olika tidsfördröjningar tillsammans med en tryckknapp som kommer att användas för att styra PÅ/AV-läget för LED. Så tre uppgifter kommer att utföras samtidigt.

kretsschema för Arduino Multitasking

komponenter som krävs

  • Arduino UNO
  • tre lysdioder(valfri färg)
  • motstånd (470, 10k)
  • hoppare
  • Breadboard

kretsschema

kretsschemat för att demonstrera användningen av Arduino Millis() Fuction är mycket enkelt och har inte mycket komponenter att fästa som visas nedan.

kretsschema för Arduino Multitasking med Arduino Millis () - funktionen

programmering Arduino UNO för Multitasking

programmering Arduino UNO för multitasking kräver bara logiken bakom hur millis() fungerar som förklaras ovan. Det rekommenderas att öva blink LED med millis om och om igen för att göra logiken tydlig och göra dig bekväm med millis() innan du börjar programmera Arduino UNO för multitasking. I denna handledning används avbrottet också med millis() samtidigt för multitasking. Knappen kommer att vara ett avbrott. Så när ett avbrott genereras, dvs tryckknappen trycks in, kommer lysdioden att växla till på eller av.

programmeringen börjar med att ange pin-nummer där lysdioder och tryckknapp är anslutna.

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

nästa skriver vi en variabel för att lagra status för lysdioder för framtida användning.

int ledState1 = LOW;int ledState2 = LOW;

precis som förklaras ovan i blink-exemplet förklaras variablerna för period och previousmillis att jämföra och generera fördröjning för lysdioder. Den första lysdioden blinkar efter varje 1 sekund och en annan lysdiod blinkar efter 200 ms.

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

en annan millis-funktion kommer att användas för att generera fördröjningen för att undvika flera tryck på tryckknappen. Det kommer att finnas liknande tillvägagångssätt som ovan.

int debouncePeriod = 20; int debounceMillis = 0;

de tre variablerna kommer att användas för att lagra status för tryckknappen som avbrott, växla LED och tryckknappstillstånd.

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

definiera åtgärden av stift som vilken stift kommer att fungera som ingång eller utgång.

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

definiera nu avbrottsstiftet genom att bifoga avbrott med definition av ISR och avbrottläge. Observera att det rekommenderas att använda digitalPinToInterrupt (pin_number) när du förklarar attachInterrupt () – funktionen för att översätta den faktiska digitala pin-koden till det specifika avbrottsnumret.

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

avbrottssubrutinen är skriven och den ändrar bara den knapptryckta flaggan. Observera att avbryta subrutin bör vara så kort som möjligt, så försök att skriva det och minimera de extra instruktionerna.

void pushButton_ISR(){ buttonPushed = true; }

Loop börjar med att lagra millis-värdet i en currentMillis-variabel som lagrar värdet av förfluten tid varje gång slingan upprepas.

unsigned long currentMillis = millis();

det finns totalt tre funktioner i multitasking, blinka en LED vid 1 sekund, blinka andra LED vid 200 ms och om tryckknappen trycks in, stäng av/på LED. Så vi kommer att skriva tre delar för att göra denna uppgift.

den första är växlar LED tillstånd efter varje 1 sekund genom att jämföra millis förflutit.

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

På samma sätt växlar den för det andra lysdioden efter varje 200 ms genom att jämföra de förflutna millierna. Förklaringen förklaras redan tidigare i denna artikel.

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

slutligen övervakas den knapptryckta flaggan och efter att ha genererat en fördröjningsfördröjning på 20 ms växlar den bara led-läget motsvarar tryckknappen som är ansluten som avbrott.

 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; } }

detta avslutar Arduino millis() handledning. Observera att för att bli vanligt med millis(), öva bara för att implementera denna logik i vissa andra applikationer. Du kan också expandera den för att använda motorer, servomotorer, sensor och annan kringutrustning. Om du är osäker, skriv till vårt forum eller kommentera nedan.

komplett kod och Video för att demonstrera användningen av millis-funktionen i Arduino finns nedan.

Lämna ett svar

Din e-postadress kommer inte publiceras.