Nr. 25 – Der Interrupt-Befehl attachInterrupt()

Aufgabe Nr.  25 : Das Leuchten einer LED durch einen Tastendruck unterbrechen

Material : Arduino, Breadboard, Kabel, Taster (Materialbeschaffung www.funduinoshop.de)

In dieser Aufgabe möchten wir das durchgehende Leuchten einer LED mit Hilfe eines Tasters unterbrechen.
Anschließend soll das Leuchten der LED fortgesetzt werden.

Unser Taster wird an Pin 2 des Arduinos angeschlossen
Unsere LED wird an Pin 13 des Arduinos angeschlossen

 

Doch wie stellen wir dies an?

Bisher haben wir eine LED entweder ein- oder ausgeschaltet (zum Beispiel mit einem delay), doch nie eine bestehende Aktion unterbrochen. Dies gelingt uns nun mit dem sogenannten Interrupt-Befehl.

 

Dieser Befehl lautet zum Beispiel :

"attachInterrupt(0, TasterUnterbricht, CHANGE)".

Die drei Bedingungen in der Klammer legen dabei folgendes fest :

"attachInterrupt(Vektor, Funktion(Brücke), Modus)"
[ attach (engl.) bedeutet anfügen, anhängen]

 

Bedingung Nummer eins, hier die „0“, dient als „Auslöser“ für unseren Interrupt. Dabei ist die Zahl 0 nicht wahllos gewählt. Der UNO Controller verfügt über zwei Pins (Pin 2 und Pin 3), welche mittels eines Interrupts angesteuert werden und somit fortlaufende Aktionen abbrechen können.

Der Zugriff auf die beiden Pins 2 & 3 wird uns ermöglicht, indem wir Sie als sogenannte Vektoren definieren.
Dabei enspricht ein Anschluss an Pin 2 dem Vektor 0 und ein Anschluss an Pin 3 dem Vektor 1Diese Vektoren dienen als variabler Speicher.
In unserem Versuchsaufbau verwenden wir einen Taster, welchen wir an den Pin 2 des Arduinos angeschließen – ergo den Vektor 0.
Damit wir auf diese Variablen Speicher zugreifen können, müssen wir die regulären Variablen (int, float usw.) mit dem Wort „volatile“ erweitern.

volatile int TasterStatus = 0;

Das Wort „volatile“ stammt aus dem englischen und bedeutet soviel wie sprunghaft, schwanked,
unbeständig – irgendwie passend, oder?

 

Die zweite Bedingung, hier die Bezeichnung „TasterUnterbricht“, bildet die „Brücke“ zu unserem Interrupt-Codeabschnitt. Neben dem bereits bekannten void setup() und void loop() verwenden wir nun eine weitere void(), welche wir allerdings selber frei benennen können. In diesem Sketch „TasterUnterbricht“.
Ändert sich also der Status unseres variablen Speichers, so soll der Interrupt „TasterUnterbricht“ ausgeführt werden.

 

Die dritte Bedingung, hier CHANGE“, beschreibt das eingetretene Ereignis, den Tastendruck.
Dieser sogenannte Modus kann in vier verschiedenen Varianten auftreten.

1. LOW = Tritt auf, wenn sich der Wert von HIGH auf LOW ändert
2. CHANGE = Tritt auf, wenn sich der Wert Pin ändert
3. RISING = Tritt auf, wenn sich der Wert DES PINS von LOW auf HIGH ändert
4. FALLING = Tritt auf, wenn sich der Wert DES PINS von HIGH auf LOW ändert

Wie schon  oben bereits erwähnt wurde, verwenden wir in unserem Sketch den Modus „CHANGE“.
Wir möchten also generell erfahren, ob sich der Status unseres Pins (also der Vektor „0“) geändert hat. Sollte dies eintreffen, so soll unser Programm zum Codeabschnitt „void TasterUnterbricht“ springen.

Ein Interrupt dient also dazu, eine fortlaufende Aktion zu unterbrechen, sobald eine von uns zuvor gesetzte Bedingung erfüllt worden ist. Für die Dauer des erfüllten Zustandes der Bedingung wird nun der Interrupt durchgeführt. Sollte die Bedingung, also die von uns im Modus definierte Aktion, nicht mehr eintreffen, soll das Programm an der ursprünglich unterbrochenen Stelle fortgeführt werden.

Der Sketch :

const int Taster = 2;          // Der Taster wurde an Pin 2 angeschlossen
const int LED =  13;           // Die LED wurde an Pin 13 angeschlossen


volatile int TasterStatus = 0;         // Variable die den Status des Taster ausliest, wird der sog. "Vektor" 0 zugewiesen
                                      
                                     
                                       // Taster Anschluss an Pin 2 entspricht dem Vektor 0   (hier der Fall)
                                       // Taster Anschluss an Pin 3 entspricht dem Vektor 1

  

void setup() {

  
          pinMode(LED, OUTPUT);         // Hier wird die LED als OUTPUT definiert
          
          
          pinMode(Taster, INPUT);       // Hier wird der Taster als INPUT definiert

  
          attachInterrupt(0, TasterUnterbricht, CHANGE);   // Hier findet die Einbindung unseres Interrupt-Befehls statt
                                                         

          
                                             
        }


void loop() {
                                           // Hier leer, der eigentliche loop() Teil findet nun in der "void TasterUnterbricht()" statt
}


void TasterUnterbricht() {                 // Sobald die Unterbrechung "TasterUnterbricht" (der Wert am Pin ändert sich [CHANGE])...
  
  TasterStatus = digitalRead(Taster);      // ... wird der TasterStatus neu definiert ("volatile"). Die neue Definition geschieht durch das Auslesen des Tasters an Pin 2. ...
  digitalWrite(LED, TasterStatus);         // ... [digitalWrite(pin,Status)] Nun wird die LED (Pin13) in den zuvor definierten Tasterstatus versetzt.
}