Das Multitasking hat die Computer zu einer Revolution geführt, bei der ein oder mehrere Programme gleichzeitig ausgeführt werden können, was die Effizienz, Flexibilität, Anpassungsfähigkeit und Produktivität erhöht. In eingebetteten Systemen können Mikrocontroller auch Multitasking verarbeiten und führen zwei oder mehr Aufgaben gleichzeitig aus, ohne die aktuellen Anweisungen anzuhalten.

Hier in diesem Tutorial erfahren Sie, wie Arduino Multitasking mit der Arduino Millis-Funktion ausführt. Im Allgemeinen wird eine Delay () -Funktion in Arduino für eine periodische Aufgabe wie das Blinken der LED verwendet, aber diese Delay () -Funktion stoppt das Programm für eine bestimmte Zeit und erlaubt keine anderen Operationen. In diesem Artikel wird erläutert, wie wir die Verwendung der Delay () -Funktion vermeiden und durch millis () ersetzen können, um mehr als eine Aufgabe gleichzeitig auszuführen und den Arduino zu einem Multitasking-Controller zu machen. Bevor wir ins Detail gehen, beginnen wir mit der Untertreibung von Multitasking.

Was ist Multitasking?

Multitasking bedeutet einfach, mehr als eine Aufgabe oder ein Programm gleichzeitig auszuführen. Fast alle Betriebssysteme verfügen über Multitasking. Diese Art von Betriebssystemen wird als MOS (Multitasking Operating System) bezeichnet. Das MOS kann ein mobiles oder Desktop-PC-Betriebssystem sein. Das gute Beispiel für Multitasking in Computern ist, wenn Benutzer die E-Mail-Anwendung, den Internetbrowser, den Media Player und die Spiele gleichzeitig ausführen und wenn Benutzer die Anwendung nicht verwenden möchten, wird sie im Hintergrund ausgeführt, wenn sie nicht geschlossen ist. Der Endbenutzer verwendet alle diese Anwendungen gleichzeitig, aber das Betriebssystem nimmt dieses Konzept etwas anders auf. Lassen Sie uns diskutieren, wie OS Multitasking verwaltet.

Was ist Multitasking in Arduino

Wie im Bild zu sehen ist, teilt die CPU die Zeit in die drei gleichen Teile und weist jeden Teil jeder Aufgabe / Anwendung zu. Dies ist, wie das Multitasking in den meisten Systemen durchgeführt wird. Das Konzept wird für das Arduino Multitasking fast gleich sein, außer dass die Zeitverteilung etwas anders sein wird. Da das Arduino in niedriger Frequenz und RAM im Vergleich zu Laptop / Handy / PC ausgeführt wird, ist die für jede Aufgabe angegebene Zeit ebenfalls unterschiedlich. Arduino hat auch eine Delay () -Funktion, die weit verbreitet ist. Aber bevor wir beginnen, besprechen wir, warum wir die delay() -Funktion in keinem Projekt verwenden sollten.

Warum delay() in Arduino überspringen?

Wenn die Referenzdokumentation von Arduino berücksichtigt wird, gibt es zwei Arten von Verzögerungsfunktionen, die erste ist delay() und die zweite ist delayMicroseconds() . Beide Funktionen sind hinsichtlich der Verzögerungserzeugung identisch. Der einzige Unterschied besteht darin, dass in der Funktion delay () die übergebene Parameter-Ganzzahl in Millisekunden angegeben ist, dh wenn wir delay(1000) schreiben, beträgt die Verzögerung 1000 Millisekunden, dh 1 Sekunde. In ähnlicher Weise ist in der Funktion delayMicroseconds() der übergebene Parameter in Mikrosekunden, dh wenn wir delayMicroseconds(1000) schreiben, beträgt die Verzögerung 1000 Mikrosekunden, dh 1 Millisekunden.

Hier kommt der Punkt, beide Funktionen pausieren das Programm für die in der Verzögerungsfunktion verstrichene Zeit. Wenn wir also eine Verzögerung von 1 Sekunde angeben, kann der Prozessor erst nach Ablauf von 1 Sekunde zur nächsten Anweisung wechseln. Wenn die Verzögerung 10 Sekunden beträgt, stoppt das Programm für 10 Sekunden und der Prozessor lässt die nächsten Anweisungen erst nach Ablauf der 10 Sekunden zu. Dies behindert die Leistung des Mikrocontrollers in Bezug auf Geschwindigkeit und Ausführung der Anweisungen.

