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 Fahrzeug-Beleuchtungen an den Pins 13 und 14 (A0) ein.

Achtung: Am Pin A4 ist wird 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 …

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 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-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
}

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


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

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

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

 

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