Programmablauf mit Interrupts steuern
Um auf eine Tastenbetätigung zu reagieren, müssen wir die Taste fortlaufend mit 'digitalRead()' abfragen. In jedem Loop von neuem. Dabei darf das weitere Programm im 'Loop' auch nicht zu lange sein. Sonst kann es passieren, das das Programm beim Betätigen der Taste noch mit anderen Aufgaben beschäftigt ist und den Tastendruck überhaupt nicht registriert (…und somit darauf auch nicht reagiert). Abhilfe schaffen Interrupts. Ein Interrupt (=Unterbrechungen) ist ein Mechanismus, welcher den Prozessor informiert den normalen Programmablauf kurz zu unterbrechen, dann zunächst die Interrupt-Routine dazwischenzuschieben und erst dann wieder mit dem normalen Programmablauf weiterzumachen. Die Interrupt-Service Routine (ISR) muss vom Prozessor nicht fortlaufend abgefragt werden. Das Ereignis wird von außen getriggert und dem Prozessor dann gemeldet. ISR werden für Real-Time Ereignisse und Multitasking Ausgaben verwendet.
Es gibt 3 Arten von Interrupt-Ereignissen
- External-Interrupt
- PinChange-Interrupt
- Timer-Interrupt
External Interrupts
Der Arduino Uno hat zwei externe Interrupts (Pin 2 und Pin 3). Definiert man diese Eingänge als Interrupt
(mit
attachInterrupt(digitalPinToInterrupt(2 oder 3), Funktion, Auslöser) )
werden sie außerhalb der loop()-Schleife ständig kontrolliert. Liegt am Interrupt dann ein entsprechender
vorher definierter Zustand an wird die loop()-Schleife unterbrochen und die Interrupt-Funktion ausgeführt.
Der Interrupt -Funktion (ISR) sollte, um das Hauptprogramm nicht unnötig lange zu unterbrechen, so kurz wie
möglich sein.
Als "Auslöser" kann LOW, FALLING, RISING oder CHANGE angegeben werden.
Programmcode
Das eingebaute LED blinkt. Wenn man die Taste drückt wird die Interrupt Service Routine (ISR) ausgelöst und das blinken wird beendet. Beim erneuten drücken fängt die LED wieder an zu blinken. Da die Variable "zustand" von außerhalb des normalen Programms geändert werden kann wird diese mit "volatile" gekennzeichnet.
#define TASTE 2
volatile bool zustand = true;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(TASTE, INPUT_PULLUP);
attachInterrupt(0, meineIRFunktion, LOW);
}
void loop() {
while (zustand == true) {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}
}
void meineIRFunktion() {
zustand = !zustand;
}