Suche

Funduino Ampelkreuzung (SMD)

Table of Contents

Grundlagen zur Ampelsteuerung

Eine Ampel steuert den Verkehr auf der Straße. Sie gibt durch Lichtsignale an, wann Fahrzeuge und Fußgänger anhalten müssen (Rot), wann sie vorsichtig sein sollen (Gelb), und wann sie fahren dürfen (Grün). Ampeln können weltweit leichte Unterschiede aufweisen. So können die Phasen unterschiedlich lang sein, die gelbe Farbe kann zeitgleich als Warnzeichen gleichzeitig mit Grün und Rot leuchten usw.

Daher soll diese Anleitung eine Unterstützung zur Programmierung der eignen lokalen Ampel darstellen.

Für unsere Anleitung gilt folgendes:

Ampelphasen

  • Rot: Fahrzeuge müssen anhalten.

  • Gelb: Fahrzeuge sollen sich bereit machen, zu fahren oder anzuhalten.

  • Grün: Fahrzeuge dürfen fahren.

Technische Grundlagen

Im folgenden Abschnitt werden die technischen Eigenschaften der Ampelkreuzung erklärt. Insbesondere die Spannungsversorgung, die Leuchtdioden, die Taster und die LDR zusammen mit einem Multiplexer werden hier beschrieben.

Spannungsversorgung

Die Ampelkreuzung verfügt über 34 Leuchtdioden und einige Fotowiderstände. Aufgrund der hohen Anzahl an Leuchtdioden ist die notwendige Stromstärke höher als es von typischen Mikrocontrollern bereitgestellt werden kann. Daher muss die Kreuzung unabhängig vom Mikrocontroller mit einer Spannung von 6V – 9V über den DC-Jack (Spannungsversorgungsbuchse) mit Spannung versorgt werden. Neben dem DC-Jack befindet sich das entscheidende Bauteil für die Spannungsversorgung.

Der Spannungswandler erzeugt aus jeder angeschlossenen Spannung zwischen 6V und 9V eine Versorgungsspannung von 5V, mit der alle Module auf der Kreuzung mit Strom versorgt werden. Auch wenn ein Mikrocontroller mit einer Systemspannung von 3,3V verwendet wird, versorgt der Spannungswandler die integrierten Module mit der richtigen Spannung.

Auf dem folgenden Bild ist der Stecker ganz oben zu erkennen. Der Stecker muss einen Durchmesser von 5,5mm außen und 2,1mm innen haben. Der positive Kontakt ist innen, der negative Kontakt außen.

Leuchtdioden

Unsere Ampelkreuzung ist mit WS2812 LEDs bestückt. Das sind spezielle LEDs, die einzeln angesteuert werden können. Jede LED hat drei Farben (Rot, Grün, Blau), die sich mischen lassen, um viele verschiedene Farben zu erzeugen. Die WS2812 LEDs sind sehr praktisch, weil sie nur einen Datenpin brauchen, um viele LEDs hintereinander zu steuern.

2.3.1 Wie funktionieren WS2812 LEDs?

  • Steuerung über Arduino: WS2812 LEDs werden über eine spezielle Bibliothek mit dem Arduino gesteuert. Jede LED kann unabhängig angesteuert werden, was ideal für komplexe Lichtmuster ist.

  • Vorteil: Man kann eine lange Kette von LEDs mit einer einzigen Datenleitung verwenden. Das Macht die Ampelkreuzung kompatibel mit Arduino, ESP32 oder auch Raspberry Pi Pico.

2.3.2 Beispielprogramm Einzelampel mit Arduino

Wir programmieren eine Ampel, die die klassischen Phasen (Rot, Gelb, Grün) durchläuft.

Materialien:

  • Arduino Uno

  • Funduino Ampelkreuzung

  • Externe Stromversorgung

Schritt-für-Schritt-Anleitung

 

Verkabelung

Schließe die Kreuzung wie folgt an den Mikrocontroller an:

