Zum Inhalt springen
RailFX Kirche mit Arduino Sound Glocken MP3

RailFX Kirche mit Arduino Nano

Michael schreibt: »[…] Meine Frage ist, ob es bei dem Soundmodul die Möglichkeit gibt, eine bestimmte MP3-Datei immer zu jeder vollen Stunde zu spielen (Schlagen einer Kirchturmuhr). […]« Klingt für mich nach einem RailFX Modul: Kirche mit Arduino!

Das folgende RailFX-Modul kann also zu jeder Stunde einen Ton abspielen. Wann genau welcher Ton abgespielt wird, lässt sich leicht einstellen.

Das können natürlich Glockenklänge sein, oder auch der Chor oder die Orgel. Und natürlich lässt sich dieses Modul für Kirchen, Synagogen, Moscheen, Tempel und vieles mehr verwenden. Ich muss allerdings gestehen, dass ich mich im Detail mit keinem der genannten Einrichtungen auskenne.


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


Bauteile

Schaltung und Aufbau

Das Modul basiert auf dem Arduino Nano. Da es in erster Linie nur um die Soundausgabe ging, ist nebem dem MP3-Player-Modul nur eine LED für die Innenbeleuchtung der Kirche vorgesehen. Sie ist am Pin D9 angeschlossen.

Für die Tonausgabe wird wieder der DFPlayer Mini verwendet. Er spielt MP3- und WAV-Dateien von einer SD-Karte ab. Für die Nutzung muss die DFPlayer Mini Bibliothek eingebunden werden. Klicke dafür im Arduino-Menü auf Sketch>Bibliotheken einbinden>Bibliotheken verwalten und gib im Suchfeld »dfplayer mini« ein. Installiere die Bibliothek DFPlayer Mini MP3 by Makuna in der aktuellen Version.

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 …

Ich habe ziemlich gute Glockensounds bei mixkit.co gefunden.

Achtung: Am Pin A4 ist das Control-Signal des RailFX Control-Moduls angelegt. Es steuert die Tageszeit und ist zwingend erforderlich. Für das gesamte System reicht allerdings ein einziges Control-Modul aus.

Einstellungen im Code

Im Code lassen sich verschiedene Einstellungen vornehmen. Je nachdem, wie viele unterschiedliche Glockenklänge man verwenden möchte, müssen die Dateien wie oben beschreiben auf eine SD-Karte kopiert werden. Im Array glockenschlag[24] kann man 24 Zahlen eingeben. Sie repräsentieren die Sound-Datei, die abgespielt wird, die Stelle im Array gibt die Stunde an, zu der die Datei abgespielt wird. Eine 1 an der ersten Stelle im Array bedeutet also, dass die Datei 001.mp3 (oder wav) um 1 Uhr abgespielt wird. Eine 2 an Stelle 10 bedeutet, dass die Datei 002.mp3 (oder wav) um 10 Uhr abgespielt wird usw.

Die Variable lautstaerke kann die Lautstärke des DFPlayers beeinflussen. Dabei können Zahlen zwischen 0 und 30 angegeben werden.

Über die Variable mp3Wahrscheinlichkeit kann man eine gewisse Varianz einbringen. Setzt man sie auf 1, werden die Sounds immer abgespielt, erhöht man ihren Wert, werden die Sounds mit abnehmender Wahrscheinlichkeit abgespielt. Also: Je höher der Wert, desto seltener werden die Sounds abgespielt.

/* ***** ***** Einstellungen ***** ***** ***** *****  ***** ***** ***** *****  ***** ***** ***** ***** */
int lautstaerke = 10;                    // Lautstärke des DFPlayers (0 – 30);
int glockenschlag[24] = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 2, 1, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0}; // Zu welcher Stunde soll welches MP3 abgespielt werden? Beginnt ab 1 Uhr
int mp3Wahrscheinlichkeit = 1;          // Wahrscheinlichkeit, mit der MP3s abgespielt werden, 1 immer, 10 oft, 100 selten

Gesamter Programm-Code: Kirche mit Arduino

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.

/*
     Rail-FX Kirche
     StartHardware.org

     Permalink: https://starthardware.org/railfx-kirche-mit-arduino-nano/

     Sounds kann man gut von hier holen:
     https://mixkit.co/free-sound-effects/church/
*/

#include "SoftwareSerial.h"              // Wird für den DFPlayer benötigt
#include "DFRobotDFPlayerMini.h"         // Wird für den DFPlayer benötigt

