Een Arduino-verkeerslicht programmeren

FunduinoLaatst bijgewerkt op

Vom einfachen Ampeltakt bis zur Fußgängerampel mit Taster

Eine Ampel zu programmieren ist der Klassiker unter den Mikrocontroller-Projekten. Das liegt daran, dass es relativ einfach ist, aber auch einen starken Alltagsbezug hat: Denn jede Ampelanlage wird in irgendeiner Weise von einem Mikrocontroller angesteuert. Moderne Ampelanlagen sind zwar in der Regel vernetzt und mit einer Reihe von Sensoren automatisiert, aber die grundlegende Funktion kannst du mit einem Arduino-Mikrocontroller sehr einfach nachbauen.

5V-Ampelmodul mit roter, gelber und grüner LED am Arduino-Mikrocontroller
Ampelmodul am Arduino

Ampel ohne Taster für Fußgänger

Die Programmierung einer Ampel mit der Arduino-Software ist leicht verständlich und kannst du direkt umsetzen, wenn du bereits eine LED ein- und ausschalten kannst. Die Unterschiede bei der Ampel liegen darin, dass es drei statt einer LED gibt und dass du die Dauer der Ampelphasen programmieren musst.

Nach dem Ausschalten der gelben LED beginnt der Loop-Teil erneut und der Arduino-Mikrocontroller schaltet die rote LED wieder ein. Die Ampel beginnt also von vorn mit der Rot-Phase.

An den Phasen kannst du natürlich noch viel verbessern. Zum Beispiel kannst du echte Ampelphasen nachmessen und im Sketch einsetzen. Dazu eignet sich übrigens die Wartezeit vor einer roten Ampel perfekt.

Programmcode – Ampel ohne Taster
int ROT = 5;  // Rote LED an Pin 5
int GELB = 6; // Gelbe LED an Pin 6
int GRUN = 7; // Grüne LED an Pin 7
void setup() // Wir starten mit dem Setup
{
  pinMode(ROT, OUTPUT);  // Pin 5 ist ein Ausgang.
  pinMode(GELB, OUTPUT); // Pin 6 ist ein Ausgang.
  pinMode(GRUN, OUTPUT); // Pin 7 ist ein Ausgang.
}
void loop() // Das Hauptprogramm beginnt
{
  digitalWrite(ROT, HIGH); // Schalte die LED an Pin 5 an.
  delay(2000); // Warte 2000 Millisekunden.
  digitalWrite(GELB, HIGH); // Schalte die LED an Pin 6 an.
  delay(1000); // Warte 1000 Millisekunden.
  digitalWrite(ROT, LOW); // Schalte die LED an Pin 5 aus.
  digitalWrite(GELB, LOW); // Schalte die LED an Pin 6 aus.
  digitalWrite(GRUN, HIGH); // Schalte die LED an Pin 7 an.
  delay(2000); // Warte 2000 Millisekunden.
  digitalWrite(GRUN, LOW); // Schalte die LED an Pin 7 aus.
  digitalWrite(GELB, HIGH); // Schalte die LED an Pin 6 an.
  delay(1000); // Warte 1000 Millisekunden.
  digitalWrite(GELB, LOW); // Schalte die LED an Pin 6 aus.
}
// Hier am Ende springt das Programm an den Start des Loop-Teils.

Die Fußgängerampel mit Tasterabfrage

Als Nächstes programmierst du eine Fußgängerampel. Reine Fußgängerampeln geben den Autofahrern ein dauerhaftes Grünsignal und wechseln nur dann auf Gelb und Rot, wenn ein Fußgänger oder Radfahrer den Taster an der Ampelanlage betätigt hat.

Während der Grünphase fragt der Arduino-Mikrocontroller permanent den Taster ab. Bei einem Tastendruck schaltet die Ampel das Signal für die Autos nach einer gewissen Zeit auf Gelb und anschließend auf Rot, um dann kurz darauf die Ampel für die Fußgänger von Rot auf Grün zu schalten. Im Sketch sieht das so aus:

