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 von einander blinken.
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 Fussball 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 wird 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 Werkzeugemenü 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
}
RailFX-Module
Zurzeit gibt es folgende Projekt-Module:
Wenn dir das Projekt gefallen hat und du von weiteren interessanten Projekten inspiriert werden willst, sieh dir doch mal mein neues E-Book an!
Darin findest du die beliebtesten Arduino-Projekte von StartHardware. Jedes Projekt umfasst Schaltplan, Bauteile, Beschreibung und Code. Für Einsteiger gibt es ein Arduino-Schnellstart-Kapitel und einen kompakten Programmierkurs. Zusätzlich findest du Zwischenkapitel mit Expertenwissen zu den Komponenten, die verwendet werden. Alle Code-Beispiele gibt es natürlich als Download.
Weitere Informationen findest du auf der Produktseite. Klicke jetzt auf den Button, um Details anzusehen.