Lektion 12 – Der Taster und if-Abfrage

Das Programm soll die LED einschalten, wenn der Taster gedrückt wird und abschalten, wenn der Taster nicht mehr gedrückt wird. Ich schlage vor, wir starten mit unserem Blink-Beispiel.

int ledPin = 9;

void setup(){
  pinMode(ledPin,OUTPUT);
}

void loop(){
  digitalWrite(ledPin, HIGH);
  delay(200);
  digitalWrite(ledPin, LOW);
  delay(200);
}

Das Programm kennst du ja bereits (siehe Lektion 7). Wir werden es jetzt einfach umbauen.

Ich schlage vor, dass wir die Pin-Nummer, an welche der Taster angeschlossen ist, wieder in einer Variable speichern.

int tasterPin = 11;

Dann müssen wir dem Arduino-Board sagen, dass wir den Pin als Eingabe verwenden wollen. Der Befehl dafür lautet:

pinMode(tasterPin,INPUT);

Du hast es schon gemerkt, oder? Der Befehl ist der gleiche wie der für die LED. Wir sagen einfach nur, dass wir jetzt keinen OUTPUT, sondern einen INPUT verwenden wollen.

Um herauszufinden, ob der Taster gedrückt (HIGH) oder nicht gedrückt (LOW) ist, können wir den folgenden Befehl verwenden:

digitalRead(tasterPin);

Bisher haben wir nur Befehle verwendet, die keine Ergebnisse liefern. Dieser hier sagt aber HIGH oder LOW, wenn wir ihn verwenden. Das nennt man den Rückgabewert.

Schwer? Na gut. Stell dir vor, es würde eine Methode geben, die summe (a,b) heißt. Die Parameter a und b wären zwei Zahlen, die wir zusammen rechnen wollen. Das Ergebnis wird von der Methode als Rückgabewert übertragen. Um nun herauszufinden, wie das Ergebnis ist, müssen wir das Ergebnis auslesen. Das geht so: c = summe (a,b); Jetzt ist das Ergebnis in der Variable c gespeichert.

Der Befehl digitalRead(tasterPin); liefert entweder HIGH oder LOW zurück. Aber wie finden wir denn nun heraus, ob das Ergebnis HIGH oder LOW ist? Dafür gibt es eine der Wichtigsten Konstruktionen in der Programmierung: die if-Abfrage.

Die if-Abfrage

Mit dieser Abfrage können wir testen, ob eine Aussage wahr oder falsch ist. Nehmen wir an, du hast rote und blaue Bausteine vermischt und du willst sie in zwei Boxen sortieren. Wie würdest du das machen?

Unsortierte Bausteine

Vielleicht so:

  1. nimm einen Baustein
  2. prüfe, ob der Baustein rot ist
  3. wenn er rot ist, packe den Stein in Box A

Genau so benutzt man die if-Abfrage. Es ist also eigentlich ganz einfach. So wird sie geschrieben. Achte auf die zwei Gleichheitszeichen hintereinander. Das ist bei einer if-Abfrage sehr wichtig.

if (Baustein==rot) {
	packe Stein in Box A
}

So, jetzt könnten wir alle roten Bausteine in Box A packen, würden aber alle blauen Steine nach der Überprüfung einfach liegen lassen. Wie kommen die jetzt in Box B? Ein Vorschlag:

  1. nimm einen Baustein
  2. prüfe, ob der Baustein rot ist
  3. wenn er rot ist, packe den Stein in Box A
  4. sonst packe ihn in Box B

Gut, oder? Und so könnten wir das programmieren:

if (Baustein==rot) {
	packe den Stein in Box A
} else {
	packe den Stein in Box B
}

Wir benutzen also das Wort else. Das trifft sich gut, denn else heißt auf Deutsch sonst.

Funktionsweise if-Abfrage

Hast du den grünen Stein gesehen? Der wandert auch in Box B, denn wir fragen ja nicht, ob der Baustein blau ist, sondern nur: Ist er rot oder ist er nicht-rot? ;-)