Programmcode – Fußgängerampel mit Tasterabfrage
int Taster = 4;
int tasterstatus = 0;
int ROT = 5;
int GELB = 6;
int GRUN = 7;
void setup() // Wir starten mit dem Setup
{
  pinMode(Taster, INPUT); // Pin 4 ist ein Eingang.
  pinMode(ROT, OUTPUT);   // Pin 5 ist ein Ausgang.
  pinMode(GELB, OUTPUT);  // Pin 6 ist ein Ausgang.
  pinMode(GRUN, OUTPUT);  // Pin 7 ist ein Ausgang.
}
void loop() // Das Hauptprogramm beginnt.
{
  digitalWrite(GRUN, HIGH); // Schalte die grüne LED an Pin 7 an.
  tasterstatus = digitalRead(Taster); // Hier wird Pin 4 ausgelesen (Befehl: digitalRead). Das Ergebnis wird unter der Variable "tasterstatus" mit dem Wert "HIGH" für 5 Volt oder "LOW" für 0 Volt gespeichert.
  if (tasterstatus == HIGH) // Verarbeitung: Wenn der Taster gedrückt ist (das Spannungssignal ist hoch), arbeitet der Sketch den folgenden Abschnitt ab.
  { // Programmabschnitt des IF-Befehls öffnen.
    delay(2000); // Warte 2000 Millisekunden (2 Sekunden), da es bei einer echten Ampel aus Sicherheitsgründen auch immer eine Weile dauert, bis die Ampel umspringt.
    digitalWrite(GRUN, LOW); // Schalte die grüne LED an Pin 7 aus.
    digitalWrite(GELB, HIGH); // Schalte die gelbe LED an Pin 6 an.
    delay(1000); // Warte 1000 Millisekunden.
    digitalWrite(GELB, LOW); // Schalte die gelbe LED an Pin 6 aus.
    digitalWrite(ROT, HIGH); // Schalte die rote LED an Pin 5 an.
    delay(5000); // Warte 5000 Millisekunden, die Ampel ist für die Autofahrer rot.
    digitalWrite(GELB, HIGH); // Schalte zusätzlich die gelbe LED an Pin 6 an.
    delay(1000); // Warte 1000 Millisekunden.
    digitalWrite(ROT, LOW); // Schalte die rote LED an Pin 5 aus.
    digitalWrite(GELB, LOW); // Schalte zusätzlich die gelbe LED an Pin 6 aus.
  } // Programmabschnitt des IF-Befehls schließen.
}
// Hier am Ende springt das Programm an den Start des Loop-Teils. Da dort die grüne LED direkt aktiviert wird, muss das nicht zusätzlich am Ende des IF-Abschnitts geschehen.

Eine eigene Ampel für die Fußgänger ergänzen

Was im Sketch aus Schritt 2 noch fehlt, ist ein Signal für die Fußgänger oder Radfahrer. Üblicherweise gibt es dafür eine weitere Ampel mit lediglich einem roten und einem grünen Signal. Diese zusätzliche Ampel baust du jetzt also auch noch auf.

Für die Fußgänger schließt du eine rote LED an Pin 8 und eine grüne LED an Pin 9 an.

