Bastelprojekt 4:
Blinken mit Intervallsteuerung
Im Bastelprojekt 1zur Ansteuerung einer LED hast du gesehen, wie wir über die Verzögerungsfunktion delay eine Unterbrechung in der Ausführung des Sketches an der betreffenden Stelle hervorgerufen haben. Die angeschlossene LED an dem digitalen Pin blinkte in regelmäßigen Abständen. Eine solche Schaltung und Programmierung hat jedoch einen entscheidenden Nachteil, den wir zuerst erkennen und dann beheben wollen. Wir müssen die Blinkschaltung dazu ein wenig modifizieren und erweitern.
Drücke den Taster – und er reagiert
Was geschähe wohl, wenn du an einem anderen digitalen Eingang zusätzlich einen Taster anschließen würdest, um dann seinen Zustand kontinuierlich abzufragen? Wenn du diesen Taster drückst, soll zeitgleich eine weitere LED leuchten. Vielleicht ahnst du schon, worauf ich hinausmöchte. Solange die Sketch-Ausführung in der delay -Funktion gefangen ist, wird die Abarbeitung des Codes unterbrochen und der digitale Eingang kann demnach nicht abgefragt werden. Du drückst also den Taster und es passiert einfach nichts.
Für dieses Bastelprojekt benötigen wir die folgenden Bauteile:
Tabelle 1: Bauteilliste |
Bauteil |
Bild |
LED rot 1x |
 |
LED gelb 1x |
 |
Mikrotaster 1x |
 |
Widerstand 330Ω 1x |
 |
Widerstand 10KΩ 1x |
 |
