Donnerstag, 18. Juni 2015

Interrupts mit dem Arduino

Manchmal ist es sinnvoll, dass eine laufende Aktion unterbrochen wird, damit kurz etwas Anderes ausgeführt wird. Beispielsweise wenn man in einer Schleife ist und dann ein User plötzlich einen Button drückt. Dann soll erst die, mit dem Button verknüpfte, Aktion ausgeführt werden, und dann die Schleife weiter ausgeführt werden. Genau dafür sind Interrupts.


Die Verwendung von Interrupts auf der Arduino Plattform


Auf dem Arduino Uno sind nicht alle Pins dazu geeignet als Interrupt Signal zu dienen. Das funktioniert nur mit Pin 2, Interrupt Pin 0, und Pin 3, Interrupt Pin 1. An anderen Arduinos sind es andere Pins, der Arduino Due kann mit Interrupts auf allen Pins umgehen. Die genaue Auflistung gibt es auf arduino.cc. Wenn man einen Interrupt verwenden will, muss man das bereits im Setup Teil festlegen. Dazu gibt es die Funktion attachInterrupt();. Diese braucht als erstes Argument(Werte in der Klammer, nach Name der Funktion) den Interrupt Pin, also 0 oder 1. Als Zweites muss die Funktion angegeben werden, die ausgeführt werden soll, wenn eine Bedingung zutrifft. Das dritte Argument ist die Bedingung, die entscheidet, ob die angegebene Funktion ausgeführt werden soll. Am Arduino Uno gibt es vier Möglichkeiten. LOW, HIGH, RISING, FALLING. LOW und HIGH sind, denke ich einmal, klar. RISING bedeutet, dass sobald die Spannung, die beispielsweise ein Button, leitet steigt, die Funktion aufgerufen wird. FALLING ist das exakte Gegenteil, also sobald die Spannung sinkt. Sobald also die Bedingung wahr ist, was automatisch laufend überprüft wird, wird die aktuelle Zeile im Sketch abgebrochen, die angegebene Funktion aufgerufen, und dann die vorherige Zeile, und der ganze Sketch regulär weiter ausgeführt. 

Das Definieren der "Interruptfunktion"

Im Setup Teil wird durch attachInterrupt() eine Funktion angegeben, die ausgeführt werden soll, wenn die Bedingung wahr ist. Diese muss aber auch definiert werden. Dazu muss man erst auswählen, ob die aufgerufene Funktion etwas zurückgeben soll, oder nicht. Interruptfunktionen geben nie etwas zurück. Nichts zurückgeben bedeutet void. Dann muss der Name der Funktion kommen mit Klammern. In diese können die Argumente geschrieben werden, die die Funktion benötigt. Auch das ist bei Interruptfunktionen leer. Also (). In die nachfolgenden, geschweiften, Klammern wird der eigentlich Programmcode der Funktion geschrieben. Eine weitere Besonderheit bei Interrupts ist, dass Variablen, die in einem Interrupt verwendet werden immer ein volatile vor dem Datentyp bei der Definition brauchen.

Eine LED per Interrupt zum Leuchten bringen

Ein Beispiel, wo man einen Interrupt verwenden könnte, ist um eine LED, unabhängig vom Loop Teil, an-/auszuschalten. Im Loop Teil blinkt, bei mir, einfach nur eine LED. Der Sketch, mit Interrupt, sieht so :
Die Verkabelung ist auch ganz normal, und wie im Sketch angegeben:
Wenn man nun auf den Button drückt schaltet sich die LED an. Sobald man den Button wieder los lässt, schaltet sich die LED wieder aus.

Kommentare:

  1. Der Arduino bietet mehr als die beschriebenen Interrupts. Alle Interrupts des ATmega328 stehen auch im Arduino Umfeld zur Verfügung.
    In meinem Buch "Arduino - Hard- und Software Open Source Plattform" habe ich u.a. die folgenden Interrupts an Hand von Programmbeispielen beschrieben: INT0, INT1, PCINTx, Timer - und Watchdog-Interrupt, Analog Comparator und AD-Umsetzer.

    AntwortenLöschen
  2. Danke für den Hinweis! :) Das kommt dann vielleicht in einem der nächsten Artikel, dieser Post soll nur den Einstieg darstellen.

    AntwortenLöschen
  3. Das ist Ok. Der Einstieg ist auf jeden Fall gelungen.

    AntwortenLöschen