Programmcode – Mit eigener Ampel für Fußgänger
int Taster = 4;
int tasterstatus = 0;
int ROT = 5;
int GELB = 6;
int GRUN = 7;
int RotFuss = 8;  // Rotes Ampelsignal für Fußgänger
int GrunFuss = 9; // Grünes Ampelsignal für Fußgänger
void setup() // Wir starten mit dem Setup
{
  pinMode(Taster, INPUT);   // Pin 4 ist ein Eingang.
  pinMode(ROT, OUTPUT);     // Pin 5 ist ein Ausgang.
  pinMode(GELB, OUTPUT);    // Pin 6 ist ein Ausgang.
  pinMode(GRUN, OUTPUT);    // Pin 7 ist ein Ausgang.
  pinMode(RotFuss, OUTPUT); // Pin 8 ist ein Ausgang.
  pinMode(GrunFuss, OUTPUT);// Pin 9 ist ein Ausgang.
}
void loop() // Das Hauptprogramm beginnt.
{
  digitalWrite(GRUN, HIGH); // Schalte die grüne Ampel an Pin 7 an. Die Autos sehen also das grüne Signal.
  digitalWrite(RotFuss, HIGH); // Schalte die rote Fußgängerampel an Pin 8 an. Die Fußgänger sehen also das rote Signal.
  tasterstatus = digitalRead(Taster); // Hier wird Pin 4 ausgelesen (Befehl: digitalRead). Das Ergebnis wird unter der Variable "tasterstatus" mit dem Wert "HIGH" für 5 Volt oder "LOW" für 0 Volt gespeichert.
  if (tasterstatus == HIGH) // Verarbeitung: Wenn der Taster gedrückt ist (das Spannungssignal ist hoch), arbeitet der Sketch den folgenden Abschnitt ab.
  { // Programmabschnitt des IF-Befehls öffnen.
    delay(2000); // Warte 2000 Millisekunden (2 Sekunden), da es bei einer echten Ampel aus Sicherheitsgründen auch immer eine Weile dauert, bis die Ampel umspringt.
    digitalWrite(GRUN, LOW); // Schalte die grüne LED an Pin 7 aus.
    digitalWrite(GELB, HIGH); // Schalte die gelbe LED an Pin 6 an.
    delay(1000); // Warte 1000 Millisekunden.
    digitalWrite(GELB, LOW); // Schalte die gelbe LED an Pin 6 aus.
    digitalWrite(ROT, HIGH); // Schalte die rote LED an Pin 5 an.
    delay(2000); // Warte 2000 Millisekunden (2 Sekunden). Die Autofahrer haben jetzt "rot".
    digitalWrite(RotFuss, LOW); // Schalte die rote Fußgängerampel an Pin 8 aus.
    digitalWrite(GrunFuss, HIGH); // Schalte die grüne Fußgängerampel an Pin 9 an. Die Radfahrer und Fußgänger gehen los.
    delay(5000); // Warte weitere 5000 Millisekunden.
    digitalWrite(RotFuss, HIGH); // Schalte die rote Fußgängerampel an Pin 8 wieder ein.
    digitalWrite(GrunFuss, LOW); // Schalte die grüne Fußgängerampel an Pin 9 aus. Die Radfahrer und Fußgänger müssen stehen bleiben.
    delay(2000); // Warte 2000 Millisekunden (2 Sekunden). Die Autofahrer haben immer noch "rot" und die Fußgänger müssen die Straße räumen.
    digitalWrite(GELB, HIGH); // Schalte zusätzlich für die Autofahrer die gelbe LED an Pin 6 an.
    delay(1000); // Warte 1000 Millisekunden.
    digitalWrite(ROT, LOW); // Schalte die rote LED an Pin 5 aus.
    digitalWrite(GELB, LOW); // Schalte zusätzlich die gelbe LED an Pin 6 aus.
  } // Programmabschnitt des IF-Befehls schließen.
}
// Hier am Ende springt das Programm an den Start des Loop-Teils. Da dort die grüne LED direkt aktiviert wird, muss das nicht zusätzlich am Ende des IF-Abschnitts geschehen.

Klaar!

Weiterführende Aufgaben

Schwieriger wird es, wenn du einen Taster brauchst, um eine Ampel zu unterbrechen, die dauerhaft zwischen Rot- und Grünphasen wechselt. An Kreuzungen ist das der Fall. Das größte Problem dabei ist die Verwendung des delay-Befehls im letzten Sketch: Während einer Delay-Phase reagiert der Sketch auf keinerlei Eingaben, die zum Beispiel an einem angeschlossenen Taster gemacht werden.

Die Lösung für dieses Problem ist vergleichsweise aufwendig und daher nur für fortgeschrittene Arduino-Nutzer geeignet. Zwei Lösungsansätze sind möglich.

Die erste Möglichkeit besteht darin, einen angeschlossenen Taster permanent auszulesen und auf die Delays zu verzichten. Dafür musst du eine mathematische Schleife nutzen, die einen Wert hochzählt und bei Erreichen einer gewissen Zahl die Ampelphase ändert.

Die zweite Möglichkeit besteht darin, die Interrupt-Funktion von Arduino-Mikrocontrollerboards zu verwenden. Sie ermöglicht es, einen Sketch zu unterbrechen, egal an welcher Stelle er sich gerade befindet. Diese Unterbrechung nutzt du bei der Ampelprogrammierung dazu, den Tastendruck eines Fußgängers zu registrieren. Auch in anderen Anwendungen spielt dieser Befehl eine wichtige Rolle. Eine Anleitung dazu findest du unter Der Interrupt-Befehl attachInterrupt.

Handleiding beoordelen

Opmerkingen

Stel een vraag of deel je ervaring

Neem contact met ons op als iets niet werkt. Vermeld daarbij je board en de foutmelding.

We controleren elke reactie voordat deze wordt gepubliceerd. Je e-mailadres blijft bij ons.