Fragwürdige Anweisungen

vor 3 years 4 weeks
Als nächstes wollen wir Ein- und Ausgaben (Inputs, Outputs) miteinander kombinieren. Wir werden ein einfaches, digital gesteuertes Licht bauen. Der Sketch den wir dazu benötigen soll folgendes tun: Wenn der Schalter gedrückt ist, soll die LED leuchten. Wir können das auch noch genauer ausdrücken: Wenn der Schalter gedrückt ist, soll die LED leuchten. Wenn der Schalter nicht gedrückt ist, soll die LED nicht leuchten. Baue die Schaltung nach. Auf einem Protoshield sieht das dann so aus: Kopiere den folgenden Sketch in deine Arduino-Software und lade ihn auf den Arduino hoch. Überprüfe, ob die LED leuchtet, wenn der Schalter gedrückt ist und dass sie erlischt, sobald der Schalter nicht gedrückt ist. Falls es nicht wie erwartet funktioniert, verwende die println Anweisung, um den Fehler zu finden (debuggen). Gebe eine Meldung aus, sobald der Schalter gedrückt wird. So kannst du herausfinden, ob der Fehler in dem Eingabe- oder in dem Ausgabeteil liegt. (Wird die Schalterbetätigung erkannt oder kann die LED nicht angesteuert werden).
/* * Schalter und LED Test Programm */ int ledPin = 12; // LED ist mit Pin 12 verbunden int switchPin = 2; // Schalter ist mit Pin 2 verbunden int val; // Variable für den Pin Zustand   void setup() { pinMode(ledPin, OUTPUT); // LED-Pin wird als Output verwendet pinMode(switchPin, INPUT); // Schalter-Pin wird als Input verwendet }   void loop(){ val = digitalRead(switchPin); // Input lesen und in val speichern if (val == LOW) { // Ist der Schalter gedrückt digitalWrite(ledPin, HIGH); // LED einschalten } if (val == HIGH) { // Ist der Schalter nicht gedrückt digitalWrite(ledPin, LOW); // LED ausschalten } }
Dieser Sketch führt eine neue, interessante Einweisung ein, die if Anweisung. Dies ist eine logische Anweisung, welche vielleicht schon aus dem Mathematikunterricht bekannt ist. Bis jetzt kannten wir nur Anweisungen, die LEDs blinken ließen oder Meldungen ausgaben etc. Jetzt können wir zusätzlich Entscheidungen fällen. if (Bedingung) {Anweisungen, wenn die Bedingung wahr ist} if (val == LOW) { digitalWrite(ledPin, High); } Die if Anweisung ist die erste Bedingungsanweisung (conditional statement). Die folgende Anweisung wird nur dann ausgeführt, falls die Bedingung wahr ist. In unserem Fall ist die Bedingung "Ist der Schalter gedrückt?" oder "Ist der Schalter nicht gedrückt?". Einige Bedingungstests... Operator Definition Beispiel
==
Test auf Gleichheit
  if (foo == 5) { Serial.print("Foo ist gleich 5"); }
Nicht mit dem Zuweisungsoperator = verwechseln!
!=
Test auf Ungleichheit
if (digitalRead(buttonPin) != LOW) { Serial.print("Der Schalter ist nicht LOW "); }
>
Größer als Test
  if ( var2 > 10 ) { Serial.print("Variable 2 ist größer als 10"); }
<
Kleiner als Test
if ( arduinoLager < 10 ) { Serial.print("Wir haben weniger als 10 Arduinos auf Lager"); }
<=
Kleiner-oder-gleich Test
  if ( 20 <= lebensJahre ) { Serial.print("Gute Nachrichten, Sie werden noch mindestens 20 Jahre leben!!"); }
>=
Größer-oder-gleich Test
  if ( katzeWaschen() >= 6 ) { Serial.print("katzenWaschen() hat eine Zahl größer oder gleich 6 geliefert"); }
