Dieses Modul des RailFX-Systems steuert eine Einsatzstelle. Dazu gehören vier Blaulicht-Paare, die in unterschiedlichen Geschwindigkeiten blinken können, einem 3-Kanal-Lauflicht, z. B. für Absperrungen, einem Blitzlicht, Fahrzeugbeleuchtung (Scheinwerfer, Rückleuchten) und einer Unfallstellen-Beleuchtung am Abend. Damit lassen sich Feuerwehr und/oder Polizeieinsätze mit dazugehörigen Effekten ausstatten. Dieses Modul verfügt darüber hinaus über eine Sound-Ausgabe per DFPlayer-Mini.
Schaltplan
Das Modul basiert auf dem Arduino Nano. Vier Blaulicht-Paare sind an die Pins 4, 5, 6, 7, 15 (A1), 16 (A2), 17 (A3), 19 (A5) angeschlossen. Dabei werden die analogen Pins als digitale Pins verwendet. Das 3-Kanal-Lauflicht ist mit den Pins 10, 11, 12 und das Blitzlicht mit Pin 9 verbunden. Nachts wird die Einsatzstelle über den Pin 8 beleuchtet. Gleichzeitig schaltet sich auch eine Fahrzeugbeleuchtung an den Pins 13 und 14 (A0) ein.
Achtung: Am Pin A4 ist das Control-Signal des RailFX Control-Moduls angelegt. Es steuert die Tageszeit und ist zwingend erforderlich.
Bauteile
- LEDs
- DFPlayer Mini MP3 Player Modul (Bitte nicht das ähnlich aussehende MP3-TP-16P Modul kaufen)
- MicroSD-Karte
- Lautsprecher
- 15x 220 Ohm Widerstand
Einstellungen im Code
Im Code lassen sich mehrere Einstellungen vornehmen. Diese sind in dem Code-Abschnitt näher erläutert. Es handelt sich im Grunde um die Geschwindigkeiten des Lauflichts und der Blaulichter.
Wie auch bei anderen Modulen mit Sound-Ausgabe wird hier ebenfalls der DFPlayer Mini verwendet. Er spielt MP3- und WAV-Dateien von einer SD-Karte ab. Die SD-Karte muss im FAT16 oder FAT32-Dateisystem formatiert sein. Darüber hinaus müssen sich die Dateien im Ordner »01« befinden und die Dateinamen müssen aufeinander folgend 001.mp3, 002.mp3, 003.mp3 usw. benannt sein. Wie erwähnt, dürfen auch WAV-Dateien verwendet werden: 001.mp3, 002.wav, 003.mp3 …
Ein paar Beispieldateien kann man hier herunterladen.
Die Anzahl der MP3-Dateien muss in der Variable mp3Anzahl angegeben werden. Dazu kann man die Abspieldauer der Dateien über die Variable mp3Dauer spezifizieren. Über mp3Wahrscheinlichkeit kann die Häufigkeit der Sound-Auslösung beeinflussen.
/* ***** ***** Einstellungen ***** ***** */ int lauflichtTimeout = 500; // Lauflicht Geschwindigkeit (ms) z. B. als Straßenabsperrung int blitzlichtZeit = 1000; // Blitzlicht Verzögerung int lautstaerke = 10; // Lautstärke des DFPlayers (0 – 30); int mp3Anzahl = 2; // Anzahl der MP3-Dateien auf der SD-Karte int mp3Dauer[] = {3, 14}; // Dauer der MP3-Dateien in Sekunden int mp3Wahrscheinlichkeit = 10; // Wahrscheinlichkeit, mit der MP3s abgespielt werden, 10 oft, 100 selten
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-Einsatzstelle-Modul
/* Rail-FX Einsatzstelle-Modul StartHardware.org */ #include "SoftwareSerial.h" // Wird für den DFPlayer benötigt #include "DFRobotDFPlayerMini.h" // Wird für den DFPlayer benötigt /* ***** ***** Einstellungen ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** */ int lauflichtTimeout = 500; // Lauflicht Geschwindigkeit (ms) z. B. als Straßenabsperrung int blitzlichtZeit = 1000; // Blitzlicht Verzögerung int lautstaerke = 10; // Lautstärke des DFPlayers (0 – 30); int mp3Anzahl = 2; // Anzahl der MP3 Dateien auf der SD-Karte int mp3Dauer[] = {3, 14}; // Dauer der MP3 Dateien in Sekunden int mp3Wahrscheinlichkeit = 10; // Wahrscheinlichkeit, mit der MP3s abgespielt werden, 10 oft, 100 selten /* ***** ***** Ab hier beginnt der Programmcode, der nicht angepasst werden muss ***** ***** ***** ***** */ int blaulichtPins[8] = {15, 16, 17, 19, 7, 6, 5, 4}; // Blaulicht Pins int lauflichtPins[3] = {10, 11, 12}; // Pins des Lauflichts int fahrzeugbeleuchtungPins[2] = {13, 14}; // Pins der Fahrzeugbeleuchtung int blitzlichtPin = 9; // an diesem Pin ist das Blitzlicht angebracht int beleuchtungsPin = 8; // an diesem Pin ist die Einsatzstellen-Beleuchtung angebracht /* State Variablen */ int soundState = 0; // Status des DFPlayers int soundRandom; // Hilfsvariable für die Soundausgabe int theSound; // Hilfsvariable für die Soundausgabe int soundPlaying = false; // Hilfsvariable für die Soundausgabe /* Speicher-Variablen */ int werbeLed1 = 1; // speichert den Zustand der Werbe-LED 1 int werbeLed2 = 1; // speichert den Zustand der Werbe-LED 2 int lauflichtPosition = 0; // speichert die Position des Lauflichts A /* Timer Variablen */ long lauflichtTimer; int blaulichtTimer[4] = {800, 700, 650, 730}; // Blaulicht Blitzfrequenz long soundTimer = 0; // Timer des DFPlayers long soundTimeout = 0; // Speichert die Abspieldauer des aktuellen MP3 /* Objekte anlegen */ SoftwareSerial mySoftwareSerial(3, 2); // RX, TX für den DFPlayer DFRobotDFPlayerMini myDFPlayer; // DFPlayer Objekt /* 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 mySoftwareSerial.begin(9600); // started die serielle Kommunikation für den DFPlayer pinMode(blitzlichtPin, OUTPUT); // Pin für das Blitzlicht pinMode(beleuchtungsPin, OUTPUT); // Pin für die Einsatzstellen-Beleuchtung for (int i = 0; i < 2; i++) { // Für die Anzahl der Fahrzeugbeleuchtung-Pins pinMode(fahrzeugbeleuchtungPins[i], OUTPUT); // Deklariere den Pin als Output digitalWrite(fahrzeugbeleuchtungPins[i], HIGH); // Schalte die LED an diesem Pin ab } for (int i = 0; i < 8; i++) { // Für die Anzahl der Blaulicht-Pins pinMode(blaulichtPins[i], OUTPUT); // Deklariere den Pin als Output digitalWrite(blaulichtPins[i], HIGH); // Schalte die LED an diesem Pin ab } for (int i = 0; i < 3; i++) { // Für die Anzahl der Lauflicht-Pins pinMode(lauflichtPins[i], OUTPUT); // Deklariere den Pin als Output digitalWrite(lauflichtPins[i], HIGH); // Schalte die LED an diesem Pin ab } /* DFPlayer Setup */ Serial.println(F("Initializing DFPlayer ... ")); if (!myDFPlayer.begin(mySoftwareSerial, false)) { // nutze softwareSerial um mit dem DFPlayer zu sprechen Serial.println(F("Fehler: Prüfe Verbindung zum DFPlayer und SD-Karte")); } Serial.println(F("DFPlayer Mini online.")); myDFPlayer.volume(lautstaerke); // Lautstärke wird zugewiesen } 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 ***** lauflichtAn(); // Lauflicht einschalten blaulichtAn(); // Blaulichter einschalten blitzlichtAn(); // Blitzlicht einschalten beleuchtungAn(); // Beleuchtung einschalten fahrzeugbeleuchtungAn(); // Fahrzeugbeleuchtung einschalten soundAn(); // Sound An } else if (myTime > 18) { // ***** Abend ***** lauflichtAn(); // Lauflicht einschalten blaulichtAn(); // Blaulichter einschalten blitzlichtAn(); // Blitzlicht einschalten beleuchtungAn(); // Beleuchtung einschalten fahrzeugbeleuchtungAn(); // Fahrzeugbeleuchtung einschalten } else if (myTime > 12) { // ***** Nachmittag ***** lauflichtAn(); // Lauflicht einschalten blaulichtAn(); // Blaulichter einschalten blitzlichtAn(); // Blitzlicht einschalten beleuchtungAus(); // Beleuchtung ausschalten fahrzeugbeleuchtungAus(); // Fahrzeugbeleuchtung ausschalten } else if (myTime > 9) { // ***** Vormittag ***** lauflichtAn(); // Lauflicht einschalten blaulichtAn(); // Blaulichter einschalten blitzlichtAn(); // Blitzlicht einschalten beleuchtungAus(); // Beleuchtung ausschalten fahrzeugbeleuchtungAus(); // Fahrzeugbeleuchtung ausschalten } else if (myTime > 7) { // ***** Morgen ***** lauflichtAn(); // Lauflicht einschalten blaulichtAn(); // Blaulichter einschalten blitzlichtAn(); // Blitzlicht einschalten beleuchtungAus(); // Beleuchtung ausschalten fahrzeugbeleuchtungAus(); // Fahrzeugbeleuchtung ausschalten } else { // ***** Nacht ***** lauflichtAn(); // Lauflicht einschalten blaulichtAn(); // Blaulichter einschalten blitzlichtAn(); // Blitzlicht einschalten beleuchtungAn(); // Beleuchtung einschalten fahrzeugbeleuchtungAn(); // Fahrzeugbeleuchtung einschalten } } } void fahrzeugbeleuchtungAn() { digitalWrite(fahrzeugbeleuchtungPins[0], LOW); digitalWrite(fahrzeugbeleuchtungPins[1], LOW); } void fahrzeugbeleuchtungAus() { digitalWrite(fahrzeugbeleuchtungPins[0], HIGH); digitalWrite(fahrzeugbeleuchtungPins[1], HIGH); } void beleuchtungAn() { digitalWrite(beleuchtungsPin, LOW); } void beleuchtungAus() { digitalWrite(beleuchtungsPin, HIGH); } void blaulichtAn() { for (int i = 0; i < 4; i++) { if (millis() % blaulichtTimer[i] < blaulichtTimer[i] / 2) { digitalWrite(blaulichtPins[i * 2], HIGH); digitalWrite(blaulichtPins[i * 2 + 1], LOW); } else { digitalWrite(blaulichtPins[i * 2], LOW); digitalWrite(blaulichtPins[i * 2 + 1], HIGH); } } } void blaulichtAus() { for (int i = 0; i < 8; i++) { digitalWrite(blaulichtPins[i], HIGH); } } void blitzlichtAn() { if (millis() % blitzlichtZeit < 40) { digitalWrite(blitzlichtPin, LOW); } else { digitalWrite(blitzlichtPin, HIGH); } } void blitzlichtAus() { digitalWrite(blitzlichtPin, HIGH); } void lauflichtAn() { if (lauflichtTimer + lauflichtTimeout < millis()) { lauflichtTimer = millis(); lauflichtPosition++; if (lauflichtPosition > 2) { lauflichtPosition = 0; } for (int i = 0; i < 3; i++) { digitalWrite(lauflichtPins[i], HIGH); } digitalWrite(lauflichtPins[lauflichtPosition], LOW); } } void lauflichtAus() { lauflichtTimer = millis(); for (int i = 0; i < 3; i++) { digitalWrite(lauflichtPins[i], HIGH); } } void soundAn() { switch (soundState) { case 0: Serial.println("soundTimer 0"); soundRandom = random(mp3Wahrscheinlichkeit); if (soundRandom < 1) { soundState = 1; theSound = random(mp3Anzahl) + 1; soundTimer = millis(); soundTimeout = mp3Dauer[theSound - 1] * 1000; Serial.print("Playsound: \t\t\t"); Serial.print(theSound); Serial.print("\t\t\t"); Serial.println(soundTimeout); myDFPlayer.playFolder(1, theSound); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) soundPlaying = true; } else { soundTimer = millis(); soundTimeout = 500; soundState = 1; } break; case 1: if (soundTimer + soundTimeout < millis()) { soundPlaying = false; soundState = 0; } break; } } void soundAus() { if (soundPlaying == true) { Serial.println(soundPlaying); myDFPlayer.pause(); soundPlaying = false; } } /* ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** */ 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 }
Und hier noch ein Video von Silvio dazu. Ich finde, die Umsetzung es ist echt super gelungen:
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
Hi,
Ich habe durch Zufall deine RailFX-Module gefunden, und es hat mir gleich gefallen.
Ich hatte sofort eine Idee, und es musste der rettungswagen von meinem Sohn her.
Bis auf den dfplayer und ein mini Lautsprecher hatte ich alles da.
Hier mal ein link von meinen umbau:
https://youtu.be/2dg46anuY2U
Mfg
Silvio
Hi Silvio, vielen Dank für das Video und schön, dass dir das RailFX gefällt :-)
Ich packe das Video mit in den Beitrag. Ich hoffe, das ist ok für dich. Sonst sag mir Bescheid.
Liebe Grüße Stefan
Hallo Stefan, kannst das Video gerne hinzufügen ;)
LG Silvio
Hallo ich habe eine Frage zu der Steuerung,
würde es auch möglich sein diese Statt Tageszeit abhängig per Taster zu Starten, da ich eine Brandsimulation mit Feuerwehreinsatz per Knopfdruck am Planen bin.
Hallo Stefan,
es erscheint nur einmalig:12:22:54.549 -> Initializing DFPlayer …
12:22:55.251 -> DFPlayer Mini online.
Spannung 4,93 V auf dem Board
Viele Grüße, Horst
Hallo Stefan,
ich finde das RailFX-System super, wenn denn alles, was ich nachbaute auch funktionieren würde. Zeitsteuerung läuft, Raumbeleuchtung läuft, Einsatzstelle will nicht ganz funktionieren, Die Beleuchtungen sind immer aktiv, auch das PKW-Licht und die Ausleuchtung der Unfallstelle. Der DF-Player bekommt beim Starten einen Impuls (LED leuchtet einmal auf) spielt aber nicht ab, obwohl das Format von Disk, Ordner und Dateien ist, wie es sein soll. Was ich halt nicht wegbekomme ist neben dem Ordner 01 der Systemordner. Stört der? Ansonsten ist der DF-Player funktionsfähig als Standalone-Player mit entsprechendem Sketch und dem gleichen Widerstand. Gibt es für den Sketch der RailFX-Einsatzstelle Einschränkungen der mp3-Laufzeit?
Viele Grüße, Horst
Hallo Horst,
es gibt keine Einschränkungen in der Laufzeit, soweit ich weiß. Der Systemordner sollte auch nicht problematisch sein. Das ist bei mir auch so. Hast du mal im Seriellen Monitor geprüft, ob das Zeitsignal ankommt? Das sollte zu jeder Modellbau-Stunde eine Zahl anzeigen. Kann auch sein, dass der Strom im System nicht ausreicht. Sag mir aber erst mal Bescheid, ob das Zeitsignal angezeigt wird.
Liebe Grüße Stefan
Hallo Stefan,
es erscheint nur einmalig:12:22:54.549 -> Initializing DFPlayer …
12:22:55.251 -> DFPlayer Mini online.
Viele Grüße, Horst
Hallo Horst,
also es sieht wirklich so aus, als ob das Zeitsignal vom Control-Modul nicht ankommt. Kannst du die Verbindung noch mal prüfen? Es muss ein Kabel vom Control-Modul A4 zu allen anderen Modulen im System (auch meistens A4) geben. Dazu müssen alle Module wenigstens mit dem GND verbunden sein. Schickst du mir mal ein Foto vom Aufbau? Dann gucke ich noch mal rein: hallo@starthardware.org
Liebe Grüße
Stefan