Arrays (Feld)
Motivation
Im Abschnitt Schleifen sollten in einer Aufgabe mehrere LEDs an verschiedenen Pins an- bzw. ausgeschaltet werden. Eine mögliche Lösung wäre es, nur Pins zu verwenden, welche mit aufeinander folgenden Zahlen bezeichnet werden (z.B. Pin 3, 4, 5, 6, 7).
Mit diesem Ansatz könnten dann alle Pins durch eine for
-Schleife zum Beispiel auf HIGH
gesetzt werden:
for(pin = 3; pin <8; pin++) // alle Pins von 3 bis 7
{
digitalWrite(pin,HIGH)
}
Ganz offensichtlich funktioniert dieser Ansatz nicht, wenn die verwendeten Pins keine aufeinander folgende Nummerierung aufweisen. In diesem Fall eignen sich jedoch Arrays (Felder), um die verschiedenen Pins anzusteuern.
Arrays (Felder)
Ein Array ist nichts anderes als ein Feld mit mehreren Variablen, welche alle den selben Datentyp haben. Ein Array vom Datentyp int
kann zum Beispiel mehrere Integer-Werte speichern:
Um das abgebildete Array zu erzeugen, wird der Datentyp (int
) gefolgt von dem Namen des Arrays mit eckigen Klammern (zahlen[]
) geschrieben. Werte können dem Array bei der Deklaration sofort in einer geschweiften Klammer { ... }
übergeben werden.
// Ein Array vom Typ Integer mit 5 Elementen (Werten)
int zahlen[] = {12, 30, 42, 56, 98};
Der Vorteil des Arrays gegenüber einzelnen Variablen liegt darin, dass der Array nur einen Namen hat und die einzelnen Element über ihren Index (0
, 1
, 2
, ...) angesprochen werden können. Anders als vielleicht zu vermuten wäre, hat das erste Element den Index 0
. Bei fünf Elementen hat somit das letzte Element den Index 4
.
Mit Hilfe der Indizes kann mit den einzelnen Array-Elementen wie mit einfachen Datentypen gearbeitet werden.
Es können Werte (neu) zugewiesen werden:
zahlen[0] = 3;
Elemente können mit Werten oder anderen Elementen verglichen werden:
zahlen[1] > 15; // true
zahlen[4] < zahlen[3] // false
Oder es können Werte über die serielle Schnittstelle ausgegeben werden:
Serial.print(`Der Wert von zahlen[3] ist:`);
Serial.println(zahlen[3]);
Außerdem - und das ist der Grund, warum Arrays so nützlich sind - kann für den Index auch eine Variable verwendet werden:
int index = 4;
zahlen[index] = 100; // zahlen[4] = 100
Der Index für das erste Element eines Arrays ist immer 0
.
Deklaration ohne Wertzuweisung
Ein Array mit einer festen Größe kann auch ohne gleichzeitige Wertezuweisung deklariert werden. Das ist besonders dann sinnvoll, wenn die Werte für die einzelnen Arrayelemente noch nicht bekannt sind.
int zahlen[5]; // Deklariert einen Array für 5 Elemente
Um dem Array Werte zuzuweisen, kann dann mit einer Schleife jedem einzelnen Arrayelement der gewünschte Werte zugewiesen:
for(int i = 0; i<5; i++){ // Schleife für die einzelnen Elemente des Array
zahlen[i]= 2*i;
}
Für das gegebene Beispiel nehmen die einzelnen Elemente folgende Werte an:
zahlen[0]: 0
zahlen[1]: 2
zahlen[2]: 4
zahlen[3]: 6
zahlen[4]: 8
Ein Array muss immer mit einer festen Größe (Anzahl von Elementen) deklariert werden. Diese Größe kann später nicht mehr geändert werden.
Einfaches Beispiel
Im folgenden Beispiel werden mit einer for-Schleife die Werte eines Arrays über die serielle Schnittstelle ausgegeben.
#define ANZAHL 7
int werte[] = {12, 30, 42, 56, 98, 298, 305};
void setup(){
Serial.begin(115200);
delay(1000);
for(int i = 0; i < ANZAHL; i++){ // Der erste Index ist 0
Serial.print("werte[");
Serial.print(i);
Serial.print("]=");
Serial.println(werte[i]); // Zugriff auf die Elemente des Arrays
delay(300);
}
}
void loop(){
// bleibt leer ...
}
Ein Array für die LED-Pins
Betrachten wir noch einmal das Beispiel der LEDs, welche an verschiedenen Arduino-Pins angeschlossen sind. Die LEDs werden an den PWM-Pins 3
, 5
, 6
, 9
und 10
angeschlossen. Die Leds selbst werden von 0 bis 4 durchnummeriert. Insgesamt werden also 5 LEDs angeschlossen.
Ein Array, der die LED-Pins beinhaltet könnte dann folgendermaßen aussehen:
int pins[] = {3, 5, 6, 9, 10}; // Array mit den einzelnen PINS als Elemente
Hat man sich einmal solch einen Array für die LEDs erstellt, kann dieser genutzt werden, um die einzelnen Pins pins[i]
als
- Ausgang zu definieren
pinMode(pinLeds[i],OUTPUT)
, - sie zu schalten
digitalWrite(pinLeds[i],HIGH)
oder, - da es PMW fähige Ausgänge sind, die einzelnen LEDs auch zu dimmen.
Beispiel
Im folgendem Beispielprogramm wird ein Array pins[]
mit 5 Elementen genutzt, um 5 LEDs nacheinander ein- und auszuschalten.
#define NUMLED 5 // Anzahl der Array Elemente
int pins[] = {3, 5, 6, 9, 10};
void setup(){
// Jeden einzelnen Pin als Ausgang konfigurieren
for(int i = 0; i < NUMLED; i++){
pinMode(pinLeds[i],OUTPUT);
}
}
void loop(){
// Jede einzelne LED anschalten
for(int i = 0; i < NUMLED; i++){
digitalWrite(pinLeds[i],HIGH);
delay(250);
}
delay(1000);
// Jede einzelne LED ausschalten
for(int i = 0; i < NUMLED; i++){
digitalWrite(pinLeds[i],LOW);
delay(250);
}
delay(1000);
}
Aufgaben
Bestimmen Sie den Mittelwert, den größten und den kleinsten Wert des folgenden Arrays und geben Sie diese auf dem seriellen Monitor aus
int zahlen[10] = {5, 12, 56, 2, 89, 45, 23, 56, 89, 12};
Wenn Sie es sich zustrauen, bestimmen Sie auch den Medianwert.
Bauen Sie eine Schaltung mit ca. 5 LEDs und 2 Tastern auf. Schreiben Sie ein Programm, welches mit den zwei Tastern die Position einer leuchtenden LED steuert. Der eine Taster bewegt das Licht nach links, der anderer Taster nach rechts. Befindet sich die leuchtende LED am Rand, springt sie beim entsprechenden Tasterdruck über zum anderen Rand (LED-Licht zirkuliert). Die Taster sollen entprellt werden.
Analysieren Sie folgendes Programm. Beantworten Sie dafür die Fragen im Kommentar.
#define NUMLED 6
const int pinLeds[NUMLED] = {3, 5, 6, 9, 10, 11};
int zustandLeds[] = {0, 0, 0, 0, 0, 0};
int dir = 1; // Welche Bedeutung hat die Variable `dir`?
int num = 0; // Welche Bedeutung hat die Variable `num`?
unsigned long lastTime = 0;
unsigned long delayMillis = 200;
void setup() {
for (int i = 0; i < NUMLED; i++) {
pinMode(pinLeds[i], OUTPUT);
}
}
void loop() {
// Wofür ist die if-Abfrage?
if ((millis() - lastTime) > delayMillis) {
for (int i = 0; i < NUMLED; i++) // Was passiert in dieser Schleife?
{
if (i == num) {
zustandLeds[i] = HIGH;
} else {
zustandLeds[i] = LOW;
}
digitalWrite(pinLeds[i], zustandLeds[i]);
}
if (num >= NUMLED-1) {
dir = -1; // Warum wird der Wert von `dir` geändert?
} else if (num == 0) {
dir = 1;
}
num += dir; // Welchen Wert nimmt `num` an
lastTime = millis();
}
}