Das beste Beispiel, um den Nachteil der Verzögerungsfunktion zu erklären, ist die Verwendung von zwei Drucktasten. Angenommen, wir möchten zwei LEDs mit zwei Drucktasten umschalten. Wenn also ein Druckknopf gedrückt wird, sollte die entsprechende LED 2 Sekunden lang leuchten. Wenn der zweite gedrückt wird, sollte die LED 4 Sekunden lang leuchten. Wenn wir jedoch delay() verwenden, stoppt das Programm für 2 Sekunden, wenn der Benutzer die erste Taste drückt, und wenn der Benutzer die zweite Taste vor der Verzögerung von 2 Sekunden drückt, akzeptiert der Mikrocontroller die Eingabe nicht, da sich das Programm in der Haltephase befindet.

Die offizielle Dokumentation von Arduino erwähnt dies eindeutig in seinen Anmerkungen und Warnungen zur Funktionsbeschreibung von delay() . Sie können dies durchgehen und überprüfen, um es klarer zu machen.

Warum millis() verwenden?

Um das durch die Verwendung von delay verursachte Problem zu überwinden, sollte ein Entwickler die millis() -Funktion verwenden, die einfach zu verwenden ist, sobald Sie sich daran gewöhnt haben, und die 100% CPU-Leistung verwendet, ohne eine Verzögerung bei der Ausführung der Anweisungen zu erzeugen. millis() ist eine Funktion, die nur die Anzahl der Millisekunden zurückgibt, die vergangen sind, seit das Arduino-Board das aktuelle Programm ausgeführt hat, ohne das Programm einzufrieren. Diese Zeitzahl wird nach ungefähr 50 Tagen überlaufen (dh auf Null zurückgehen).

Genau wie Arduino delayMicroseconds() hat, hat es auch die Micro-Version von millis() als micros(). Der Unterschied zwischen micros und millis besteht darin, dass micros () nach ungefähr 70 Minuten überläuft, verglichen mit millis (), das 50 Tage beträgt. Je nach Anwendung können Sie also millis () oder micros () verwenden.

Using millis() instead of delay():

Um millis() für Timing und Delay zu verwenden, müssen Sie die Zeit, zu der die Aktion stattgefunden hat, aufzeichnen und speichern, um die Zeit zu starten und dann in Intervallen zu überprüfen, ob die definierte Zeit verstrichen ist. Speichern Sie also wie angegeben die aktuelle Zeit in einer Variablen.

unsigned long currentMillis = millis();

Wir benötigen zwei weitere Variablen, um herauszufinden, ob die erforderliche Zeit vergangen ist. Wir haben die aktuelle Zeit in der Variablen currentMillis gespeichert, müssen aber auch wissen, wann der Zeitraum begonnen hat und wie lange der Zeitraum ist. Also wird das Intervall und previousMillis deklariert. Das Intervall teilt uns die Zeitverzögerung mit und previosMillis speichert das letzte Mal, dass das Ereignis aufgetreten ist.

unsigned long previousMillis;unsigned long period = 1000;

Um dies zu verstehen, nehmen wir ein Beispiel für eine einfache blinkende LED. Die Periode = 1000 zeigt an, dass die LED für 1 Sekunde oder 1000 ms blinkt.

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

Hier wird die Anweisung <if (currentMillis – previousMillis >= period)> prüft, ob die 1000ms vergangen sind. Wenn 1000 ms vergangen ist, dann die LED blinken und wieder kommt zu gleichen zustand. Und das geht weiter. Das war’s, wir haben gelernt, Millis anstelle von Delay zu verwenden. Auf diese Weise wird das Programm nicht für ein bestimmtes Intervall angehalten.

Interrupts in Arduino funktionieren genauso wie in anderen Mikrocontrollern. Das Arduino UNO Board verfügt über zwei separate Pins zum Anbringen von Interrupts an GPIO Pin 2 und 3. Wir haben es im Arduino Interrupts Tutorial ausführlich behandelt, wo Sie mehr über Interrupts und deren Verwendung erfahren können.

Hier zeigen wir Arduino Multitasking, indem wir zwei Aufgaben gleichzeitig erledigen. Die Aufgaben umfassen das Blinken von zwei LEDs mit unterschiedlicher Zeitverzögerung sowie einen Druckknopf, mit dem der EIN / AUS-Zustand der LED gesteuert wird. Es werden also drei Aufgaben gleichzeitig ausgeführt.

Schaltplan für Arduino Multitasking

Komponenten Erforderlich

  • Arduino UNO
  • Drei LEDs (Jede Farbe)
  • Widerstände (470, 10 k)
  • Jumper
  • Breadboard

