← Kapitel 3: Blinklicht | ↑ Übersicht | Kapitel 5: Eingänge →

Kapitel 4: Übungsaufgabe Ampelsteuerung

Wir ändern unseren ersten Versuchsaufbau um eine gelbe und eine grüne LED:

Aufbau Ampel

Die Pinbelegungen sind wie folgt:

Drei 120R-Widerstände:

  • D3 und G3
  • D6 und G6
  • D9 und G9

Die rote LED: Plus auf J3, Minus auf die Masseschiene

Die gelbe LED: Plus auf J6, Minus auf die Masseschiene

Die grüne LED: Plus auf J9, Minus auf die Masseschiene

Die Kabel:

blau: GND und Masseschiene

rot: 13 und A3

gelb: 12 und A6

grün: 11 und A9

Wir erhalten dadurch folgenden Schaltplan:

Um den ganzen Code ein wenig übersichtlicher zu gestalten lernen wir vor der Übung noch eine wichitge Componente der Programmiersprache: Defines

Mit diesen Defines können wir den Code deutlich lesbarer machen. Das funktioniert so:

#define KONSTANTENNAME Wert

Jetzt wenden wir diese Definition auf unser erstes Beispiel mit der LED an:

#define LED_ROT 13

Soweit so gut. Jetzt passiert vorerst nichts, wir verwenden also unsere Definition:

digitalWrite(LED_ROT, HIGH);

Was nun passiert ist folgendes:

Der Compiler (Das war das Teil, das unseren Code in Maschinensprache übersetzt) arbeitet den Code von oben nach unten ab. Ganz oben schreiben wir unser #define hin. Wenn der Compiler zu dieser Stelle kommt weiß er „Ah, LED_ROT bedeutet in Wirklichkeit 13“.

Nun arbeitet er den Code weiter ab und macht dabei etwas geniales: An jeder Stelle, an der LED_ROT steht, schreibt der Compiler 13 hin.

Um solche #defines schnell zu erkennen, werden sie in der Regel mit Großbuchstaben geschrieben. Wir erkennen jetzt also, dass zum Beispiel HIGH auch eine Konstante ist, die von Arduino bereits definiert wurde.

Warum definieren wir das aber? Ganz einfach: Wenn wir die rote LED mehrfach in unserem Code verwenden müssen, können wir jedesmal LED_ROT schreiben. Sollte sich irgendwann der Pin ändern (Und jeder der jetzt denkt: „Warum sollte sich ein Pin ändern?“ sei gewarnt: Das passiert sehr häufig, meistens aus Bequemlichkeit) kann diese Anpassung am Anfang des Codes in der Definition gemacht werden. Einmal und nicht X-mal im gesamten Quellcode.

Das Ziel dieser Aufgabe ist es, eine Ampelsteuerung zu simulieren. Das Timing dieser Steuerung soll wie folgt aussehen:

  • Die Ampel startet rot
  • Nach 2 Sekunden rot wird gelb eingeschaltet
  • Nach 1 Sekunde erlischt rot und gelb, grün leuchtet
  • Nach 3 Sekunden schaltet die Ampel von grün auf gelb
  • Nach 1 Sekunde erlischt gelb und der Zyklus beginnt von vorne

Da die Defines noch neu sind gibt es hier das Grundgerüst des Codes, der erweitert werden soll:

kapitel04_ampel-grund.ino
#define LED_ROT 13
#define LED_GELB 12
#define LED_GRUEN 11
 
void setup()
{
  pinMode(LED_ROT, OUTPUT);
}
 
void loop() 
{
  digitalWrite(LED_ROT, HIGH);
}

Die Aufgabe besteht nun darin, den Code an den entsprechenden Stellen so zu erweitern, dass die Ampelsteuerung wie oben beschrieben, funktioniert.

Als Vergleich zur selbst erstellten Lösung gibt es hier die Musterlösung, die aber natürlich nicht benötigt wird!

Jetzt wo wir wissen, wie Ausgänge funktionieren, kommen wir logischerweise zur anderen Richtung: Kapitel 5: Eingänge