Der Schaltplan zeigt uns zur Gewährleistung eines sicheren Eingangspegels einen externen Pulldown-Widerstand am digitalen Pin 8:
Abb. 1:Der Schaltplan zur Abfrage des Tasters und Ansteuerung der LEDs
Auf dem Arduino Discoveryboard werden in diesem Bastelprojekt ein paar Bauteile mehr zum Einsatz kommen:
Abb. 2:Der Schaltungsaufbau zur Tasterabfrage
Mit diesem Schaltungsaufbau wenden wir uns dem Sketch zu.
Vorwarnung: Der folgende Sketch funktioniert nicht so, wie wir es vielleicht erwarten.
// Der Sketch funktioniert nicht wie erhofft int ledPinBlink = 13; // Rote Blink-LED Pin 13 int ledPinTaster = 10; // Gelbe Taster-LED Pin 10 int tasterPin = 8; // Taster Pin 8 int tasterStatus; // Variable für Tasterstatus void setup() { pinMode(ledPinBlink, OUTPUT); // Blink-LED Pin als Ausgang pinMode(ledPinTaster, OUTPUT); // Taster-LED Pin als Ausgang pinMode(tasterPin, INPUT); // Taster-Pin als Eingang } void loop() { // Blink-LED blinken lassen digitalWrite(ledPinBlink, HIGH); // Rote LED HIGH-Pegel delay(1000); // 1 Sek. warten digitalWrite(ledPinBlink, LOW); // Rote LED LOW-Pegel delay(1000); // 1 Sek. warten // Abfrage des Taster-Status tasterStatus = digitalRead(tasterPin); if(tasterStatus == HIGH) digitalWrite(ledPinTaster, HIGH); // Gelbe LED HIGH-Pegel else digitalWrite(ledPinTaster, LOW); // Gelbe LED LOW-Pegel }
Warum funktioniert der Sketch denn nicht wie erwartet? Die Ausführung in der Endlosschleife kommt doch irgendwann einmal an der Zeile für die Tasterabfrage vorbei. Dann wird der Status doch korrekt abgefragt. Das entscheidende Wörtchen, das hier verwendet wird, ist irgendwann ! Du möchtest aber sicherlich einen Sketch so programmieren, dass zu jedem Zeitpunkt der Verarbeitung auf einen Tastendruck reagiert wird und nicht nur irgendwann einmal, wenn die Ausführung des Codes gerade die betreffende Stelle erreicht. Die delay -Funktion behindert uns bei der Fortführung des Codes und kann hier nicht die erste Wahl sein. Ich zeige dir das Verhalten am besten anhand eines Impulsdiagramms, bei dem die relevanten Signale wie Pin 13 (Blink-LED), Pin 8 (Taster) und Pin 10 (Taster-LED) untereinander zu sehen sind:
Abb. 3:Das Impulsdiagramm der Signale an Pin 13, Pin 8 und Pin 10
Das oberste Signal (hier blau) zeigt den Status der blinkenden LED an Pin 13, der unermüdlich im Sekundentakt zwischen HIGH - und LOW -Pegel wechselt. Das darunter liegende Signal (hier lila) zeigt den Pegel am Taster an Pin 8, der nun versucht, die Taster-LED an Pin 10 zu steuern. Das unterste Signal sollte also zeitgleich mit dem Signal am Taster den Pegel wechseln, was aber nicht der Fall ist. Ich habe vier markante rote Punkte in diesem Diagramm platziert. An Punkt
halte ich den Taster so lange gedrückt, dass ich die abfallende Flanke des Blink-Signals erwische. Warum reagiert die Taster-LED an Pin 10 hier nicht? Das ist ganz einfach, denn wir haben es mit zwei delay -Aufrufen zu tun. Bei einem Wechsel von HIGH zu LOW wird die erste delay -Funktion abgearbeitet und wir stecken quasi noch in der zweiten delay -Funktion fest. Ein Tastendruck wird also hier nicht abgefragt. Das geschieht erst an Punkt
, wo ich die Taste beim Pegelwechsel von LOW zu HIGH gedrückt halte. Bevor es zum weiteren Pegelwechsel geht, erfolgt die Abfrage des digitalen Pins 8, an dem sich der Taster befindet. Jetzt kann der Status des Tasters ausgewertet werden und die Taster-LED an Pin 10 leuchtet. Das ist so lange der Fall, bis bei der ansteigenden Flanke der Blink-LED der Taster ein LOW -Signal hat, was erst bei Punkt
der Fall ist und nicht schon bei Punkt
. Aus diesem Grund müssen wir auf die Verwendung der delay -Funktion verzichten und einen anderen Weg wählen.
Sehen wir uns den folgenden Sketch an und lassen uns nicht durch die Anzahl der Codezeilen irritieren, denn wir gehen alles Schritt für Schritt durch:
// Der Sketch funktioniert wie erhofft int ledPinBlink = 13; // Rote Blink-LED Pin 13 int ledPinTaster = 10; // Gelbe Taster-LED Pin 10 int tasterPin = 8; // Taster Pin 8 int tasterStatus; // Variable für Tasterstatus int interval = 2000; // Intervalzeit (2 Sekunden) unsigned long prev; // Zeit-Variable int ledStatus = LOW; // Statusvariable für die Blink-LED void setup() { pinMode(ledPinBlink, OUTPUT); // Blink-LED-Pin als Ausgang pinMode(ledPinTaster, OUTPUT); // Taster-LED-Pin als Ausgang pinMode(tasterPin, INPUT); // Taster-Pin als Eingang prev = millis(); // Jetzigen Zeitstempel merken } void loop() { // Blink-LED über Intervalsteuerung blinken lassen if((millis() - prev) > interval) { prev = millis(); ledStatus = !ledStatus; // Toggeln des LED-Status digitalWrite(ledPinBlink, ledStatus); // Toggeln der roten LED } // Abfrage des Tasterstatus tasterStatus = digitalRead(tasterPin); if(tasterStatus == HIGH) digitalWrite(ledPinTaster, HIGH); // Gelbe LED HIGH-Pegel else digitalWrite(ledPinTaster, LOW); // Gelbe LED auf LOW-Pegel }
Читать дальше