Schleifen

Nochmal!

Bisher kannst du Programme mit Wiederholungen nur durch sich wiederholenden Quelltext (unschön!) oder durch die „loop()“-Funktion erzeugen. Es gibt allerdings noch eine weitere elegantere Möglichkeit: Schleifen.

Sie ermöglichen einen bestimmten Quelltextabschnitt zu wiederholen solange eine bestimmte Bedingung erfüllt oder bis eine bestimmte Anzahl von Durchläufen erreicht ist.

In C++/Arduino gibt es unterschiedliche Arten von Schleifen. Zwei davon lernst du in diesem Kapitel kennen: die „for“-Schleife und die „while“-Schleife. Die „for“-Schleife wird verwendet, um eine bestimmte Anzahl von Schritten durchzuführen, während die „while“-Schleife verwendet wird, um eine Aktion so lange auszuführen, wie eine bestimmte Bedingung erfüllt ist.

for

Die for-Schleife wird meist verwendet, wenn von Anfang an klar ist, wie viele Wiederholungen benötigt werden. Der Kopf einer for-Schleife besteht aus 3 Segmenten.

for(A; B; C)

Im einzelnen haben sie die folgenden Funktionen:

  • A: Dieses Segment wird vor der ersten Ausführung der Schleife ausgeführt. Normalerweise wird hier eine sogenannte Schleifenvariable deklariert und initialisiert.
  • B: Dieses Segment enthält die Schleifenbedingung, unter der die Schleife weiterhin ausgeführt wird. Sie wird vor jedem Durchlauf geprüft.
  • C: Dieses Segment wird nach jedem einzelnen Schleifendurchlauf ausgeführt. Oft wird dort die Schleifenvariable um einen bestimmten Wert erhöht.

Ein Schleifenkopf könnte also wie folgt aussehen:

for(int i = 0; i < 100; i = i + 10){
  //Code
}

Hier wird der Variablen i anfangs der Wert 0 zugewiesen und nach jedem Durchlauf um 10 erhöht. Die Schleife wird ausgeführt, solange i kleiner 100 ist. Sie wirs also 10 mal durchlaufen. Die Schleifenvariable i nimmt dabei die Werte 0, 10, 20, …, 90 an.

Beispiel

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

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

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

  for(int i = 0; i < 16; i++){  // Der Inhalt der Schleife wird 16 mal wiederholt. Die 
                                // Schleifenvariable i nimmt dabei die Werte von 0 bis 15 an.
    u8g2.drawLine(0,0,i*8,63);  // # Linie von (0,0) nach (i*8,63) in den Speicher zeichnen
    delay(50);                  // 50 Millisekunden warten
    u8g2.sendBuffer();          // Grafik zum Display übertragen und anzeigen.
  }
}

void loop() {}

while

Die while-Schleife wird meist verwendet, wenn vor Ausführung nicht genau bekannt ist, wie viele Durchläufe es geben soll. Zu Beginn eines jedes Durchlaufs, auch des ersten, wird überprüft, ob eine Bedingung erfüllt ist. Ist dies der Fall, wird der Programmteil innerhalb der Schleife ausgeführt. Vor der nächsten Ausführung wird die Bedingung erneut geprüft. Ist sie erfüllt wird der Programmteil erneut ausgeführt und so weiter…

Beispiel

Angenommen, wir möchten eine Zahl erraten, die der Picoboy in einer Variablen abgelegt hat. Wir können eine „while“-Schleife verwenden, um die Schleife so lange auszuführen, bis wir die richtige Zahl erraten haben:

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

#define KEY_CENTER 0

U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, 10, 8, 9);
int xPos;                                                  //

void setup(void) {
  u8g2.begin();                                             //
  u8g2.clearBuffer();                                       //
  u8g2.sendBuffer();                                        //
  pinMode(KEY_CENTER, INPUT_PULLUP);
}

void loop() {
  xPos = 0;                                                 //
  u8g2.clearBuffer();                                       //
  while (xPos < 128 && digitalRead(KEY_CENTER) == HIGH) {   //
    u8g2.drawLine(xPos, 0, xPos, 63);                       // # Linie von (0,0) nach (i*8,63) in den Speicher zeichnen
    u8g2.sendBuffer();                                      // Grafik zum Display übertragen und anzeigen.
    xPos = xPos + 1; 
  }
  delay(1000);
}

Schachteln

Wie du es schon von den Verzweigungen kennst, lassen sich auch Schleifen schachteln.

Beispiel

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

#define KEY_CENTER 0

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

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

  for(int i = 0; i < 8; i = i + 1){
    for(int j = 0; j < 16; j = j + 1){
      u8g2.drawPixel(j * 8, i *8);
      delay(20);
      u8g2.sendBuffer();
    }
  }
}

void loop() {}

Beispiel

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

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

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

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

  pinMode(KEY_CENTER, INPUT_PULLUP);
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);

  int farbe = 0;
  while (digitalRead(KEY_CENTER) == HIGH) {
    if (farbe == 0) {
      farbe = 1;
      digitalWrite(LEDR, HIGH);
      digitalWrite(LEDG, LOW);
    } else {
      farbe = 0;
      digitalWrite(LEDR, LOW);
      digitalWrite(LEDG, HIGH);
    }
  delay(50);
  }
}

void loop() {}

Beispiel

Auch tiefere Verschachtelungen sind möglich:

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

#define KEY_CENTER 0

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

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

  for (int i = 0; i < 8; i = i + 1) {
    for (int j = 0; j < 16; j = j + 1) {
      if (i * 2 != j) {
        u8g2.drawPixel(j * 8, i * 8);
        delay(20);
        u8g2.sendBuffer();
      }
    }
  }
}

void loop() {}

Hier geht es weiter.