Diese Seite ist auch in 2 anderen Sprachen verfügbar.

attachInterrupt()

[External Interrupts]

Beschreibung

Digitalpins, die Interrupts unterstützen

Der erste Parameter von attachInterrupt() ist die Interruptnummer. Im Normalfall solltest du digitalPinToInterrupt(pin) benutzen, um die tatsächlichen Digitalpins auf die Interruptnummer umzuwandeln. Wenn du z.B. auf Pin 3 verbinden willst, benutze digitalPinToInterrupt(3) als ersten Parameter für attachInterrupt().

Board Benutzbare Digitalpins für Interrupts

Uno, Nano, Mini, andere 328-basierte

2, 3

Uno WiFi Rev.2

Alle Digital-Pins

Uno WiFi Rev.2, Nano Every

Alle Digital-Pins

Mega, Mega2560, MegaADK

2, 3, 18, 19, 20, 21

Micro, Leonardo, andere 32u4-basierte

0, 1, 2, 3, 7

Zero

Alle Digital-Pins außer Pin 4

MKR Family-Boards

0, 1, 4, 5, 6, 7, 8, 9, A1, A2

Nano 33 IoT

2, 3, 9, 10, 11, 13, 15, A5, A7

Nano 33 BLE, Nano 33 BLE Sense

Alle Pins

Due

Alle Digital-Pins

101

Alle Digital-Pins (Nur Pins 2, 5, 7, 8, 10, 11, 12, 13 funktionieren mit CHANGE)

Anmerkungen und Warnungen

Innerhalb der vom Interrupt ausgelösten Funktion wird delay() nicht funktionieren und millis() nicht hochzählen. Empfangene Serielle Daten in der Funktion können verloren gehen. Variablen, die innerhalb der Funktion verarbeitet werden, sollten als volatile gekennzeichnet werden. Siehe dazu auch den Abschnitt zu Interrupt Service Routinen weiter unten.

Benutzung von Interrupts

Interrupts sind nützlich, um bestimmte Tasks in Microkontrollerprogrammen automatisch ablaufen zu lassen und können helfen, Timingprobleme zu lösen. Gute Beispiele dafür sind das Lesen eines Drehgebers sowie das Einlesen von Benutzereinaben.

Wenn du z.B. sicherstellen willst, dass das Programm alle Stromimpulse eines Drehgebers messen kann, wäre es sehr schwer ein Programm zu schreiben, das noch andere Aufgaben zusätzlich erfüllt, weil das Programm sonst immer den Sensor pollen (d.h. permanent abfragen) müsste. Andere Sensoren haben eine ähnliche Interfacedynamik: Das Auslesen eines Geräuschsensors oder eines Infrarotsensors funktioniert ähnlich. Interrupts können dabei helfen, dass der Microkontroller andere weitere Aufgaben zusätzlich ausführen kann, trotzdem aber keine Eingaben verliert.

Über Interrupt Service Routinen

Interrupt Service Routinen sind spezielle Funktionen, die einige eindeutige Limitierungen haben als "normale" Funktionen: Interrupt Service Routinen können keine Parameter besitzen und sollten nichts zurückgeben. Interrupt Service Routinen sollten generell so kurz und schnell wie möglich sein.

Wenn dein Sketch mehrere Interrupt Service Routinen benutzt, kann nur eine auf einmal laufen. Andere Interrupts werden aufgerufen, nachdem die erste Interrupt Service Routine beendet ist. Die Reihenfolge hängt dabei von der Priorität der Routinen ab.

millis() verlässt sich zum Zählen auf Interrupts, wird also in einer Interrupt Service Routine niemels hochzählen. delay() benutzt ebenfalls Interrupts und wird deshalb gar nicht in einer Interrupt Service Routine funktionieren. micros() wird anfangs gut funktionieren, aber nach circa 1 bis 2 ms sich unvorhersehbar verhalten. delayMicroseconds() benutzt keine Zähler und wird deshalb normal funktionieren.

