Material: das Mikrocontrollerboard mit dem USB-Kabel, 3 LEDs (rot, gelb, grün), Taster!
Es wird durch den Taster ein Interrupt ausgelöst. Dies ist nur an Pin 2 oder 3 möglich. Durch einen Interrupt wird ein (sequentielles) Programm unterbrochen. Die wenigen Register (Speicher) des
Prozessors werden (auf dem Stapel) gespeichert. Dann wird ein ausgewähltes Unterprogramm aufgerufen. Nach Beendigung des Unterprogramms wird das eigentliche Programm fortgeführt, indem die Register wieder mit den auf dem Stapel gespeicherten Werten
geladen werden.
Interrupts sind erforderlich, um bestimmte Prozesse (z.B. Speicherauffrischung , Eingabeaktionen etc) zeitnah ausführen zu können. Komplexe Prozessoren verfügen über mehrere
Interrupt-Stufen. Nicht maskierbare Interrupts (NMI) werden beispielsweise vom Betriebssystem selbst ständig ausgelöst, weil sie fü den Betrieb eines Computers unabdingbar sind.
Schaltung:
Die Minuspole werden gemeinsam mit grd (ground) verbunden. Die Pluspole der LEDs sind (s. Bild) an den Pins 12 , 9 bzw. 7 angeschlossen.
Im Sketch sollten Sonderzeichen (Umlaute oder Ähnliches) vermieden werden.
Die Ampelphasen: rot - rot-gelb - grün - gelb. Die jeweilige Dauer einer Phase (4 s, 1 s, 4 s, 1 s) ist natürlich veränderbar.
Der Sketch :
| int rot=12; | // Die Pins erhalten aussagekräftige Bezeichnungen |
| int gelb=9; | |
| int gruen=7; | |
| int Taster=2; | // Interrupt-Pin |
| bool flag=false; | boolesche Variable flag wird gesetzt |
| volatile int TasterStatus=0; | //Bedeutung volatile: immer aktuellen Wert im Speicher halten |
| void setup() { | |
|   pinMode(rot, OUTPUT); | // Pins als Ausgang festlegen |
|   pinMode(gelb, OUTPUT); | |
|   pinMode(gruen, OUTPUT); | |
|   pinMode(Taster,INPUT_PULLUP); | // Pin 2 als Interrupt-Pin kennzeichnen |
|   attachInterrupt(digitalPinToInterrupt(Taster),   TasterUnterbricht, FALLING); |
// Bedeutung s. unten |
|   Serial.begin(9600); | // den seriellen Monitor initialisieren |
| } |
| void TasterUnterbricht() { | // Das ist das Unterprogramm |
|   digitalWrite(rot, LOW); | |
|   digitalWrite(gruen, LOW); | |
|   TasterStatus = digitalRead(Taster); | |
|   Serial.println(TasterStatus); | // Taster-Status am seriellen Monitor ausgeben |
|   flag=!flag; | // Die Variable flag invertieren |
| } |
void loop() { |
|
|   digitalWrite(rot,HIGH);   digitalWrite(gelb,LOW);   digitalWrite(gruen,LOW);   delay(4000); |
//Rot-Phase |
|   digitalWrite(rot,HIGH);   digitalWrite(gelb,HIGH);   digitalWrite(gruen,LOW);   delay(1000); |
//Rot-gelb-Phase |
|   digitalWrite(rot,LOW);   digitalWrite(gelb,LOW);   digitalWrite(gruen,HIGH);   delay(4000); |
//Grün-Phase |
|   digitalWrite(rot,LOW);   digitalWrite(gelb,HIGH);   digitalWrite(gruen,LOW);   delay(1000); |
//Gelb-Phase |
|   while (flag) { | |
|     digitalWrite(ledgelb, HIGH);     long k=0;     while (k<60000) {       TasterStatus = digitalRead(Taster);       k=k+1;     }     digitalWrite(ledgelb,LOW);     k=0;     while (k<60000) {       TasterStatus = digitalRead(Taster);       k=k+1;     } |
|
|   } | |
| } |
Anmerkungen
Die Anweisung attachInterrupt erfordert drei Parameter:
    eine Interrupt-Nummer: durch digitalPinToInterrupt(Taster) realisiert
    den Namen des Unterprogramms: TasterUnterbricht
    Modus, wann der Interrupt ausgelöst werden soll
Der Interrupt kann bei steigender, fallender oder bei sich ändernder Flanke ausgelöst werden.
Die kryptischen while-Schleifen while (k<60000) { ...} sind erforderlich, weil delay-Anweisungen nicht in einer Interrupt-Routine funktionieren.
Sie lösen selbst Interrupts aus.
Die Schleifen bewirken eine gewisse Pause - sie ersetzen einfache delay-Anweisungen.
Die Variable k ist vom Typ long, weil int-Variablen nur ganze Zahlen von -32768-32767 darstellen können.long-Variablen umfassen einen größeren Zahlenbereich ganzer Zahlen.
Im Unterprogramm TasterUnterbricht wird nur die Variable flag invertiert. Nur wenn der Wert von flag true ist, wird das Blinklicht ausgelöst bzw. umgeschaltet.
Das Blinklicht wird aber erst nach einem kompletten Ampel-Durchgang ausgelöst.
Die Darstellung der Werte der beiden Variablen im seriellen Monitor ist nicht erforderlich.
Sie dient nur der Kontrolle.