VIN an der Kreuzung: Verbinde mit 5V vom Arduino

GND an der Kreuzung: Verbinde mit GND vom Arduino.

SIG an der Kreuzung: Verbinde mit Pin3 des Arduino. Über den Pin3 werden nun die LEDs angesteuert

Software vorbereiten

Installiere die Adafruit NeoPixel Library über den Bibliotheksmanager in der Arduino IDE.

Code für eine einfache Ampel

Hier ist der Code für die Steuerung einer einzelnen Ampel

 

#include <Adafruit_NeoPixel.h>

// Pin und Anzahl der WS2812 LEDs
#define DATA_PIN 3
#define NUMPIXELS 3  // 3 LEDs für die Ampel

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, DATA_PIN, NEO_GRB + NEO_KHZ800);

// Funktion zum Setzen der Ampelfarbe
void setAmpel(int pixel, int r, int g, int b) {
  strip.setPixelColor(pixel, strip.Color(r, g, b));
  strip.show();
}

void setup() {
  strip.begin(); // Initialisiere WS2812 LEDs
  strip.show();  // Alle LEDs ausschalten
}

void loop() {
  // Phase Rot
  setAmpel(0, 255, 0, 0);  // Rot an
  setAmpel(1, 0, 0, 0);    // Gelb aus
  setAmpel(2, 0, 0, 0);    // Grün aus
  delay(5000);             // 5 Sekunden Rot

  // Phase Rot-Gelb
  setAmpel(0, 255, 0, 0);  // Rot an
  setAmpel(1, 255, 255, 0); // Gelb an
  setAmpel(2, 0, 0, 0);    // Grün aus
  delay(2000);             // 2 Sekunden Rot-Gelb

  // Phase Grün
  setAmpel(0, 0, 0, 0);    // Rot aus
  setAmpel(1, 0, 0, 0);    // Gelb aus
  setAmpel(2, 0, 255, 0);  // Grün an
  delay(5000);             // 5 Sekunden Grün

  // Phase Gelb
  setAmpel(0, 0, 0, 0);    // Rot aus
  setAmpel(1, 255, 255, 0); // Gelb an
  setAmpel(2, 0, 0, 0);    // Grün aus
  delay(2000);             // 2 Sekunden Gelb
}

Erklärung des Codes

  • Die Ampel durchläuft die Phasen Rot, Rot-Gelb, Grün, und Gelb.

  • Jede Phase wird durch setAmpel() gesteuert, die die Farbe der LEDs entsprechend der Ampelfunktion setzt.

  • Die delay()-Befehle bestimmen, wie lange jede Phase dauert.

Taster für Fußgänger

Auf der Ampelkreuzung befinden sich insgesamt acht Taster. Diese Taster sind für die Fußgänger gedacht um zu signalisieren, dass Fußgänger die Straße überqueren wollen.

Diese Funktion ist sinnvoll, da eine Kreuzung wesentlich effizienter arbeitet, wenn die Hauptfahrspuren nicht unterbrochen werden, wenn keine Fußgänger darauf warten, die Straße zu überqueren.

Jeweils zwei Taster gehören zu einer Fahrspur, da es unrelevant ist, an welcher Straßenseite der Taster gedrückt wurde.

Die Taster beiden Taster, die jeweils zusammengehören, sind jeweils beschriftet mit „Side1“, „Side2“, „Side3“ und „Side4“.

Die Taster verfügen über einen Pulldown-Widerstand. Das bedeutet, dass an den Kontakten mit den Beschriftungen „Side1“, „Side2“, „Side3“ und „Side4“ kein Spannungspegel anliegt (GND), solange kein Taster gedrückt wird. Wenn ein Taster gedrückt wird, liegt an den Kontakten ein Spannungssignal in Höhe von VIN an, also bei einer Spannungsversorgung mit 5V liegt an dem Pin das 5V Signal an.

Fotowiderstände (LDR) mit Analogmultiplexer CD74HC4067