/* ***** ***** Einstellungen ***** ***** ***** *****  ***** ***** ***** *****  ***** ***** ***** ***** */
int lautstaerke = 10;                    // Lautstärke des DFPlayers (0 – 30);
int glockenschlag[24] = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 2, 1, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0}; // Zu welcher Stunde soll welches MP3 abgespielt werden? Beginnt ab 1 Uhr
//int glockenschlag[24] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // Diese Zeile würde pro Stunde das MP3 (oder WAV) 001.mp3 (001.wav) abspielen
int mp3Wahrscheinlichkeit = 1;          // Wahrscheinlichkeit, mit der MP3s abgespielt werden, 1 immer, 10 oft, 100 selten

/* ***** ***** Ab hier beginnt der Programmcode, der nicht angepasst werden muss ***** ***** ***** ***** */

int beleuchtungsPin = 9;                 // an diesem Pin ist die Kirchenbeleuchtung 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 */

/* Timer Variablen */
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;
int myLastTime = 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(beleuchtungsPin, OUTPUT);       // Pin für die Kirchenbeleuchtung

  /* DFPlayer Setup */
  Serial.println(F("Initializing DFPlayer ... "));
  if (!myDFPlayer.begin(mySoftwareSerial)) {  // 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 != myLastTime) && (myTime > -1) && (myTime < 24)) { // Prüft, ob sich die Zeit geändert hat.
      Serial.print("myTime= \t");Serial.println(myTime);
      soundAn(glockenschlag[myTime]);                           // Sound An
    }

    if (myTime > 22) {              // ***** Später Abend *****
      beleuchtungAn();              // Beleuchtung einschalten
    } else if (myTime > 18) {       // ***** Abend *****
      beleuchtungAn();              // Beleuchtung einschalten
    } else if (myTime > 12) {       // ***** Nachmittag *****
      beleuchtungAus();             // Beleuchtung ausschalten
    } else if (myTime > 9) {        // ***** Vormittag *****
      beleuchtungAus();             // Beleuchtung ausschalten
    } else if (myTime > 7) {        // ***** Morgen *****
      beleuchtungAus();             // Beleuchtung ausschalten
    } else {                        // ***** Nacht *****
      beleuchtungAn();              // Beleuchtung einschalten
    }
  }

  myLastTime = myTime;              // speichert die Zeit dieses Loop-Durchlaufes für den nächsten Durchlauf
}

void beleuchtungAn() {
  digitalWrite(beleuchtungsPin, LOW);
}

void beleuchtungAus() {
  digitalWrite(beleuchtungsPin, HIGH);
}

void soundAn(int mp3Index) {
  if (mp3Index != 0) {
    soundRandom = random(mp3Wahrscheinlichkeit);
    if (soundRandom < 1) {
      theSound = mp3Index;
      Serial.print("Playsound: \t"); Serial.println(theSound);
      myDFPlayer.playFolder(1, theSound); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255)
    }
  }
}


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 Kirche mit Arduino Nano“

  1. Hallo,
    RailFX ist ein sehr interessantes Projekt.
    Damit kann man den Spielwert der Bahn ungemein erhöhen.
    Eine Frage hätte ich aber noch: Wie lang dürfen die
    Leitungen zwischen dem Control Modul und den
    Erweiterungsmodulen den sein?
    Grüsse Wolfgang

  2. Hallo,
    danke für den Code. Ich denke du hast noch einen kleinen Fehler in Code, wenn ich mit der vorgegebenen Verdrahtung arbeite leuchtet die Kirchenbeleuchtung, wenn sie aus sein sollte. Im Programmcode steht auch bei Beleuchtung an LOW und bei aus HIGH aus. Ich hab es schon bei mir geändert, ich weiß nicht ob du es auch machen willst.

    So jetzt hab ich noch eine verrückte Idee, hab aber keine Ahnung ob das geht, da ich keine Ahnung habe wie schnell eine RFID ausgelesen werden kann. Meine Idee wäre folgende: Jede Modellbahnlok würde einen RF Chip bekommen, auf der Strecke wird zum Beispiel vor dem Bahnhof ein Lesegerät angebracht.
    Mit den Code vom Chip könnte man dann auf den jeweilige Zuge abgestimmte durchsagen machen, zum Beispiel: “Achtung auf Gleis 1 durchfahrender Güterzug.” oder “Achtung auf Gleis 5, Einfahrt des Intercity von Dortmund nach Kassel.”
    Wie ist deine Meinung dazu?

    Liebe Grüße Michael

    1. Hi Michael, danke für den Hinweis. Das ändere ich noch. Ob das mit dem RFID-Chip so schnell geht, weiß ich nicht genau. Wäre aber schon eine coole Idee. Liebe Grüße Stefan

      1. Hi, Ihr zwei…
        Ich habe bei meiner Modelleisenbahn mit Märklin C-Gleis RFID Lesemodule verbaut…
        Personen Züge fahren bei mir in den Bahnhof, Güterzüge auf die Bergstrecke…
        Funktioniert einwandfrei…
        Grüße Peter

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.