Verzweigungen

Verschiedene Wege

Bislang laufen deine Programme Zeile für Zeile durch. – Das soll sich nun ändern.

Eine Verzweigung ist eine Möglichkeit, deinem Programm zu sagen, dass es unter angegebenen Bedingungen unterschiedliche Aktionen ausführen soll. Eine Verzweigung ist mit einer Entscheidung zu vergleichen, die du triffst und abhängig von der Situation verschiedene Dinge tust.

In C++/Arduino kannst du eine Verzweigung mit der „if“-Anweisung erstellen. Die „if“-Anweisung prüft eine Bedingung und führt eine Aktion aus, wenn die Bedingung erfüllt ist. Wenn die Bedingung nicht erfüllt ist, wird die Aktion nicht ausgeführt.

Beispiel 1

#define LEDR 5                             // Es wird festgelegt, dass jedes später im Text vorkommende LEDR beim Übersetzen
                                           // des Programms in eine für den PicoBoy verständliche Fassung durch eine 5 ersetzt wird.
                                           // Die rote LED ist an Pin 5 des Prozessors angeschlossen.
#define LEDG 7                             // Hier geschieht die entsprechende Festlegung für die grüne LED
#define KEY_CENTER 0                       // und den "Mitteltaster" des Joysticks. 

void setup(void) { 
  pinMode(KEY_CENTER, INPUT_PULLUP);       // Der Pin INPUT_PULLUP wird auf den Modus "Eingang" geschaltet, da der Zustand des Tasters
                                           // ausgelesen werden soll.
  pinMode(LEDR, OUTPUT);                   // Der Pin LEDR wird auf den Modus "Ausgang" geschaltet, da er eine LED schalten soll.
  pinMode(LEDG, OUTPUT);                   // Der Pin LEDR wird auf den Modus "Ausgang" geschaltet, da er eine LED schalten soll.

  digitalWrite(LEDG, LOW);                 // Schaltet die grüne LED aus.
  digitalWrite(LEDR, HIGH);                // Schaltet die rote LED ein.

  if (digitalRead(KEY_CENTER) == LOW) {    // Falls der Joystick mittig gedrückt wird...
    digitalWrite(LEDG, HIGH);              // ... schalte die grüne LED ein.
    digitalWrite(LEDR, LOW);               // ... schalte die rote LED aus.
  }
}

void loop(){}

Anmerkungen

  • Der Programmablauf erfolgt sehr schnell. Daher wirst du nur einen Unterschied merken, wenn du den Joystick gedrückt hältst, während du den PicoBoy mit der Taste „RES“ neu startest. Keine Bange – Du siehst bald, wie es anders geht.
  • Beachte die zusätzlichen geschweiften Klammern „{ … }“. Sie begrenzen den den Codeabschnitt, der bei erfüllter Bedingung ausgeführt wird.
  • Die Vergleichsoperatoren in C++ sind „<“ (kleiner), „>“ (größer), „<=“ (kleiner oder gleich), „>=“ (größer oder gleich), „==“ (gleich) und „!=“ (ungleich).

Soll unter einer Bedingung ein Teil des Quelltextes ausgeführt werden und bei Nichterfüllung ein anderer, so  kannst auch eine „else“-Anweisung hinzufügen.

Beispiel 2

#define LEDR 5
#define LEDG 7
#define KEY_CENTER 0

void setup(void) {
  pinMode(KEY_CENTER, INPUT_PULLUP);
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);

  if (digitalRead(KEY_CENTER) == LOW) {
    digitalWrite(LEDG, HIGH);
    digitalWrite(LEDR, LOW);
  } else {
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDR, HIGH);
  }
}

void loop() {}

Anmerkungen

  • Während der Ausführung zeigt sich kein sichtbarer Unterschied zu Beispiel 1. Er geht aus dem Programmablaufplan hervor.

Geht immer!

Natürlich lassen sich Verzweigungen auch mit den Grafikbefehlen kombinieren. Sie stehen hier innerhalb der Funktion „loop()“ und werden daher unentwegt wiederholt, nachdem die Funktion „setup()“ abgearbeitet ist.

Beispiel

#include <U8g2lib.h>
#include <SPI.h>

#define KEY_RIGHT 2
#define KEY_DOWN 3
#define KEY_LEFT 4
#define KEY_UP 1
#define KEY_CENTER 0

