Nr. 45 – Arduino Ampel

Eine Ampel zu programmieren ist der Klassiker unter den Mikrocontrolling 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. Natürlich sind moderne Ampelanlagen in der Regel vernetzt und mit einer Reihe von Sensoren automatisiert, aber die grundlegende Funktion lässt sich mit einem Arduino-Mikrocontroller sehr einfach nachbauen.

Material: Arduino Mikrocontroller, ein Breadboard, drei LEDs (Rot, Gelb, Grün) mit passenden Widerständen (100-200 Ohm) oder noch besser ein fertiges Ampelmodul für Arduino wie dieses hier: https://www.funduinoshop.com/Ampel-Modul-fuer-Mikrocontroller

Ampel ohne Taster für Fußgänger

Die Programmierung einer Ampel mit der Arduino Software ist sehr leicht und kann direkt umgesetzt werden, wenn man bereits in der Lage ist, eine LED ein- und aus zu schalten. Die Unterschiede bei der Ampel liegen darin, dass es drei anstatt einer LED gibt, und dass die Dauer der Ampelphasen programmiert werden muss.

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 Pin5 an.
delay(2000); // Warte 1000 Millisekunden.
digitalWrite(GELB, HIGH); // Schalte die LED an Pin6 an.
delay(1000); // Warte 1000 Millisekunden.
digitalWrite(ROT, LOW); // Schalte die LED an Pin5 aus.
digitalWrite(GELB, LOW); // Schalte die LED an Pin6 aus.
digitalWrite(GRUN, HIGH); // Schalte die LED an Pin7 an.
delay(2000); // Warte 1000 Millisekunden.
digitalWrite(GRUN, LOW); // Schalte die LED an Pin7 aus.
digitalWrite(GELB, HIGH); // Schalte die LED an Pin6 an.
delay(1000); // Warte 1000 Millisekunden.
digitalWrite(GELB, LOW); // Schalte die LED an Pin6 aus.
}
// Hier am Ende springt das Programm an den Start des Loop-Teils.

Nach dem ausschalten der gelben LED beginnt der Loop-Teil von vorne und der Arduino Mikrocontroller schaltet die Rote LED wieder ein. Die Ampel beginnt also von vorne mit der Rot-Phase.

An den Phasen kann nun natürlich noch viel verbessert werden. Zum Beispiel kann man echte Ampelphasen prüfen und im Sketch einsetzen. Dazu ist übrigens perfekt die Wartezeit vor einer roten Ampel geeignet.

Die Arduino Fußgängerampel mit Tasterabfrage

