Zum Inhalt springen
RailFX-Einsatzstelle Blaulicht, Sirene, MP3 Player mit Arduino Nano

RailFX Einsatzstelle – mit Arduino und Blaulicht

    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.

    Wir benötigen Ihre Zustimmung um den Inhalt von YouTube laden zu können.

    Mit dem Klick auf das Video werden durch den mit uns gemeinsam Verantwortlichen Youtube [Google Ireland Limited, Irland] das Video abgespielt, auf Ihrem Endgerät Skripte geladen, Cookies gespeichert und personenbezogene Daten erfasst. Damit kann Google Aktivitäten im Internet verfolgen und Werbung zielgruppengerecht ausspielen. Es erfolgt eine Datenübermittlung in die USA, diese verfügt über keinen EU-konformen Datenschutz. Weitere Informationen finden Sie hier.

    Jmx0O2RpdiBjbGFzcz0mcXVvdDtudi1pZnJhbWUtZW1iZWQmcXVvdDsmZ3Q7Jmx0O2lmcmFtZSB0aXRsZT0mcXVvdDtSYWlsRlggRWluc2F0enN0ZWxsZSAmbmRhc2g7IEVmZmVrdGUgZiZ1dW1sO3IgTW9kZWxsYmFobiB1bmQgTW9kZWxsYmF1IG1pdCBBcmR1aW5vJnF1b3Q7IHdpZHRoPSZxdW90OzEyMDAmcXVvdDsgaGVpZ2h0PSZxdW90OzY3NSZxdW90OyBzcmM9JnF1b3Q7aHR0cHM6Ly93d3cueW91dHViZS5jb20vZW1iZWQvdWhtUWtHUGJZMWs/ZmVhdHVyZT1vZW1iZWQmcXVvdDsgZnJhbWVib3JkZXI9JnF1b3Q7MCZxdW90OyBhbGxvdz0mcXVvdDthY2NlbGVyb21ldGVyOyBhdXRvcGxheTsgY2xpcGJvYXJkLXdyaXRlOyBlbmNyeXB0ZWQtbWVkaWE7IGd5cm9zY29wZTsgcGljdHVyZS1pbi1waWN0dXJlJnF1b3Q7IGFsbG93ZnVsbHNjcmVlbiZndDsmbHQ7L2lmcmFtZSZndDsmbHQ7L2RpdiZndDs=

    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.


    Sieh dir jetzt meinen neuen Arduino-Videokurs an: Jetzt ansehen!


    Bauteile

    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:

    Wir benötigen Ihre Zustimmung um den Inhalt von YouTube laden zu können.

    Mit dem Klick auf das Video werden durch den mit uns gemeinsam Verantwortlichen Youtube [Google Ireland Limited, Irland] das Video abgespielt, auf Ihrem Endgerät Skripte geladen, Cookies gespeichert und personenbezogene Daten erfasst. Damit kann Google Aktivitäten im Internet verfolgen und Werbung zielgruppengerecht ausspielen. Es erfolgt eine Datenübermittlung in die USA, diese verfügt über keinen EU-konformen Datenschutz. Weitere Informationen finden Sie hier.

    Jmx0O2RpdiBjbGFzcz0mcXVvdDtudi1pZnJhbWUtZW1iZWQmcXVvdDsmZ3Q7Jmx0O2lmcmFtZSB0aXRsZT0mcXVvdDtSVFcmcXVvdDsgd2lkdGg9JnF1b3Q7MTIwMCZxdW90OyBoZWlnaHQ9JnF1b3Q7Njc1JnF1b3Q7IHNyYz0mcXVvdDtodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC8yZGc0NmFudVkyVT9mZWF0dXJlPW9lbWJlZCZxdW90OyBmcmFtZWJvcmRlcj0mcXVvdDswJnF1b3Q7IGFsbG93PSZxdW90O2FjY2VsZXJvbWV0ZXI7IGF1dG9wbGF5OyBjbGlwYm9hcmQtd3JpdGU7IGVuY3J5cHRlZC1tZWRpYTsgZ3lyb3Njb3BlOyBwaWN0dXJlLWluLXBpY3R1cmUmcXVvdDsgYWxsb3dmdWxsc2NyZWVuJmd0OyZsdDsvaWZyYW1lJmd0OyZsdDsvZGl2Jmd0Ow==

    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


    9 Gedanken zu „RailFX Einsatzstelle – mit Arduino und Blaulicht“

    1. 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

      1. 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

    2. 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.

    3. 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

    4. 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

      1. 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

        1. Hallo Stefan,
          es erscheint nur einmalig:12:22:54.549 -> Initializing DFPlayer …
          12:22:55.251 -> DFPlayer Mini online.
          Viele Grüße, Horst

          1. 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

    Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht.

     

    Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.