Normalerweise werden globale Variablen benutzt, um Daten zwischen Interrupt Service Routinen und dem Hauptprogramm zu tauschen. Dass die Variablen dabei korrekt geändert werden, sollten sie als volatile deklariert werden.

Für weitere Informationen zu Interrupts, siehe auch Nick Gammon’s Anmerkungen.

Syntax

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) (Empfohlen)
attachInterrupt(interrupt, ISR, mode) (Nicht empfohlen)
attachInterrupt(pin, ISR, mode) (Nicht empfohlen; Funktioniert nur auf Arduino SAMD-, Uno WiFi Rev2-, Due- und 101-Boards.)

Parameter

interrupt: Die Interruptnummer. Erlaubte Datentypen: int.+ pin: Die Arduino-Pinnummer.
ISR: Die Interrupt Service Routine, die aufgerufen werden soll. Die Funktion darf keine Parameter haben und nichts zurückgeben.
mode: Definiert, wann der Interrupt getriggert werden soll. 4 Konstanten sind dafür definiert:

  • LOW Interrupt wird getriggert, wenn der Pin LOW ist,

  • CHANGE Interrupt wird getriggert, wenn der Pin den Wert ändert

  • RISING Interrupt wird getriggert, wenn der Pin von LOW auf HIGH wechselt,

  • FALLING Interrupt wird getriggert, wenn der Pin von HIGH auf LOW wechselt.
    Die Due-, Zero- und MKR1000-Boards erlauben zusätzlich:

  • HIGH Interrupt wird getriggert, wenn der Pin HIGH ist.

Rückgabewert

Nichts.

Beispielcode

Lässt eine LED blinken.

// Setze den Pin für die LED auf 13
const byte ledPin = 13;
// Setze den Interruptpin auf 2
const byte interruptPin = 2;
// Definiere eine globale volatile Variable für den Status der LED
volatile byte state = LOW;

void setup() {
  // Lege den Pin für die LED als Outputpin fest
  pinMode(ledPin, OUTPUT);
  // Lege den Interruptpin als Inputpin mit Pullupwiderstand fest
  pinMode(interruptPin, INPUT_PULLUP);
  // Lege die ISR 'blink' auf den Interruptpin mit Modus 'CHANGE':
  // "Bei wechselnder Flanke auf dem Interruptpin" --> "Führe die ISR aus"
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}

void loop() {
  // Schreibe den Status der LED auf den LED-Pin zurück:
  // "Schalte die LED an oder aus"
  digitalWrite(ledPin, state);
}

void blink() {
  // Invertiere den Status: "Lass die LED blinken von HIGH auf LOW/ an auf aus"
  state = !state;
}

Interruptnummern

Im Normalfall solltest du digitalPinToInterrupt(pin) benutzen anstatt den Interruptnummer direkt zu setzen. Die Interruptpins und deren Mapping variiert von Board zu Board. Wenn der Sketch also auf einem anderen Board ausgeführt werden soll, kann es schnell zu Problemen kommen.

Alte Sketches haben oft direkte Interruptnummern angegeben. Oft wurden Pin 0 (Digitalpin 2) oder Pin 1 (Digitalpin 3) verwendet. Die Tabelle unten zeigt, welche Interruptpins auf welchem Board verfügbar sind.

In der Tabelle unten sind die Interruptpins definiert als die Nummer, die an attachInterrupt() übergeben wird. Aus historischen Gründen stimmt diese Nummerierung nicht immer mit den Inputnummern auf dem ATmega-Chip überein (z.B. int.0 ist INT4 auf dem ATmega2560-Chip).

Board int.0 int.1 int.2 int.3 int.4 int.5

Uno, Ethernet

2

3

Mega2560

2

3

21

20

19

18

32u4 based (e.g Leonardo, Micro)

3

2

0

1

7

Für Due, Zero, MKR1000 und 101 Boards gilt: Interruptnummer = Pinnummer.

Siehe auch