Dieses Modul des RailFX-Systems kann zur Beleuchtung einer Siedlung, eines Gebäudes oder einer Stadt verwendet werden. Es können bis zu zehn Wohnhäuser beleuchtet werden. Zusätzlich gibt es eine LED, die einen Fernseher simuliert, eine Straßenbeleuchtung mit zwei Kanälen, die in der Nacht leuchten, einem Kanal, der flackert und zwei Kanäle für eine oder zwei Werbetafeln, die sich entweder abwechselnd oder unterschiedlich voneinander blinken.
Bauteile
- LEDs
- 16x 220 Ohm Widerstand
Schaltplan
Auch dieses Modul arbeitet mit einem Arduino Nano. An die digitalen Kanäle 2, 3, 4, 5 und 12, 13, 14 (A0), 15 (A1), 16 (A2), 17 (A3) sind die LEDs als Wohnhausbeleuchtung angeschlossen. Jeder Kanal kann bis zu 40mA liefern. Hier lassen sich weitere LEDs parallel zu den aktuellen LEDs angeschlossen werden. Sie teilen sich dann alle einen Widerstand. Allerdings verringert sich die Leuchtkraft der einzelnen LED. Außerdem müssen es in der jeweiligen Parallelschaltung gleiche LEDs sein (gleicher Innenwiderstand), sonst leuchtet nur die LED mit dem kleinsten Innenwiderstand. Am Pin 6 ist eine LED angeschlossen, die flackert und einen Fernseher simulieren soll. Bei mir ist sie grün, weil gerade Fußball läuft.
An den Pins 10 und 11 werden die Straßenlampen angeschlossen. Zusätzlich gibt es noch am Pin 9 einen Anschluss für eine flackernde, defekte Straßenlampe. Mit diesen Pins könnte man aber auch eine Motel-Beleuchtung realisieren, in der ein Buchstabe blinkt (kennt man ja von Motel-Schildern :-D )
Die Pins 7 und 8 können Werbetafeln beleuchten. Man kann sie so einstellen, dass sie nicht blinken, abwechselnd blinken oder in unterschiedlicher Geschwindigkeit blinken. Damit lassen sich z. B. Werbebanner über Geschäften beleuchten, oder Animationen mit zwei Phasen erzeugen. Hier könnte ich mir gravierte Acrylglasscheiben vorstellen, die vom Rand per LED beleuchtet werden.
Achtung: Am Pin A4 ist das Control-Signal des RailFX Control-Moduls angelegt. Es steuert die Tageszeit und ist zwingend erforderlich.
Einstellungen im Code
Wie alle RailFX-Module wird auch dieses über das Control-Modul gesteuert. Es liefert die Uhrzeit und synchronisiert so alle RailFX-Module.
Im Code lassen sich mehrere Einstellungen vornehmen.
Die Variable strassenlampenTimeout steuert die Einschaltzeit der Straßenlampen in Millisekunden. Diese dimmen sich dann in der angegebenen Zeit an.
Mit der Variablen strassenlampeFlackern lässt sich die Flackerfrequenz einstellen. Je höher der Wert, desto langsamer flackert die LED am Pin 9.
Die Wohnhausbeleuchtungen sollen sich unterschiedlich ein und ausschalten, damit die Siedlung auch schön belebt aussieht. Das lässt sich mit der Variablen einschaltWahrscheinlichkeit beeinflussen. Je höher der Wert, desto »unterschiedlicher« schalten sich die Häuser ein. Das Gleiche fürs Ausschalten erledigt die Variable »ausschaltWahrscheinlichkeit«.
Nun etwas Werbung: Die Variablen werbeBlinken1 und werbeBlinken2 steuern die LEDs für die Werbetafeln. Wenn der Wert beider Variablen gleich ist, blinken sie abwechselnd. Das könnte man für eine Animation verwenden. Ist der Wert unterschiedlich, blinken sie in unabhängiger Frequenz. Hier können also z. B. zwei unabhängige Werbetafeln betrieben werden. Wenn der Wert auf 0 gesetzt wird, leuchten die LEDs dauerhaft.
int strassenlampenTimeout = 100; // Einschaltzeit der Straßenlampen (ms) int strassenlampeFlackern = 1000; // je höher der Wert, desto langsamer flackert die LED an Pin 9 int einschaltWahrscheinlichkeit = 2000; // je höher der Wert, desto unterschiedlicher das Einschalten der Hausbeleuchtung int ausschaltWahrscheinlichkeit = 2000; // je höher der Wert, desto unterschiedlicher das Ausschalten der Hausbeleuchtung int werbeBlinken1 = 1500; // Blinkgeschwindigkeit der Werbe-LED, 0 = nicht blinken int werbeBlinken2 = 1500; // Blinkgeschwindigkeit der Werbe-LED, 0 = nicht blinken
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-Siedlung-Modul
/* Rail-FX Siedlung-Modul StartHardware.org */ /* ***** ***** Einstellungen ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** */ int strassenlampenTimeout = 100; // Einschaltzeit der Straßenlampen (ms) int strassenlampeFlackern = 1000; // Je höher der Wert, desto langsamer flackert die LED an Pin 9 int einschaltWahrscheinlichkeit = 2000; // Je höher der Wert, desto unterschiedlicher das Einschalten der Hausbeleuchtung int ausschaltWahrscheinlichkeit = 2000; // Je höher der Wert, desto unterschiedlicher das Ausschalten der Hausbeleuchtung int werbeBlinken1 = 1500; // Blinkgeschwindigkeit der Werbe-LED, 0 = nicht blinken int werbeBlinken2 = 1500; // Blinkgeschwindigkeit der Werbe-LED, 0 = nicht blinken /* ***** ***** Ab hier beginnt der Programmcode, der nicht angepasst werden muss ***** ***** ***** ***** */ int strassenlampenPin1 = 11; // an diesem Pin sind Straßenlampen angeschlossen int strassenlampenPin2 = 10; // an diesem Pin sind Straßenlampen angeschlossen int strassenlampenPin3 = 9; // defekte Straßenlampe int wohnPins[10] = {2, 3, 4, 5, 12, 13, 14, 15, 16, 17}; // digitale Output-Pins -> Belegung siehe unten int werbePin1 = 7; // an diesem Pin ist die Werbe-LED 1 angebracht int werbePin2 = 8; // an diesem Pin ist die Werbe-LED 2 angebracht int tvPin = 6; // an diesem Pin ist eine LED für einen TV angeschlossen /* Pinbelegung (Achtung, LEDs schalten bei LOW ein) 2, 3, 4, 5, 6 = Wohnhaus 13, 14, 15, 16 = Wohnhaus 12 = TV 7 = Werbung 1 8 = Werbung 2 9 = Straßenlampen 1 10 = Straßenlampen 2 11 = defekte Straßenlampe */ /* Speicher-Variablen */ int strassenlampenHelligkeit = 0; // speichert, wie hell die Straßenlampen leuchten int werbeLed1 = 1; // speichert den Zustand der Werbe-LED 1 int werbeLed2 = 1; // speichert den Zustand der Werbe-LED 2 /* Timer Variablen */ long strassenlampenTimer = 0; // Timer der Straßenlampen /* 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 /* for (int i = 0; i < 13; i++) { pinMode(ledPins[i], OUTPUT); digitalWrite(ledPins[i], HIGH); }*/ pinMode(werbePin1, OUTPUT); pinMode(werbePin2, OUTPUT); for (int i = 0; i < 10; i++) { pinMode(wohnPins[i], OUTPUT); digitalWrite(wohnPins[i], HIGH); } 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 tvAus(); // TV ausschalten werbelichtEin(); // Zeigt die Lichter von Geschäften oder Billboards hauslichterAus(); // Häuserbeleuchtung ausschalten } else if (myTime > 18) { // ***** Abend ***** strassenlampenAn(); // Straßenlampen an tvEin(); // TV einschalten werbelichtEin(); // Zeigt die Lichter von Geschäften oder Billboards hauslichterEin(); // Häuserbeleuchtung einschalten } else if (myTime > 12) { // ***** Nachmittag ***** strassenlampenAus(); // Straßenlampen aus tvAus(); // TV ausschalten werbelichtAus(); // schaltet die Werbelichter aus hauslichterAus(); // Häuserbeleuchtung ausschalten } else if (myTime > 9) { // ***** Vormittag ***** strassenlampenAus(); // Straßenlampen aus tvAus(); // TV ausschalten werbelichtAus(); // schaltet die Werbelichter aus hauslichterAus(); // Häuserbeleuchtung ausschalten } else if (myTime > 7) { // ***** Morgen ***** strassenlampenAn(); // Straßenlampen an tvAus(); // TV ausschalten werbelichtAus(); // schaltet die Werbelichter aus hauslichterAus(); // Häuserbeleuchtung ausschalten } else { // ***** Nacht ***** strassenlampenAn(); // Straßenlampen an tvAus(); // TV ausschalten werbelichtEin(); // Zeigt die Lichter von Geschäften oder Billboards hauslichterAus(); // Häuserbeleuchtung einschalten } } } void tvEin() { if (random(500) == 1) analogWrite(tvPin, random(150)); } void tvAus() { analogWrite(tvPin, 255); } void werbelichtEin() { if (werbeBlinken1 == 0) { digitalWrite(werbePin1, LOW); } else if (millis() % werbeBlinken1 * 2 < werbeBlinken1) { digitalWrite(werbePin1, LOW); } else { digitalWrite(werbePin1, HIGH); } if (werbeBlinken2 == 0) { digitalWrite(werbePin2, LOW); } else if (millis() % werbeBlinken2 * 2 > werbeBlinken2) { digitalWrite(werbePin2, LOW); } else { digitalWrite(werbePin2, HIGH); } } void werbelichtAus() { digitalWrite(werbePin1, HIGH); digitalWrite(werbePin2, HIGH); } void hauslichterEin() { if (random(einschaltWahrscheinlichkeit) == 1) { // Einschalten der Hausbeleuchtung per Zufall digitalWrite(wohnPins[random(10)], LOW); } } void hauslichterAus() { if (random(ausschaltWahrscheinlichkeit) == 1) { // Einschalten der Hausbeleuchtung per Zufall digitalWrite(wohnPins[random(10)], HIGH); } } void strassenlampenAn() { if (strassenlampenTimer + strassenlampenTimeout < millis()) { strassenlampenHelligkeit++; if (strassenlampenHelligkeit > 255) strassenlampenHelligkeit = 255; strassenlampenTimer = millis(); analogWrite(strassenlampenPin1, 255 - strassenlampenHelligkeit); analogWrite(strassenlampenPin2, 255 - strassenlampenHelligkeit); analogWrite(strassenlampenPin3, 255 - strassenlampenHelligkeit); } if (strassenlampeFlackern != 0) { if (random(strassenlampeFlackern) == 1) analogWrite(strassenlampenPin3, random(255) - strassenlampenHelligkeit); } } void strassenlampenAus() { strassenlampenHelligkeit = 0; analogWrite(strassenlampenPin1, 255); analogWrite(strassenlampenPin2, 255); analogWrite(strassenlampenPin3, 255); strassenlampenTimer = millis(); } 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,
habe nun das Control sowie Siedlungs Modul programmiert und getestet.
Hat alles auf Anhieb funktioniert.
Danke nochmal für das tolle Projekt.
Da ich in den einzelnen Häusern nicht so viele Ausgänge bzw. Strassenlampen
benötige, spricht was dagene, “kleinere” Arduino Pro Micro mit 328 oder 168 CPU zu verwenden?
Da könnte ich noch mehrere von einem Bekannten bekommen, die übrig sind.
Grüsse
Wolfgang
Hi Wolfgang, danke für deinen Kommentar. Da spricht eigentlich nichts dagegen. Vielleicht musst du noch mal die Pin-Zuordnung anpassen, aber ansonsten sollte das funktionieren. Liebe Grüße Stefan
Hallo Stefan,
hat alles super funktioniert mit der Anpassung aif den Arduino Pro Micro.
Eine Frage hätte ich noch:
Gibt es die Möglichkeit, die Anzahl der Ausgänge per Zufall zu begrenzen?
Dass zum Schluss nicht alles Augänge leuchten, sondern z.B. nur 5. Sind ja nie
alle Bewohner zuhause. Und diese zufällig,also jedesmal anderst ausgewählt.
Vermutlich in dem Abschnitt
void hauslichterEin() {
if (random(einschaltWahrscheinlichkeit) == 1) { // Einschalten der Hausbeleuchtung per Zufall
digitalWrite(wohnPins[random(10)], LOW);
}
}
irgendwo einen Zähler
Grüsse
Wolfgang
Hi Wolfgang, hm, gute Frage. Das Begrenzen mit dem aktuellen Code ist erstmal nicht so einfach. Du könntest aber mal versuchen, den Wert der Einschaltwahrscheinlichkeit hochzusetzen (Variable: einschaltWahrscheinlichkeit). Hast du das schon mal versucht? Liebe Grüße Stefan
Hallo Stefan,
ich hatte mir überlegt, so wie in Deinem Lottozahlengenerator
eine Auswahl an “wohnPins” zu “ziehen” und nur diese dann anzuschalten.
Quasi 5 oder 6 aus 10. Werde versuchen, das die nächsten Tage
umzusetzen.
Grüsse
Wolfgang
Hi Wolfgang, ist auf jeden Fall eine spannende Aufgabe. Ich drück dir die Daumen :-) Liebe Grüße Stefan
Hallo
Ich würde gerne das SiedlungsModul über ein ULN 2803 betreiben. Da ich noch ein paar Laternen mit Glühampen habe und ich diese nicht tauschen möchte. Und so kann ich ja Theoretisch die Ausgänge höher belasten aber ich habe jetzt das problem das mit ULN 2803 die lampen weiter leuchten.
Hi Matze, hast du den Pin 9 vom ULN an GND? Liebe Grüße Stefan
Ja habe ich und konnte das problem selber lösen. Da du die LED bei low einschaltest. Sind bei mir die Häuser angegangen wenn sie aus gehen sollen und andersrum. Ich habe dann einfach die low und high befehle getauscht und es hat funktioniert.
Danke für deine hilfe und super arduino projekte.
Gruß Matze
Habe jetzt das Control Modul und das Siedlungs Modul zusammen. Funktioniert sehr gut aber wo und wie kann ich die ein/aus schaltzeit der Beleuchtung ändern??
Hi Matze, das geht in der Loop-Funktion bei den if-Anweisungen. Da sind die Tageszeiten bestimmten Uhrzeiten zugewiesen (z.B. if (myTime > 22) … ) und die könntest du ändern. Probier es mal. Es ist dieser Block:
if (myTime > 22) { // ***** Später Abend *****
strassenlampenAn(); // Straßenlampen an
tvAus(); // TV ausschalten
werbelichtEin(); // Zeigt die Lichter von Geschäften oder Billboards
hauslichterAus(); // Häuserbeleuchtung ausschalten
} else if (myTime > 18) { // ***** Abend *****
strassenlampenAn(); // Straßenlampen an
tvEin(); // TV einschalten
werbelichtEin(); // Zeigt die Lichter von Geschäften oder Billboards
hauslichterEin(); // Häuserbeleuchtung einschalten
} else if (myTime > 12) { // ***** Nachmittag *****
strassenlampenAus(); // Straßenlampen aus
tvAus(); // TV ausschalten
werbelichtAus(); // schaltet die Werbelichter aus
hauslichterAus(); // Häuserbeleuchtung ausschalten
} else if (myTime > 9) { // ***** Vormittag *****
strassenlampenAus(); // Straßenlampen aus
tvAus(); // TV ausschalten
werbelichtAus(); // schaltet die Werbelichter aus
hauslichterAus(); // Häuserbeleuchtung ausschalten
} else if (myTime > 7) { // ***** Morgen *****
strassenlampenAn(); // Straßenlampen an
tvAus(); // TV ausschalten
werbelichtAus(); // schaltet die Werbelichter aus
hauslichterAus(); // Häuserbeleuchtung ausschalten
} else { // ***** Nacht *****
strassenlampenAn(); // Straßenlampen an
tvAus(); // TV ausschalten
werbelichtEin(); // Zeigt die Lichter von Geschäften oder Billboards
hauslichterAus(); // Häuserbeleuchtung einschalten
}
Liebe Grüße Stefan