Die Ampelkreuzung verfügt über zehn Fotowiderstände, mit denen modellhaft geprüft werden kann, ob auf den jeweiligen Straßenpositionen ein Fahrzeug steht.

Was kann damit im Modell geprüft werden?

Es kann geprüft werden, ob an einer Ampel ein Fahrzeug wartet. Bei einer intelligenten Ampelschaltung lässt sich so eine Effizienzsteigerung erreichen. Wenn kein Fahrzug wartet, kann eine Fahrbahn dauerhaft auf Ampelphase „rot“ verweilen. Die anderen Fahrzeuge müssen nicht unnötig anhalten. Dadurch lässt sich Zeit und Energie sparen.

Außerdem kann bei komplexeren Programmierungen geprüft werden, ob eine Fahrbahn am Kreuzungsausgang mit Fahrzeugen verstopft ist. So könnte man etwa eine Linksabbiegerspur in der Ampelphase „Rot“ belassen, um den Kreuzungsbereich nicht mit Autos zu verstopfen.

Erklärung des Analogmultiplexers CD74HC4067

Der Analogmultiplexer CD74HC4067, auch als 16-Kanal-Multiplexer bekannt, ist ein kleines Bauteil, welches in der Elektronik viele Möglichkeiten bietet. Aber was genau macht er, und warum ist er so nützlich?

Was ist ein Analogmultiplexer?

Ein Analogmultiplexer ist wie ein elektronischer Schalter, der zwischen mehreren Eingängen oder Ausgängen hin- und herschalten kann. Er kann eine Verbindung zu einem von vielen Kanälen herstellen und Daten in beide Richtungen durchlassen. In unserem Fall möchten wir zehn Analoge Sensoren an den Arduino anschließen, aber der Arduino hat nur wenige analoge Pins. Der Multiplexer hilft dabei, dieses Problem zu lösen, indem er als eine Art „Verteiler“ arbeitet.

Wie funktioniert der CD74HC4067?

16 Kanäle: Der CD74HC4067 hat 16 Eingänge oder Ausgänge, je nachdem, wie man ihn verwendet, die mit nur einem analogen Pin am Arduino Mikrocontroller verbunden werden.

Steuerung mit Signalen: Man steuerst den Multiplexer mit den vier Steuerpins S0, S1, S2, S3. Diese Pins sind auf der Ampelkreuzung vorhanden und beschriftet. Diese Pins bestimmen, welcher der 16 Kanäle gerade aktiv ist und an den Analogen Eingangspin des Arduino Mikrocontrollers weitergeleitet werden.

Verbindungen der Fotowiderstände zum Arduino: Immer nur einer der 16 Kanäle kann zur gleichen Zeit durchgeschaltet sein.

Ansteuerung

Je nachdem, welche der Pins S0, S1, S2 und S3 mit GND oder Spannung (HIGH und LOW) versorgt werden, wird einer der 16 analogen Kanäle an den Analogen Pin des Mikrocontrollers weitergeleitet und dort vom Mikrocontroller ausgelesen.

Folgende Kombinationen sind bei der Ampelkreuzung möglich:

Fotowiderstand 1 zum analogen Pin des Mikrocontrollers durchschalten

S0= LOW / S1= LOW / S2= LOW / S3= LOW

Fotowiderstand 2 zum analogen Pin des Mikrocontrollers durchschalten

S0= HIGH / S1= LOW / S2= LOW / S3= LOW

Fotowiderstand 3 zum analogen Pin des Mikrocontrollers durchschalten

S0= LOW / S1= HIGH / S2= LOW / S3= LOW

Fotowiderstand 4 zum analogen Pin des Mikrocontrollers durchschalten

S0= HIGH / S1= HIGH / S2= LOW / S3= LOW

Fotowiderstand 5 zum analogen Pin des Mikrocontrollers durchschalten

S0= LOW / S1= LOW / S2= HIGH / S3= LOW