Blitz Quiz
  • Verändere den Sketch so, dass er genau das Gegenteil tut. Wenn der Schalter gedrückt wird, soll die LED ausgehen und die LED soll angehen, wenn der Schalter nicht mehr gedrückt ist. Es soll nur der Sketch geändert werden, nicht die Schaltung Markiere die folgenden Zeilen mit der Maus, um die Antwort zu sehen! Vertausche die Zeilen digitalWrite(ledPin, HIGH); und digitalWrite(ledPin, LOW);
  • Verändere den Sketch so, dass die LED 5 mal in der Sekunde blinkt (100ms an 100ms aus), wenn der Schalter gedrückt wird und komplett aus ist, wenn der Schalter nicht gedrückt wird Markiere die folgenden Zeilen mit der Maus, um die Antwort zu sehen! /* * Schalter und LED Test Programm */ int ledPin = 12; // LED ist mit Pin 12 verbunden int switchPin = 2; // Schalter ist mit Pin 2 verbunden int val; // Variable für den Pin Zustand void setup() { pinMode(ledPin, OUTPUT); // LED-Pin wird als Output verwendet pinMode(switchPin, INPUT); // Schalter-Pin wird als Input verwendet } void loop(){ val = digitalRead(switchPin); // Input lesen und in val speichern if (val == LOW) { // Ist der Schalter gedrückt digitalWrite(ledPin, HIGH); // LED einschalten delay(100); digitalWrite(ledPin, LOW); // LED ausschalten delay(100); } } Beachte, dass du nichts tun musst, wenn switchPin auf HIGH steht, weil am Ende der Anweisung "val == LOW" die LED ausgeschaltet wird!