Schaltplan

Der Schaltplan zur Demonstration der Verwendung der Arduino Millis () -Funktion ist sehr einfach und enthält nicht viele Komponenten, wie unten gezeigt.

Schaltplan für Arduino Multitasking mit Arduino Millis() Funktion

Programmierung Arduino UNO für Multitasking

Programmierung Arduino UNO für multitasking wird nur erfordern die logik hinter wie millis() arbeit, die ist oben erklärt. Es wird empfohlen, Blink LED mit millis immer wieder zu üben, um die Logik klar zu machen und sich mit millis () vertraut zu machen, bevor Sie mit der Programmierung von Arduino UNO für Multitasking beginnen. In diesem Tutorial wird der Interrupt auch mit millis () gleichzeitig für Multitasking verwendet. Die Taste wird ein Interrupt sein. Wenn also ein Interrupt erzeugt wird, d. H. Ein Druckknopf gedrückt wird, schaltet die LED in den EIN- oder AUS-Zustand.

Die Programmierung beginnt mit der Angabe von Pin-Nummern, an denen LEDs und Taster angeschlossen sind.

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

Als nächstes schreiben wir eine Variable, um den Status der LEDs für die zukünftige Verwendung zu speichern.

int ledState1 = LOW;int ledState2 = LOW;

Wie oben im Blink-Beispiel erläutert, werden die Variablen für period und previousmillis deklariert, um eine Verzögerung für LEDs zu vergleichen und zu erzeugen. Die erste LED blinkt nach jeweils 1 Sekunde und eine weitere LED blinkt nach 200 ms.

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

Eine weitere Millis-Funktion wird verwendet, um die Entprellverzögerung zu erzeugen, um das mehrfache Drücken der Taste zu vermeiden. Es wird einen ähnlichen Ansatz wie oben geben.

int debouncePeriod = 20; int debounceMillis = 0;

Die drei Variablen werden verwendet, um den Status des Druckknopfes als Interrupt, Toggle-LED und Druckknopfstatus zu speichern.

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

Definieren Sie die Aktion von Pin, welcher Pin als EINGABE oder AUSGABE fungiert.

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

Definieren Sie nun den Interrupt-Pin, indem Sie Interrupt mit Definition von ISR und Interrupt-Modus anhängen. Beachten Sie, dass es empfohlen wird, digitalPinToInterrupt(pin_number) zu verwenden, wenn Sie die Funktion attachInterrupt() deklarieren, um die tatsächliche digitale PIN in die spezifische Interrupt-Nummer zu übersetzen.

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

Das Interrupt-Unterprogramm ist geschrieben und ändert nur das buttonPushed-Flag. Versuchen Sie also, es zu schreiben und die zusätzlichen Anweisungen zu minimieren.

void pushButton_ISR(){ buttonPushed = true; }

Die Schleife beginnt mit dem Speichern des Millis-Werts in einer currentMillis-Variablen, die den Wert der verstrichenen Zeit bei jeder Iteration der Schleife speichert.

unsigned long currentMillis = millis();

Es gibt insgesamt drei Funktionen im Multitasking, blinkt eine LED bei 1 Sekunde, Blinkt zweite LED bei 200ms und Wenn die Drucktaste gedrückt wird, dann schalten Sie die LED AUS / EIN. Also werden wir drei Teile schreiben, um diese Aufgabe zu erledigen.

Der erste schaltet den LED-Status nach jeweils 1 Sekunde um, indem die verstrichenen Millis verglichen werden.

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

In ähnlicher Weise schaltet es die LED nach jeweils 200 ms um, indem es die verstrichenen Millis vergleicht. Die Erklärung wird bereits früher in diesem Artikel erklärt.

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

Zuletzt wird das buttonPushed-Flag überwacht und nach Erzeugung einer Entprellverzögerung von 20 ms wird nur der Status der LED umgeschaltet, der dem als Interrupt angehängten Taster entspricht.

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

Dies beendet das Arduino millis() Tutorial. Beachten Sie, dass Sie, um sich an millis() zu gewöhnen, nur üben, diese Logik in einigen anderen Anwendungen zu implementieren. Sie können es auch erweitern, um Motoren, Servomotoren, Sensoren und andere Peripheriegeräte zu verwenden. Im Zweifelsfall schreiben Sie bitte an unser Forum oder kommentieren Sie unten.

Der vollständige Code und das Video zur Demonstration der Verwendung der Millis-Funktion in Arduino finden Sie unten.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.