Fotowiderstand 6 zum analogen Pin des Mikrocontrollers durchschalten

S0= HIGH / S1= LOW / S2= HIGH / S3= LOW

Fotowiderstand 7 zum analogen Pin des Mikrocontrollers durchschalten

S0= LOW / S1= HIGH / S2= HIGH / S3= LOW

Fotowiderstand 8 zum analogen Pin des Mikrocontrollers durchschalten

S0= HIGH / S1= HIGH / S2= HIGH / S3= LOW

Fotowiderstand 9 zum analogen Pin des Mikrocontrollers durchschalten

S0= LOW / S1= LOW / S2= LOW / S3= HIGH

Fotowiderstand 10 zum analogen Pin des Mikrocontrollers durchschalten

S0= HIGH / S1= LOW / S2= LOW / S3= HIGH

In der Arduinosoftware kann folgender Programmblock zum ansteuern des Multiplexers mit anschließendem Auslesen des Pins verwendet werden:

Beispiel für Fotowiderstand 3

digitalWrite(S0, LOW);
digitalWrite(S1, HIGH);
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
SensorWert = analogRead(Analogpin);

Zusammenfassung

Der CD74HC4067 ist wie ein elektronischer Verteiler, der dabei hilft, viele Module mit einem Arduino zu verbinden, auch wenn nur wenige Pins zur Verfügung stehen. Er ist sehr nützlich, um viele Signale zu lesen oder zu steuern, und das alles mit nur einem kleinen Bauteil!

Programmierung der gesamten Kreuzung ohne Taster und LDR

Die Kreuzung wird nun mit zwei Fahrtrichtungen und Fußgängerampeln programmiert.

Ziel

Die Programmierung der Kreuzung soll die Steuerung von zwei Fahrtrichtungen mit ihren Ampeln und Fußgängerampeln ermöglichen. Wir beachten keine gesonderte Linksabbiegerampel.

Auch die Taster für die Fußgänger und die Fotowiderstände werden in diesem Beispiel nicht abgefragt.

Der Gesamte Ablauf der Ampelschaltung wird in einzelne Phasen aufgeteilt, die jeweils alle Ampeln beinhalten.

Phasenübersicht der Kreuzung

Hier sind die acht Phasen beschrieben, die die gesamte Kreuzung steuern:

Phase 1

Fahrtrichtung 1: Rot

Fahrtrichtung 2: Grün

Fußgängerampel 1: Grün

Fußgängerampel 2: Rot

Erklärung: Die Fahrtrichtung 1 muss anhalten, während die Fahrtrichtung 2 fährt. Die Fußgängerampel der ersten Fahrtrichtung ist grün, sodass Fußgänger sicher die Straße überqueren können.

Phase 2

Fahrtrichtung 1: Rot

Fahrtrichtung 2: Gelb

Fußgängerampel 1: Grün

Fußgängerampel 2: Rot

Erklärung: Die Fahrtrichtung 2 bereitet sich auf das Anhalten vor. Die Fußgängerampel der ersten Fahrtrichtung bleibt noch grün.

Phase 3

Fahrtrichtung 1: Rot

Fahrtrichtung 2: Rot

Fußgängerampel 1: Grün

Fußgängerampel 2: Rot

Erklärung: Beide Fahrtrichtungen zeigen Rot. Es gibt eine kurze Sicherheitsphase, in der beide Fahrtrichtungen anhalten, um Kollisionen zu vermeiden. Die Fußgänger der ersten Fahrtrichtung haben immer noch grün.

Phase 4

Fahrtrichtung 1: Gelb

Fahrtrichtung 2: Rot

Fußgängerampel 1: Rot

Fußgängerampel 2: Rot

Erklärung: Die Fahrtrichtung 1 bereitet sich auf die Grünphase vor, und die Fußgängerampel der ersten Fahrtrichtung schaltet auf Rot.

Phase 5

Fahrtrichtung 1: Grün