Nun aber zurück zu unserem Programm. Das sieht bisher so aus und muss verändert werden:

int ledPin = 9;
int tasterPin = 11;

void setup(){
  pinMode(ledPin,OUTPUT);
  pinMode(tasterPin,INPUT);
}

void loop(){
  digitalWrite(ledPin, HIGH);
  delay(200);
  digitalWrite(ledPin, LOW);
  delay(200);
}

Die if-Abfrage für den Button fragt, ob der Button HIGH ist:

if (digitalRead(tasterPin)==HIGH){

}

Wenn der Button HIGH ist, soll die LED eingeschalten werden:

if (digitalRead(tasterPin)==HIGH){
  digitalWrite(ledPin, HIGH);
}

Ansonsten (else) soll sie ausgeschaltet werden:

if (digitalRead(tasterPin)==HIGH){
  digitalWrite(ledPin, HIGH);
} else {
  digitalWrite(ledPin, LOW);
}

Hier noch mal das ganze Programm:

int ledPin = 9;
int tasterPin = 11;

void setup(){
  pinMode(ledPin,OUTPUT);
  pinMode(tasterPin,INPUT);
}

void loop(){
  if (digitalRead(tasterPin)==HIGH){
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
}

Funktioniert es? Super. Jetzt versuche das Programm so umzuschreiben, dass die LED aus geht, wenn der Taster gedrückt ist. Die Lösung findest du hier unten:

Es gibt viele Lösungen. Hier zwei Vorschläge:

int ledPin = 9;
int tasterPin = 11;

void setup(){
  pinMode(ledPin,OUTPUT);
  pinMode(tasterPin,INPUT);
}

void loop(){
  if (digitalRead(tasterPin)==LOW){
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
}

Oder:

int ledPin = 9;
int tasterPin = 11;

void setup(){
  pinMode(ledPin,OUTPUT);
  pinMode(tasterPin,INPUT);
}

void loop(){
  if (digitalRead(tasterPin)==HIGH){
    digitalWrite(ledPin, LOW);
  } else {
    digitalWrite(ledPin, HIGH);
  }
}

Das war jetzt aber gar nicht so einfach. Schön, dass du es trotzdem geschafft hast. Jetzt kennst Du schon die wichtigsten Dinge beim Programmieren: Variablen, Schleifen und if-Abfragen. Weiter so! Von jetzt an wird alles viel einfacher. Versprochen.

Titelbild von Walter Benson, CC-BY-SA

32 thoughts on “Lektion 12 – Der Taster und if-Abfrage

  1. ich habe 7 leds und darunter eine grüne mit dem taster will ich abfragen ob die Grüne led leuchtet wenn sie leuchtet soll eine andere auf der rechten seite angehen bitte um hilfe

  2. Das einzige Problem ist, einen Taster anzuschliessen.
    Das ist nicht so trivial wie der Rest deines Beitrags, finde ich.

    pinMode(tasterPin, INPUT); // erfordert einen Pulldown-Widerstand.

    Was hältst du übrigens von
    void loop() {
    digitalWrite(ledPin, digitalRead(tasterPin)); // led zeigt taster Zustand an.
    }

  3. vielen Dank für die tollen Erklärungen. Ich habe zwei Arduino Anfänger Bücher und in keinem ist es so gut erklärt wie hier. Echt super!

  4. Sehr gute und witzige Anleitung. Schade, dass hier keine weiteren Kommentare stehen. Gerade die Eingabe und Ausgabebefehle sind Dinge, die man, wenn man lange nicht programmiert hat, hier gut erklärt wiederfindet. Danke für diese Seite und die Mühe zum Erstellen.

  5. Hi,
    habe beide Programme ausprobiert.
    Beim 1. Programm ist der Ablauf wie von Ihnen angegeben.
    Beim 2. Programm ist der Ablauf wie beim 1.Programm. Kein Unterschied. Wo könnte der Fehler sein.
    Habe das 2. Programm kopiert und in meiner Arduinodsoftware 1.6.12 eingefügt. Trotzdem keine Änderung. 2. Programm reagiert weiter wie 1. Programm.

  6. Hallo ich würde gerne eine ampel mit grün gelb rot und fußgänger ampel machen mit rot und grün.
    mir ist aber nicht eingefallen wie ich den schalter einbinde und den code möglichst einfach halten kann.
    lg Timo

  7. Hallo @Neuling

    Ich habe es mit verzögerungen versucht aber funktioniert auch nicht. Bei mir ist das gleiche ergebnis nur halt mit LED.

    Hallo@Kim

    Lass die LEDs nach rechts laufen, bei der letzten angekommen kein Befehl.
    Es sei denn die letzte Led is an un der Taster ist gedrück, dann erst Linkslauf und da wieder bei der letzten die Abfrage UND Taster.

    LG Nathalie

  8. Hallo bin neu hier. Mache zur Zeit Schülerpraktikum und habe vom Betrieb einen Arduino bekommen. Bisher habe ich alle Aufgabenstellungen geschafft nur jetzt bin ich am verzweifel. Ich soll 4 Leds rechtsrum laufen lassen und sowie ich den Taster drücke soll es ander herum laufen. Seit gestern sitze ich dran, aber ich bekomme es einfach nicht hin.Kann mir jemand einen Tipp geben.

  9. Hallo,
    ich habe versucht das Programm nachzustellen aber habe anstatt einer LED ein Relais genommen welches einen Motor steuert.
    Ich möchte den Motor starten sobald der Taster gedrückt wird. Sollte ja genau so funktionieren wie mit der LED. Nehme ich nur das if ohne else passiert nichts beim Tastendruck. Nehme ich das else mit rein schaltet das Relais an und aus. Immer wieder sehr schnell.

    Habe es schon ein paar mal hin und her geschrieben aber irgendwie klappt es garnicht. Momentan sieht es so aus:
    int taster1=2;
    int taster2=3;
    int motor1=12;
    int motor2=13;
    int tasterstatus1=0;
    int tasterstatus2=0;

    void setup() {
    // put your setup code here, to run once:
    pinMode(taster1, INPUT);
    pinMode(taster2, INPUT);
    pinMode(motor1, OUTPUT);
    pinMode(motor2, OUTPUT);

    }

    void loop() {
    // put your main code here, to run repeatedly:

    tasterstatus1=digitalRead(taster1);
    tasterstatus2=digitalRead(taster2);

    if(tasterstatus1 == HIGH)
    {
    digitalWrite(motor1, HIGH);
    }
    else
    {
    digitalWrite(motor1, LOW);
    }
    if(tasterstatus2 == HIGH)
    {
    digitalWrite(motor2,HIGH);
    }
    else
    {
    digitalWrite(motor2, LOW);
    }
    }

    was ist hier falsch?

    1. Hi der Code sieht erstmal ganz gut aus. Meine Fehler finde ich aber auch meist nur mit dem Compiler und Testausgaben mittels Serial.println(„text“).

      Ich würde mal ein paar Testausgaben einbauen und dann in der Console schauen was passiert.
      Meine Vermutung ist, das irgendetwas zu viel Strom zieht oder die Verdrahtung evtl. noch lücken enthält. (Vergiss das Serial.begin(9600); in der setup Funktion nicht.)

      Du kannst auch die Relais erstmal durch LEDs ersetzen die Ziehen nicht so viel Strom.

      LG Stef

  10. Hallo,

    bei mir will es nicht klappen, da es irgendein problem mit meinem „else“ gibt. dieses wird, obwohl ich nach langem rätseln sogar den code kopiert habe nicht rot.

    [code]
    int ledPin = 9;
    int tasterPin = 11;

    void setup(){
    pinMode(ledPin,OUTPUT);
    pinMode(tasterPin,INPUT);
    }

    void loop(){
    if (digitalRead(tasterPin)==HIGH){
    digitalWrite(ledPin, HIGH);
    } else {
    digitalWrite(ledPin, LOW);
    }
    }
    [/code]

      1. Ja es hat dann schon geklappt.. Es hat am Anfang nicht funktioniert und deswegen dachte ich das mit dem Code irgendwas nicht stimmt, aber es hatt sich dann herausgestellt das die ganzen taster aus dem Starterkit defekt sind…. Ich hatte noch einen anderen rumliegen mit welchem das dann geklappt hat ;) *yay
        Vielen Dank für für die Hilfe

        Lg
        Pius

  11. Hallo Christian,

    super! Ich glaube, wir kommen dem Problem näher.
    Du hast einfach zweimal eine Klammer zuviel:

    digitalWrite(ledPin), HIGH);

    und

    digitalWrite(ledPin), LOW);

    Der Befehl digitalWrite(Pin, Zustand); bekommt die zwei Parameter. Da kommen die Klammern außen rum.
    Bei digitalRead(pin) gibt es nur ein Parameter, vielleicht hat Dich das abgelenkt.

    Liebe Grüße

    Stefan

  12. Ich komme nicht weiter an diesem Punkt. Ich habe jetzt mehrmals das Breadboard und meinen Code kontrolliert, kann aber einfach keinen Fehler entdecken. Trotzdem wird beim Versuch zu verifizieren eine lange Reihe an Fehlermeldungen angezeigt:

    Arduino: 1.6.3 (Mac OS X), Platine: „Arduino Uno“

    sketch_may04a.ino: In function ‚void loop()‘:
    sketch_may04a.ino:11:25: error: too few arguments to function ‚void digitalWrite(uint8_t, uint8_t)‘
    In file included from sketch_may04a.ino:1:0:
    /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:126:6: note: declared here
    void digitalWrite(uint8_t, uint8_t);
    ^
    sketch_may04a.ino:11:32: error: expected ‚;‘ before ‚)‘ token
    sketch_may04a.ino:13:25: error: too few arguments to function ‚void digitalWrite(uint8_t, uint8_t)‘
    In file included from sketch_may04a.ino:1:0:
    /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:126:6: note: declared here
    void digitalWrite(uint8_t, uint8_t);
    ^
    sketch_may04a.ino:13:31: error: expected ‚;‘ before ‚)‘ token
    Fehler beim Kompilieren.

    Ich bin heiß darauf, weiterzumachen und würde mich sehr über Hilfe freuen :)

    1. Hallo Christian,

      klar, da helfe ich gerne. Es sieht so aus, als ob Du ein Semikolon vergessen hast. Wenn Du es nicht findest, poste doch mal den Code hier, dann gucke ich mal drüber.

      Liebe Grüße

      Stefan

      1. Ja das hatte ich aus dem Zusammenhang geschlossen. ;) Aber bisher konnte ich kein fehlendes Semikolon finden. Hier der Code:

        int ledPin = 9;
        int tasterPin = 11;

        void setup() {
        pinMode(ledPin,OUTPUT);
        pinMode(tasterPin,INPUT);
        }

        void loop() {
        if (digitalRead(tasterPin)==HIGH){
        digitalWrite(ledPin), HIGH);
        } else {
        digitalWrite(ledPin), LOW);
        }
        }

  13. Zur weiteren Erhöhung der präzisen Darlegungen schlage ich vor:
    Den Absatz über den grünen Baustein (Lektion 12) abändern zu:
    „Hast du den grünen Stein gesehen? Der wandert auch in Box B, denn wir fragen ja nicht, ob der Baustein blau ist, sondern nur:
    Ist er rot oder nicht-rot?“
    Als Anlehnung an „wahr oder nicht-wahr“.
    FG an Alle

  14. Hallo,
    ich bin etwas verwirrt über die Aufgabenstellung für die Übung in Lektion 12:

    „Jetzt versuche das Programm so umzuschreiben, dass die LED an geht, wenn der Taster gedrückt ist. Die Lösung findest du hier“

    Das macht aber das vorhandene Programm doch schon, oder? Sollte es nicht heißen: Schreibe das Programm so um, dass die LED aus geht, wenn der Taster gedrückt wird? Zumindest wird nach meinem Verständnis genau das erreicht, indem man das Programm wie in der Lösung ändert.

  15. Hallo,

    in der Lektion 12 ist m. E. ein Fehler. Warum wird nicht die deklarierte Variable tasterPin in der loop-Methode benutzt, sondern (die nicht deklarierte Variable) buttonPin? Ich vermute mal, dass hier einfach eingedeutscht wurde! Nur halt leider nicht überall.

    Für Anfänger ist so etwas natürlich schon ein kleine Hürde.

    int ledPin = 9;
    int tasterPin = 11;

    void setup(){
    pinMode(ledPin,OUTPUT);
    pinMode(tasterPin,INPUT);
    }

    void loop(){
    if (digitalRead(buttonPin)==LOW){
    digitalWrite(ledPin, HIGH);
    } else {
    digitalWrite(ledPin, LOW);
    }
    }

    1. Hallo

      Eine Frage:

      Wie und kann mans überhaupt, den Taster so abfragen, das wenn er 2mal gedrückt wurde, das Licht dauerhaft an bleibt bis man ihn wieder gedrückt hat?
      Er soll bei einmal nur 30sek und bei 2 mal dauerhaft.

      Lg und schönes Wochenende
      Nathalie

      1. Hallo Nathalie Schuster!
        Eine Antwort kann ich dir nicht geben, weil ich zu wenig Übung habe. Aber ich möchte dich für deine Frage unterstützen. Sie interessiert auch mich und vielleicht meldet sich jemand, der eine Lösung kennt, die man dann für eigene Bedürfnisse abändern kann.
        mfg alois

        1. Hallo, dachte schon die Seit ist tot.

          Scheinbar ist es nur unmöglich.
          habe es mit setzen versucht un un un aber hat nicht geklappt.

          Vlt kommt noch einer drauf.

          Ich hoffe mal :)

          Lg Nathalie

          1. Hallo Nathalie, hallo Alois,

            das ist in der Tat kein einfaches Problem. Es ist schon zu lösen. Hier wäre der Code dafür. Große Erklärungen habe ich erstmal nicht eingefügt. Versucht mal, ob Ihr es versteht:

            int ledPin = 9;
            int tasterPin = 11;

            int einschaltdauer = 3000; // 3s
            int tasterTimeout = 500; // doppelklick wird innerhalb von 0,5 Sekunden erwartet
            boolean letzterTasterZustand = false;
            boolean doppelklick = false;
            boolean einfachklick = false;
            boolean dauerAn = false;

            long letztesMalGedrueckt = 0;
            long lichttimer = 0;

            void setup() {
            Serial.begin(9600);
            pinMode(ledPin, OUTPUT);
            pinMode(tasterPin, INPUT);
            }

            void loop() {
            boolean tasterZustand = digitalRead(tasterPin);
            if (tasterZustand == HIGH) {
            if (letzterTasterZustand != tasterZustand) {
            if (letztesMalGedrueckt + tasterTimeout > millis()) {
            doppelklick = true;
            einfachklick = false;
            } else {
            einfachklick = true;
            doppelklick = false;
            }
            letztesMalGedrueckt = millis();
            }
            }

            if (doppelklick == true) {
            dauerAn = true;
            }

            if (einfachklick == true) {
            einfachklick = false;
            if (dauerAn == true) {
            dauerAn = false;
            digitalWrite(ledPin, LOW);
            } else {
            lichttimer = millis();
            }
            }

            if (lichttimer + einschaltdauer > millis()) {
            digitalWrite(ledPin, HIGH);
            } else {
            digitalWrite(ledPin, LOW);
            if (dauerAn == true) {
            digitalWrite(ledPin, HIGH);
            }
            }

            letzterTasterZustand = tasterZustand;
            delay(20);
            }

            Liebe Grüße

            Stefan

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Ich akzeptiere

 

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.