Als nächstes soll eine Fußgängerampel programmiert werden. Reine Fußgängerampeln geben den Autofahrern ein dauerhaftes Grünsignal und wechseln lediglich dann auf ein gelbes und rotes Licht, wenn ein Fußgänger oder Radfahrer den Taster an der Ampelanlage betätigt hat. Während der Grünphase wird vom Arduino Mikrocontroller permanent der Taster abgefragt und bei einem Tastendruck schaltet die Ampel das Signal nach einer gewissen Zeit für die Autos auf gelb und anschließend rot um dann noch kurzer Zeit die Ampel für die Fußgänger von rot auf grün zu schalten. Im Sketch sieht das folgendermaßen aus:

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 Pin7 an.
tasterstatus=digitalRead(Taster);  //Hier wird der Pin4 ausgelesen (Befehl:digitalRead). Das Ergebnis wird unter der Variable „tasterstatus“ mit dem Wert „HIGH“ für 5Volt oder „LOW“ für 0Volt gespeichert.
if (tasterstatus == HIGH) //Verarbeitung: Wenn der Taster gedrückt ist (Das Spannungssignal ist hoch)verarbeitet der Sketch die folgende Schleife
 { //Programmabschnitt der IF-Schleife ö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 Pin7 aus.
 digitalWrite(GELB, HIGH); // Schalte die gelbe LED an Pin6 an.
 delay(1000); // Warte 1000 Millisekunden.
 digitalWrite(GELB, LOW); // Schalte die gelbe LED an Pin6 aus. 
 digitalWrite(ROT, HIGH); // Schalte die rote LED an Pin5 an.
 delay(5000); // Warte 5000 Millisekunden, die Ampel ist für die Autofahrer rot.
 digitalWrite(GELB, HIGH); // Schalte zusätzlich die gelbe LED an Pin6 an.
 delay(1000); // Warte 1000 Millisekunden.
 digitalWrite(ROT, LOW); // Schalte die rote LED an Pin5 aus.
 digitalWrite(GELB, LOW); // Schalte zusätzlich die gelbe LED an Pin6 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 dies nicht zusätzlich am Ende der Schleife gemacht werden.

Was in diesem Sketch 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 bauen wir also auch noch auf.

Wir schließen für die Fußgänger eine rote LED an Pin8 an und eine grüne LED an Pin9.

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 Pin7 an. Die Autos sehen also das grüne Signal
digitalWrite(RotFuss, HIGH); // Schalte die rote Fußgängerampel an Pin8 an. Die Autos sehen also das grüne Signal
tasterstatus=digitalRead(Taster);  //Hier wird der Pin4 ausgelesen (Befehl:digitalRead). Das Ergebnis wird unter der Variable „tasterstatus“ mit dem Wert „HIGH“ für 5Volt oder „LOW“ für 0Volt gespeichert.
if (tasterstatus == HIGH) //Verarbeitung: Wenn der Taster gedrückt ist (Das Spannungssignal ist hoch)verarbeitet der Sketch die folgende Schleife
 { //Programmabschnitt der IF-Schleife ö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 Pin7 aus.
 digitalWrite(GELB, HIGH); // Schalte die gelbe LED an Pin6 an.
 delay(1000); // Warte 1000 Millisekunden.
 digitalWrite(GELB, LOW); // Schalte die gelbe LED an Pin6 aus. 
 digitalWrite(ROT, HIGH); // Schalte die rote LED an Pin5 an.
 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. Die Autofahrer haben jetzt "rot".
 digitalWrite(RotFuss, LOW); // Schalte die rote Fußgängerampel an Pin8 aus.
 digitalWrite(GrunFuss, HIGH); // Schalte die grüne Fußgängerampel an Pin9 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 Pin8 ein.
 digitalWrite(GrunFuss, LOW); // Schalte die grüne Fußgängerampel an Pin9 aus. Die Radfahrer und Fußgänger müssen stehen bleiben
 delay(2000); // Warte 2000 Millisekunden(2 Sekunden). Die Autofahrer haben immernoch "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 Pin6 an.
 delay(1000); // Warte 1000 Millisekunden.
 digitalWrite(ROT, LOW); // Schalte die rote LED an Pin5 aus.
 digitalWrite(GELB, LOW); // Schalte zusätzlich die gelbe LED an Pin6 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 dies nicht zusätzlich am Ende der Schleife gemacht werden.

Achtung, nur für Fortgeschrittene

Schwieriger wird es, wenn ein Taster benötigt wird um eine Ampel zu unterbrechen, die dauerhaft die Rot- und Grünphasen ändert. 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 bspw. an einem angeschlossenen Taster vorgenommen werden.

Die Lösung für dieses Problem ist vergleichsweise Aufwändig 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 muss eine mathematische Schleife genutzt werden, 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. Diese Interruptfunktion ermöglicht es, einen Sketch zu unterbrechen, egal an welcher Stelle er sich gerade befindet. Diese Unterbrechung nutzt man bei der Ampelprogrammierung dazu, den Tastendruck eines Fußgängers zu registrieren. Auch in anderen Anwendungen spielt dieser Befehlt eine wichtige Rolle. Daher gibt es zu diesem Befehl eine separate Anleitung.