Fahrtrichtung 2: Rot

Fußgängerampel 1: Rot

Fußgängerampel 2: Grün

Erklärung: Die Fahrtrichtung 1 darf jetzt fahren, und die Fußgängerampel der zweiten Fahrtrichtung schaltet auf Grün.

Phase 6

Fahrtrichtung 1: Gelb

Fahrtrichtung 2: Rot

Fußgängerampel 1: Rot

Fußgängerampel 2: Rot

Erklärung: Die Fahrtrichtung 1 bereitet sich auf das Anhalten vor, und die Fußgängerampel der zweiten Fahrtrichtung schaltet auf Rot.

Phase 7

Fahrtrichtung 1: Rot

Fahrtrichtung 2: Rot

Fußgängerampel 1: Grün

Fußgängerampel 2: Rot

Erklärung: Beide Fahrtrichtungen zeigen Rot. Die Fußgänger der ersten Fahrtrichtung haben Grün und können die Straße sicher überqueren.

Phase 8

Fahrtrichtung 1: Rot

Fahrtrichtung 2: Gelb

Fußgängerampel 1: Grün

Fußgängerampel 2: Rot

Erklärung: Die Fahrtrichtung 2 bereitet sich darauf vor, wieder anzufahren, und die Fußgängerampel der ersten Fahrtrichtung bleibt noch auf Grün.

Programmcode

Hier ist der vollständige Sketch für die Programmierung der gesamten Kreuzung mit den beschriebenen Phasen.

#include <Adafruit_NeoPixel.h>

// Pin und Anzahl der WS2812 LEDs
#define DATA_PIN 3
#define NUMPIXELS 34  // Gesamtzahl der LEDs

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, DATA_PIN, NEO_GRB + NEO_KHZ800);

// Funktion zum Setzen der Ampelfarbe für eine Richtung
void setAmpel(int pixel1, int pixel2, int r, int g, int b) {
  strip.setPixelColor(pixel1, strip.Color(r, g, b));
  strip.setPixelColor(pixel2, strip.Color(r, g, b));
  strip.show();
}

// Funktion zum Setzen der Fußgängerampel mit mehreren LEDs
void setFussgaengerAmpel(int gruen1, int gruen2, int gruen3, int gruen4, int rot1, int rot2, int rot3, int rot4, bool gruenAn) {
  if (gruenAn) {
    // Grün an, Rot aus
    strip.setPixelColor(gruen1, strip.Color(0, 255, 0));
    strip.setPixelColor(gruen2, strip.Color(0, 255, 0));
    strip.setPixelColor(gruen3, strip.Color(0, 255, 0));
    strip.setPixelColor(gruen4, strip.Color(0, 255, 0));
    strip.setPixelColor(rot1, strip.Color(0, 0, 0));
    strip.setPixelColor(rot2, strip.Color(0, 0, 0));
    strip.setPixelColor(rot3, strip.Color(0, 0, 0));
    strip.setPixelColor(rot4, strip.Color(0, 0, 0));
  } else {
    // Rot an, Grün aus
    strip.setPixelColor(gruen1, strip.Color(0, 0, 0));
    strip.setPixelColor(gruen2, strip.Color(0, 0, 0));
    strip.setPixelColor(gruen3, strip.Color(0, 0, 0));
    strip.setPixelColor(gruen4, strip.Color(0, 0, 0));
    strip.setPixelColor(rot1, strip.Color(255, 0, 0));
    strip.setPixelColor(rot2, strip.Color(255, 0, 0));
    strip.setPixelColor(rot3, strip.Color(255, 0, 0));
    strip.setPixelColor(rot4, strip.Color(255, 0, 0));
  }
  strip.show();
}

void setup() {
  strip.begin(); // Initialisiere WS2812 LEDs
  strip.show();  // Alle LEDs ausschalten
}