U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, 10, 8, 9);

int xPos;
int yPos;

void setup(void) {
  u8g2.begin();
  u8g2.clearBuffer();
  u8g2.sendBuffer();

  pinMode(KEY_RIGHT, INPUT_PULLUP);
  pinMode(KEY_DOWN, INPUT_PULLUP);
  pinMode(KEY_LEFT, INPUT_PULLUP);
  pinMode(KEY_UP, INPUT_PULLUP);
  pinMode(KEY_CENTER, INPUT_PULLUP);

  xPos = 64;
  yPos = 32;
}

void loop() {
  if (digitalRead(KEY_UP) == LOW) {
    yPos = yPos - 1;
  }
  if (digitalRead(KEY_DOWN) == LOW) {
    yPos = yPos + 1;
  }
  if (digitalRead(KEY_LEFT) == LOW) {
    xPos = xPos - 1;
  }
  if (digitalRead(KEY_RIGHT) == LOW) {
    xPos = xPos + 1;
  }
  if (digitalRead(KEY_CENTER) == LOW) {
    u8g2.clearBuffer();
    xPos = 64;
    yPos = 32;
  }
  delay(50);
  u8g2.drawPixel(xPos,yPos);
  u8g2.sendBuffer();
}

Anmerkung:

  • Im Falle „form ungleich 1“ soll ein Dreieck gezeichnet werden. Da dazu mehrere Programmzeilen erforderlich sind, sind mehrere Zeilen eingerückt, die nur in diesem Fall ausgeführt werden.
  • Die Befehlr „delay()“, „drawPixel()“ und „sendBuffer()“ sollen auf jeden Fall ausgeführt werden und stehen daher außerhalb der geschweiften Klammern. Sie werden ausgeführt, nachdem der if-Block durchlaufen ist.

Logische Operatoren

Führt man Beispiel 3 aus, so zeigt sich, dass man aus dem Display „herauszeichnen“ kann. Durch sogenannte logische Operatoren lässt sich das Verhindern. Eine Bedingung für einen Schritt nach rechts könnte beispielsweise lauten: Gehe nach rechts, wenn der Joystick nach rechts gedrückt wird und die aktuelle Position noch mindestens einen Schritt von der rechten Kante entfernt ist. Dieser Ansatz ist im folgenden Beispiel umgesetzt.

Beispiel

#include <U8g2lib.h>
#include <SPI.h>

#define KEY_RIGHT 2
#define KEY_DOWN 3
#define KEY_LEFT 4
#define KEY_UP 1
#define KEY_CENTER 0

U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, 10, 8, 9);

int xPos;
int yPos;

void setup(void) {
  u8g2.begin();
  u8g2.clearBuffer();
  u8g2.sendBuffer();

  pinMode(KEY_RIGHT, INPUT_PULLUP);
  pinMode(KEY_DOWN, INPUT_PULLUP);
  pinMode(KEY_LEFT, INPUT_PULLUP);
  pinMode(KEY_UP, INPUT_PULLUP);
  pinMode(KEY_CENTER, INPUT_PULLUP);

  xPos = 64;
  yPos = 32;
}

void loop() {
  if (digitalRead(KEY_UP) == LOW && yPos > 0) {
    yPos = yPos - 1;
  }
  if (digitalRead(KEY_DOWN) == LOW && yPos < 63) {
    yPos = yPos + 1;
  }
  if (digitalRead(KEY_LEFT) == LOW && xPos > 0) {
    xPos = xPos - 1;
  }
  if (digitalRead(KEY_RIGHT) == LOW && xPos < 127) {
    xPos = xPos + 1;
  }
  if (digitalRead(KEY_CENTER) == LOW) {
    u8g2.clearBuffer();
    xPos = 64;
    yPos = 32;
  }
  delay(50);
  u8g2.drawPixel(xPos,yPos);
  u8g2.sendBuffer();
}

Neben „and“ gibt es noch weitere Möglichkeiten solche logischen Aussagen durch verschiedene Operatoren zu verknüpfen. Hier ein Überblick:

AND (&&)

aba && b
falsefalsefalse
falsetruefalse
truefalsefalse
truetruetrue

OR (||)

aba || b
falsefalsefalse
falsetruetrue
truefalsetrue
truetruetrue

NOT (!)

anot a
falsetrue
fruefalse

Hier geht es weiter.