Dieses Modul des RailFX-Systems betreibt eine Ampelanlage mit zwei Fahrtrichtungen und Fußgängerampeln. Dazu gibt es noch eine Straßenbeleuchtung und eine optionale Nachtabschaltung.
Schaltplan
Auch dieses Modul arbeitet mit einem Arduino Nano. An die digitalen Kanäle 2 – 11 sind die LEDs für die Ampeln angeschossen. Jeder Kanal kann bis zu 40mA liefern. Da man für eine Ampelanlage natürlich mehrere einzelne Ampeln benötigt, kann man die Schaltung durch parallel geschaltete LEDs erweitern. Allerdings verringert sich die Leuchtkraft der einzelnen LED. Am A2 und A3 wird die Straßenbeleuchtung betrieben. Sie werden als digitale Ausgänge (D16, D17) betrieben und schalten sich gesteuert durch das Control-Modul in der Nacht ein. Das grüne Kabel links (SCL) ist überflüssig – sorry.
Achtung: Am Pin A4 ist das Control-Signal des RailFX Control-Moduls angelegt. Es steuert die Tageszeit und ist zwingend erforderlich.
Bauteile
- 1x LED-Set
Einstellungen im Code
Im Code lassen sich mehrere Einstellungen vornehmen. Die Variable meineAdresse muss auf das System angepasst werden. Diese Adresse darf im gesamten System (also bei allen Modulen) nur einmal vorkommen. Die Variable wartezeiten speichert die Dauer der einzelnen Farbphasen der Ampelanlage. Die Variable nachtabschaltung kann man auf true oder false setzen. Bei true wird die Ampeln nachts abgeschaltet und blinkt gelb. Bei false geschieht das nicht.
long wartezeiten[10] = {5000, 2000, 500, 2000, 500, 5000, 2000, 500, 2000, 500}; // Wartezeiten der Ampelphasen boolean nachtabschaltung = true; // true = Ampel schaltet nachts ab (gelbe blinken), false = Ampel schaltet nicht ab
Beim Upload muss man darauf achten, dass das richtige Board im Arduino-Menü ausgewählt ist. Dazu muss ebenfalls im Werkzeuge-Menü im Unterpunkt Prozessor »ATmega328P (Old Bootlaoder)« ausgewählt sein.
Der folgende Programmcode kann mit den oben erwähnten Änderungen einfach kopiert und auf das Arduino-Nano geladen werden.
Code für das RailFX-Ampel-Modul
/* Rail-FX Ampel-Modul StartHardware.org */ /* ***** ***** Einstellungen ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** */ long wartezeiten[10] = {5000, 2000, 500, 2000, 500, 5000, 2000, 500, 2000, 500}; // Wartezeiten der Ampelphasen boolean nachtabschaltung = true; // true = Ampel schaltet nachts ab (gelbe blinken), false = Ampel schaltet nicht ab /* ***** ***** Ab hier beginnt der Programmcode, der nicht angepasst werden muss ***** ***** ***** ***** */ int strassenlampenPin1 = 16; // an diesem Pin sind die Straßenlampen angeschlossen int strassenlampenPin2 = 17; // an diesem Pin sind weitere Straßenlampen angeschlossen int ledPins[10] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; int ampelphasen[12][10] = { {1, 0, 0, 0, 1, 0, 0, 1, 1, 0}, // state 0 {1, 0, 0, 1, 0, 0, 0, 1, 1, 0}, // state 1 {1, 0, 0, 1, 0, 0, 1, 0, 1, 0}, // state 2 {1, 0, 0, 1, 0, 1, 0, 0, 1, 0}, // state 3 {1, 1, 0, 1, 0, 1, 0, 0, 1, 0}, // state 4 {0, 0, 1, 1, 0, 1, 0, 0, 0, 1}, // state 5 {0, 0, 1, 1, 0, 1, 0, 0, 1, 0}, // state 6 {0, 1, 0, 1, 0, 1, 0, 0, 1, 0}, // state 7 {1, 0, 0, 1, 0, 1, 0, 0, 1, 0}, // state 8 {1, 0, 0, 1, 0, 1, 1, 0, 1, 0}, // state 9 {0, 1, 0, 0, 0, 0, 1, 0, 0, 0}, // state 10 // blinken {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // state 11 // blinken }; /* Speicher-Variablen */ int strassenlampenHelligkeit = 0; // speichert, wie hell die Straßenlampen leuchten /* Timer Variablen */ long strassenlampenTimer = 0; // Timer der Straßenlampen long ampelTimer = 0; long ampelTimeout = 0; /* State Variablen */ int ampelState = 0; String stateName; /* */ /* Variablen vom Controlmodul um die Uhrzeit festzustellen*/ boolean receive = false; boolean receiveStarted = false; int receiveTimeout = 10; long receiveTimer = 0; int receivedTime = 0; int receivePulse = 0; int lastReceivePulse = 0; int receivePin = 18; int myTime = 0; #define PAYLOAD_SIZE 2 // nötig für die Kommunikation zum Master int uhrzeit = 0; // speichert die uhrzeit vom Master-Modul (0 und 255) byte nodePayload[PAYLOAD_SIZE]; // speichert die Daten vom Master-Modul zwischen void setup() { Serial.begin(115200); // started die serielle Kommunikation pinMode(receivePin, INPUT); // Empfangspin vom Control-Modul for (int i = 0; i < 10; i++) { pinMode(ledPins[i], OUTPUT); } pinMode(strassenlampenPin1, OUTPUT); pinMode(strassenlampenPin2, OUTPUT); strassenlampenAus(); } void loop() { receiveFunction(); // Führe Anweisungen für Empfang aus if (receiveStarted == false) { // Falls gerade keine Daten empfangen werden: if (myTime > 22) { // ***** Später Abend ***** strassenlampenAn(); // Straßenlampen an zeigeAmpelphase(); // Ampel an } else if (myTime > 18) { // ***** Abend ***** strassenlampenAn(); // Straßenlampen an zeigeAmpelphase(); // Ampel an } else if (myTime > 12) { // ***** Nachmittag ***** strassenlampenAus(); // Straßenlampen aus zeigeAmpelphase(); // Ampel an } else if (myTime > 9) { // ***** Vormittag ***** strassenlampenAus(); // Straßenlampen aus zeigeAmpelphase(); // Ampel an } else if (myTime > 7) { // ***** Morgen ***** strassenlampenAn(); // Straßenlampen an zeigeAmpelphase(); // Ampel an } else { // ***** Nacht ***** strassenlampenAn(); // Straßenlampen an if (nachtabschaltung == true) { zeigeAmpelAus(); // Ampel aus ampelTimer = millis(); // resetten des Ampel-Timers für die nächste Phase ampelState = 3; // resetten des Ampel-Zustands } else { zeigeAmpelphase(); // Ampel an } } } } void strassenlampenAn() { digitalWrite(strassenlampenPin1, LOW); digitalWrite(strassenlampenPin2, LOW); } void strassenlampenAus() { digitalWrite(strassenlampenPin1, HIGH); digitalWrite(strassenlampenPin2, HIGH); } void zeigeAmpelphase() { if (ampelTimer + ampelTimeout < millis()) { ampelTimer = millis(); ampelState++; if (ampelState >= 10) ampelState = 0; ampelTimeout = wartezeiten[ampelState]; zeigeAmpelphase(); } for (int i = 0; i < 10; i++) { if (ampelphasen[ampelState][i] == 1) { digitalWrite(ledPins[i], LOW); } else { digitalWrite(ledPins[i], HIGH); } } } void zeigeAmpelAus() { // Blink-Funktion für abgeschaltetet Ampel if (millis() % 2000 > 1000) { for (int i = 0; i < 10; i++) { if (ampelphasen[11][i] == 1) { digitalWrite(ledPins[i], LOW); } else { digitalWrite(ledPins[i], HIGH); } } } else { for (int i = 0; i < 10; i++) { if (ampelphasen[10][i] == 1) { digitalWrite(ledPins[i], LOW); } else { digitalWrite(ledPins[i], HIGH); } } } } void receiveFunction() { // Empfängt die Uhrzeit vom Control-Modul receivePulse = digitalRead(receivePin); // Lies den Empfangspin aus if ((receiveTimer + receiveTimeout < millis()) && (receiveStarted == true)) { // Bei Timeout und aktivem Empfang receiveStarted = false; // beende aktiven Empfang myTime = receivedTime - 1; // speichere die empfangene Zeit receivedTime = 0; // setze die Hilfsvariable zum Zeitempfang zurück Serial.println(myTime); // serielle Ausgabe } // falls ein Puls am Empfangspin erfasst wird, der vorher nicht da war if ((receivePulse == 0) && (lastReceivePulse == 1)) { receiveTimer = millis(); // starte Timer neu if (receiveStarted == false) receiveStarted = true; // starte aktiven Empfang, wenn noch nicht geschehen receivedTime++; // es gab einen Puls, also erhöhe die Hilfsvariable zum Zeitempfang } lastReceivePulse = receivePulse; // aktuellen Zustand am Pin für nächsten Durchlauf merken }
Wenn dir das Projekt gefallen hat und du von weiteren interessanten Projekten inspiriert werden willst, sieh dir doch mal mein neues E-Book »Arduino Projekte Volume 1« an!
- Die beliebtesten Arduino-Projekte von StartHardware
- Inklusive Schaltplan, Beschreibung und Code
- Arduino-Schnellstart-Kapitel
- Kompakter Programmierkurs
Hallo Stefan, Ampel ist im Betrieb, was sie aber perfekt machen würde, wäre das tackern an der Fußgängerampel für Blinde. Bei rot ein langsames tackern und bei grün ein schnelles tackern. Wäre das ein Anreiz dies noch mit einzubinden?
Hi Volker, gute Idee, ist aber erstmal nicht geplant. Meine Liste ist zurzeit ziemlich lang. Den Sound könntest du aber selber realisieren. Viele RailFX-Module haben ja schon einen MP3-Player. Das kannst du ja in den Code einbauen und den Sound auslösen, wenn die Fußgängerampeln umschalten.
Liebe Grüße
Stefan
Hallo, tolle Sache Deine Module. Was aber fehlt ist die Nachtdimmung der Deckenbeleuchtung wie es in Hamburg auch realisiert wurde. Hast Du da noch eine Idee??
Hallo Volker, hm, noch nicht, ist aber eine echt spannende Idee! Ich denk drüber nach. Wird bestimmt das nächste Modul :-)
Hallo Stefan, der Dimmer an sich ist ja nicht das Problem, aber das Einbinden des Contolmoduls ist schon eine Herausforderung. Kannst Du mir sagen wie lange Du dafür brauchst??
Hi Volker, wie willst du die Lampen dimmen? LED-Strips? Wenn ich die Art des Outputs kenne, geht es auf jeden Fall schneller ;-) Liebe Grüße
Ich dachte an RGB Strips. Ist doch machbar oder?
Hallo Stefan, noch ein Nachtrag, in Hamburg wird das Licht dunkel und rot geht dann an für die Nacht, wäre das im Automatikbetrieb möglich?
Klar, das sollte alles möglich sein.
Kannst Du mir sagen wie lange Du dafür brauchst?