void loop() {
  // Phase 1: Richtung 1 Rot, Richtung 2 Grün, Fußgänger 1 Grün, Fußgänger 2 Rot
  setAmpel(15, 6, 255, 0, 0);  // Richtung 1 Rot an
  setAmpel(16, 7, 0, 0, 0);    // Richtung 1 Gelb aus
  setAmpel(17, 8, 0, 0, 0);    // Richtung 1 Grün aus
  delay(2000); // 2 Sekunden warten, bevor Fußgänger 1 Grün wird
  setFussgaengerAmpel(18, 32, 24, 26, 19, 33, 25, 27, true);  // Fußgänger 1 Grün
  setAmpel(0, 9, 0, 0, 0);     // Richtung 2 Rot aus
  setAmpel(1, 10, 0, 0, 0);    // Richtung 2 Gelb aus
  setAmpel(2, 11, 0, 255, 0);  // Richtung 2 Grün an
  setFussgaengerAmpel(20, 22, 30, 28, 21, 23, 31, 29, false); // Fußgänger 2 Rot
  delay(5000); // 5 Sekunden Grünphase für Richtung 2

  // Phase 2: Richtung 1 bleibt Rot, Richtung 2 schaltet auf Gelb, Fußgänger 2 auf Rot
  setAmpel(15, 6, 255, 0, 0);  // Richtung 1 Rot an
  setAmpel(16, 7, 0, 0, 0);    // Richtung 1 Gelb aus
  setAmpel(17, 8, 0, 0, 0);    // Richtung 1 Grün aus
  setFussgaengerAmpel(18, 32, 24, 26, 19, 33, 25, 27, true);  // Fußgänger 1 Grün
  setAmpel(0, 9, 0, 0, 0);     // Richtung 2 Rot aus
  setAmpel(1, 10, 255, 255, 0); // Richtung 2 Gelb an
  setAmpel(2, 11, 0, 0, 0);    // Richtung 2 Grün aus
  setFussgaengerAmpel(20, 22, 30, 28, 21, 23, 31, 29, false); // Fußgänger 2 Rot
  delay(2000); // 2 Sekunden Gelbphase für Richtung 2

  // Phase 3: Beide Richtungen zeigen Rot, Fußgänger 1 Grün, Fußgänger 2 Rot
  setAmpel(15, 6, 255, 0, 0);  // Richtung 1 Rot an
  setAmpel(16, 7, 0, 0, 0);    // Richtung 1 Gelb aus
  setAmpel(17, 8, 0, 0, 0);    // Richtung 1 Grün aus
  setFussgaengerAmpel(18, 32, 24, 26, 19, 33, 25, 27, true);  // Fußgänger 1 Grün
  setAmpel(0, 9, 255, 0, 0);   // Richtung 2 Rot an
  setAmpel(1, 10, 0, 0, 0);    // Richtung 2 Gelb aus
  setAmpel(2, 11, 0, 0, 0);    // Richtung 2 Grün aus
  delay(2000); // 2 Sekunden warten, bevor Fußgänger 2 Grün wird
  setFussgaengerAmpel(20, 22, 30, 28, 21, 23, 31, 29, true);  // Fußgänger 2 Grün
  delay(1000); // 1 Sekunde beide Richtungen Rot

  // Phase 4: Richtung 1 schaltet auf Gelb, Richtung 2 bleibt Rot, Fußgänger 1 auf Rot
  setAmpel(15, 6, 255, 0, 0);  // Richtung 1 Rot an
  setAmpel(16, 7, 255, 255, 0); // Richtung 1 Gelb an
  setAmpel(17, 8, 0, 0, 0);    // Richtung 1 Grün aus
  setFussgaengerAmpel(18, 32, 24, 26, 19, 33, 25, 27, false); // Fußgänger 1 Rot
  setAmpel(0, 9, 255, 0, 0);   // Richtung 2 Rot an
  setAmpel(1, 10, 0, 0, 0);    // Richtung 2 Gelb aus
  setAmpel(2, 11, 0, 0, 0);    // Richtung 2 Grün aus
  delay(2000); // 2 Sekunden Gelbphase für Richtung 1 vor Grün

  // Phase 5: Richtung 1 Grün, Richtung 2 bleibt Rot, Fußgänger 2 Grün
  setAmpel(15, 6, 0, 0, 0);    // Richtung 1 Rot aus
  setAmpel(16, 7, 0, 0, 0);    // Richtung 1 Gelb aus
  setAmpel(17, 8, 0, 255, 0);  // Richtung 1 Grün an
  setFussgaengerAmpel(18, 32, 24, 26, 19, 33, 25, 27, false); // Fußgänger 1 Rot
  setAmpel(0, 9, 255, 0, 0);   // Richtung 2 Rot an
  setAmpel(1, 10, 0, 0, 0);    // Richtung 2 Gelb aus
  setAmpel(2, 11, 0, 0, 0);    // Richtung 2 Grün aus
  setFussgaengerAmpel(20, 22, 30, 28, 21, 23, 31, 29, true); // Fußgänger 2 Grün
  delay(5000); // 5 Sekunden Grünphase für Richtung 1

  // Phase 6: Richtung 1 schaltet auf Gelb vor Rot, Richtung 2 bleibt Rot, Fußgänger 2 auf Rot
  setAmpel(15, 6, 0, 0, 0);    // Richtung 1 Rot aus
  setAmpel(16, 7, 255, 255, 0); // Richtung 1 Gelb an
  setAmpel(17, 8, 0, 0, 0);    // Richtung 1 Grün aus
  setFussgaengerAmpel(20, 22, 30, 28, 21, 23, 31, 29, false); // Fußgänger 2 Rot
  delay(2000); // 2 Sekunden Gelbphase für Richtung 1 vor Rot

  // Phase 7: Beide Richtungen zeigen Rot, Fußgänger 1 auf Grün, Fußgänger 2 bleibt Rot
  setAmpel(15, 6, 255, 0, 0);  // Richtung 1 Rot an
  setAmpel(16, 7, 0, 0, 0);    // Richtung 1 Gelb aus
  setAmpel(17, 8, 0, 0, 0);    // Richtung 1 Grün aus
  delay(2000); // 2 Sekunden warten, bevor Fußgänger 1 Grün wird
  setFussgaengerAmpel(18, 32, 24, 26, 19, 33, 25, 27, true);  // Fußgänger 1 Grün
  setAmpel(0, 9, 255, 0, 0);   // Richtung 2 Rot an
  setAmpel(1, 10, 0, 0, 0);    // Richtung 2 Gelb aus
  setAmpel(2, 11, 0, 0, 0);    // Richtung 2 Grün aus
  setFussgaengerAmpel(20, 22, 30, 28, 21, 23, 31, 29, false); // Fußgänger 2 Rot
  delay(1000); // 1 Sekunde beide Richtungen Rot

  // Phase 8: Richtung 1 bleibt Rot, Richtung 2 schaltet auf Gelb, Fußgänger 1 Grün, Fußgänger 2 auf Rot
  setAmpel(15, 6, 255, 0, 0);  // Richtung 1 Rot an
  setAmpel(16, 7, 0, 0, 0);    // Richtung 1 Gelb aus
  setAmpel(17, 8, 0, 0, 0);    // Richtung 1 Grün aus
  setFussgaengerAmpel(18, 32, 24, 26, 19, 33, 25, 27, true);  // Fußgänger 1 Grün
  setAmpel(0, 9, 255, 0, 0);   // Richtung 2 Rot an
  setAmpel(1, 10, 255, 255, 0); // Richtung 2 Gelb an
  setAmpel(2, 11, 0, 0, 0);    // Richtung 2 Grün aus
  setFussgaengerAmpel(20, 22, 30, 28, 21, 23, 31, 29, false); // Fußgänger 2 Rot
  delay(2000); // 2 Sekunden Gelbphase für Richtung 2
}