Jetzt bist du an der Reihe: schließe eine weitere, rote LED mit einem Widerstand an Pin 11 an. Verändere den Sketch so, dass bei einem Schalterdruck eine LED an und die andere aus ist. Wenn der Schalter losgelassen wird, soll die erste LED aus sein und die zweite an. Versuche die Schaltung auf dem Protoshield nachzubauen. Falls dir das schwer fällt, klicke hier um ein Foto des Schaltungsaufbaus zu sehen. Hier ist eine mögliche Lösung für den Sketch:
/* * Switch and 2 LED test program */ int led1Pin = 12; // LED #1 ist mit Pin 12 verbunden int led2Pin = 11; // LED #2 ist mit Pin 11 verbunden int switchPin = 2; // Schalter ist mit Pin 2 verbunden int val; // Variable für Pin-Zustand   void setup() { pinMode(led1Pin, OUTPUT); // Pin von LED #1 ist Output pinMode(led2Pin, OUTPUT); // Pin von LED #2 ist Output pinMode(switchPin, INPUT); // Schalter-Pin ist Input }   void loop(){ val = digitalRead(switchPin); // Wert des Inputs lesen und in val speichern if (val == LOW) { // Ist der Schalter gedrückt? digitalWrite(led1Pin, HIGH); // LED #1 einschalten digitalWrite(led2Pin, LOW); // LED #2 ausschalten }   if (val == HIGH) { // Ist der Schalter nicht gedrückt? digitalWrite(led1Pin, LOW); // LED #1 ausschalten digitalWrite(led2Pin, HIGH); // LED #2 einschalten } }
Wenn... sonst...! Eine LED durch einen Schalterdruck ein- oder auszuschalten ist schon sehr beeindruckend, aber es würde beispielsweise nerven, einen Schalter ständig gedrückt zu halten, um Fernsehen zu schauen. Was wir jetzt brauchen ist ein Schalter mit wechselnden Aktionen. Bei jedem Drücken und Loslassen des Schalters soll etwas getan werden und nicht nur dann, wenn der Schalter gedrückt wird. Wir wollen also feststellen, ob der Schalter gerade gedrückt oder losgelassen wurde. Um das zu erreichen, müssen wir uns den Wert des Inputs merken, um zu sehen, ob er sich verändert hat. Wir merken uns also den Status (state) des Schalters. Wenn sich der Zustand ändert (ein Auslöser tritt ein), dann wollen wir eine Aktion ausführen.
/* * Wechselnder Schalter */ int switchPin = 2; // Schalter an Pin 2 int val; // Variable für den Pin-Zustand int buttonState; // Variable für den letzten Schalterzustand   void setup() { pinMode(switchPin, INPUT); // Schalter-Pin ist Input Serial.begin(9600); // Start der seriellen Kommunikation mit 9600bps buttonState = digitalRead(switchPin); // Anfangszustand lesen }   void loop(){ val = digitalRead(switchPin); // Eingabewert lesen und in val speichern if (val != buttonState) { // Der Zustand des Schalters hat sich verändert if (val == LOW) { // Ist der Schalter gedrückt? Serial.println("Schalter gedrueckt"); } else { // der Schalter ist nicht gedrückt Serial.println("Schalter nicht gedrueckt"); } } buttonState = val; // Den Zustand merken }
Übertrage diesen Sketch auf deinen Arduino und probiere in aus. Beobachte den seriellen Monitor wenn du den Schalter drückst und wieder loslässt. Schauen wir uns die neuen Code-Zeile an:
int buttonState; // Variable für den letzten Schalterzustand
Diese Zeile ist nicht ungewöhnlich, hier wird nur eine Variable eingerichtet, um den Zustand des Schalters zu merken. Solange wir nicht wissen, in welchem Zustand sich der Schalter befindet, wenn der Arduino das erste Mal eingeschaltet wird, lassen wir es als unbekannt stehen (nicht initialisiert)
buttonState = digitalRead(switchPin); // Anfangszustand lesen
In der setup() Prozedur initialisieren (= Startwert setzen) wir die Variable mit dem Schalterzustand durch das Lesen des Schalterwertes sobald der Sketch startet und wir den Schalter-Pin als Input gesetzt haben.
void loop(){ val = digitalRead(switchPin); // Eingabewert lesen und in val
Jetzt kommt der interessante Teil. In der loop() Prozedur checken wir als Erstes den Zustand des Schalter-Pins und speichern ihn in der Variablen val.
if (val != buttonState) { // Der Zustand des Schalters hat sich verändert if (val == LOW) { // Ist der Schalter gedrückt?
Jetzt kommen zwei ineinander verschachtelte if Anweisungen. Das bedeutet, dass wir erst die erste Bedingung prüfen und wenn diese erfolgreich ist, wir die zweite Bedingung prüfen. Das ist etwas komplexer als eine einfache if Anweisung aber nicht so sehr unterschiedlich zu dem, was wir tagtäglich machen. Zum Beispiel:
if ( es regnet ) { // Fällt Wasser vom Himmel? if ( Ich habe einen Schirm ) { // Prüfe meine Siebensachen AufspannenSchirm(); // Führe die Prozedur zum Schirmöffnen aus } }
Selbstverständlich können wir keinen Schirm öffnen, wenn wir gar keinen dabei haben. Und es macht keinen Sinn, das zu überprüfen, falls es nicht regnet. In der ersten if Anweisung, prüfen wir, ob der Zustand des Schalters (HIGH oder LOW) sich von dem zuletzt gemerkten unterscheidet. Wenn er sich unterscheidet (Überprüfung durch den Ungleich-Operatior !=), dann wird die nächste Gruppe von Anweisungen in den geschweiften Klammern { und } ausgeführt. Schauen wir uns die nächsten Code-Zeilen an und finden heraus, was diese exotische if-else Anweisung macht.
if (val == LOW) { // Ist der Schalter gedrückt? Serial.println("Schalter gedrueckt"); } else { // der Schalter ist nicht gedrückt Serial.println("Schalter nicht gedrueckt"); }
Diese Anweisung ist einfach zu verstehen: bisher haben wir bei erfolgreicher Prüfung einer if-Bedingung immer die in den geschweiften Klammern stehenden Anweisungen ausgeführt. Jetzt haben wir eine Alternative für den Fall, dass die if-Bedingung nicht erfolgreich geprüft wurde. Wir prüfen jetzt also zwei Bedingungen, eine für (val == LOW) und eine für (val == HIGH). Anstatt zwei if-Anweisunge zu schreiben, können wir eine if-else Anweisung schreiben. Beide führen zu dem gleichen Ergebnis. if-else ist aber unkomplizierter. Wenn val nicht HIGH ist, muss es LOW sein. if (Bedingung) {Anweisungen, wenn Bedingung wahr ist} else {Anweisungen, wenn Bedingung nicht wahr ist} if (val == LOW) { ... } else { ... } In der if-else Anweisung, überprüfen wir ganz einfach val. um festzustellen, welchen Wert uns digitalRead() zuletzt geliefert hat.
buttonState = val; // Den Zustand merken
Zum Schluss merken wir und den gerade verarbeiteten Zustand als letzten bekannten Zustand des Schalters. Blitz Quiz
  • Entferne oder kommentiere die Zeile buttonState = val; aus. Übertrage den Sketch erneut auf den Arduino. Was passiert jetzt? Markiere die folgenden Zeilen mit der Maus, um die Antwort zu sehen! Wenn der Schalter gedrückt wird, wird "Schalter gedrueckt" immer wieder ausgegeben. Wenn er nicht gedrückt ist, wird gar nichts ausgegeben
  • Warum ist das so? Gehe den Sketch durch und überlege dir, welche Werte die Variablen buttonState und val in jeder Zeile haben. Markiere die folgenden Zeilen mit der Maus, um die Antwort zu sehen! Wenn der Arduino startet ist buttonState auf LOW (vorausgesetzt, der Schalter ist bei einem Reset oder Neustart des Arduinos nicht gedrückt). Jedesmal, wenn der Schalter im Zustand HIGH gelesen wird, wird die Bedingung (val != buttonState) erfolgreich getestet und die Meldung ausgegeben. Die Variable buttonState wird nie auf den Wert HIGH gesetzt. Deshalb wird auch nie die Meldung "Schalter nicht gedrueckt" ausgegeben und die Bedingung (val != buttonState) immer erfolgreich getestet.

0 Antworten auf “Fragwürdige Anweisungen”