Beispielprogramm zum Auslesen der Taster und LDR

int Fotowiderstand = A0;
int LED = 12;
int SchwelleDunkelheit = 400;
int S0 = 4;
int S1 = 5;
int S2 = 6;
int S3 = 7;
int p = 5;
int SensorWert = 0;
int Taster1 = 8;
int Taster2 = 9;
int Taster3 = 10;
int Taster4 = 11;
int TasterStatus = 0;

void setup() {
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);

  pinMode(Taster1, INPUT);
  pinMode(Taster2, INPUT);
  pinMode(Taster3, INPUT);
  pinMode(Taster4, INPUT);

  // Seriellen Monitor starten
  Serial.begin(9600);
}

void loop() {
  // 1
  digitalWrite(S0, LOW);
  digitalWrite(S1, LOW);
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  delay(p);
  SensorWert = analogRead(Fotowiderstand);
  Serial.print(SensorWert);
  Serial.print("  ");

  // 2
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  delay(p);
  SensorWert = analogRead(Fotowiderstand);
  Serial.print(SensorWert);
  Serial.print("  ");

  // 3
  digitalWrite(S0, LOW);
  digitalWrite(S1, HIGH);
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  delay(p);
  SensorWert = analogRead(Fotowiderstand);
  Serial.print(SensorWert);
  Serial.print("  ");

  // 4
  digitalWrite(S0, HIGH);
  digitalWrite(S1, HIGH);
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  delay(p);
  SensorWert = analogRead(Fotowiderstand);
  Serial.print(SensorWert);
  Serial.print("  ");

  // 5
  digitalWrite(S0, LOW);
  digitalWrite(S1, LOW);
  digitalWrite(S2, HIGH);
  digitalWrite(S3, LOW);
  delay(p);
  SensorWert = analogRead(Fotowiderstand);
  Serial.print(SensorWert);
  Serial.print("  ");

  // 6
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  digitalWrite(S2, HIGH);
  digitalWrite(S3, LOW);
  delay(p);
  SensorWert = analogRead(Fotowiderstand);
  Serial.print(SensorWert);
  Serial.print("  ");

  // 7
  digitalWrite(S0, LOW);
  digitalWrite(S1, HIGH);
  digitalWrite(S2, HIGH);
  digitalWrite(S3, LOW);
  delay(p);
  SensorWert = analogRead(Fotowiderstand);
  Serial.print(SensorWert);
  Serial.print("  ");

  // 8
  digitalWrite(S0, HIGH);
  digitalWrite(S1, HIGH);
  digitalWrite(S2, HIGH);
  digitalWrite(S3, LOW);
  delay(p);
  SensorWert = analogRead(Fotowiderstand);
  Serial.print(SensorWert);
  Serial.print("  ");

  // 9
  digitalWrite(S0, LOW);
  digitalWrite(S1, LOW);
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  delay(p);
  SensorWert = analogRead(Fotowiderstand);
  Serial.print(SensorWert);
  Serial.print("  ");

  // 10
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  delay(p);
  SensorWert = analogRead(Fotowiderstand);
  Serial.print(SensorWert);
  Serial.print("  ");

  // Tasater abfragen
  TasterStatus = digitalRead(Taster1);
  if (TasterStatus == HIGH) {
    Serial.print("Taster1 aktiv");
  }
  TasterStatus = digitalRead(Taster2);
  if (TasterStatus == HIGH) {
    Serial.print("Taster2 aktiv");
  }
  TasterStatus = digitalRead(Taster3);
  if (TasterStatus == HIGH) {
    Serial.print("Taster3 aktiv");
  }
  TasterStatus = digitalRead(Taster4);
  if (TasterStatus == HIGH) {
    Serial.println("Taster4 aktiv");
  } else if (TasterStatus == LOW) {
    Serial.println(" ");
  }
}

Alle Modelle der hier gezeigten Modelle sind hier zum Download  in einer kompakten Zip Datei verfügbar.