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


    7 Gedanken zu „RailFX Kirche mit Arduino Nano“

    1. Hallo Stefan,
      ich habe das Control-Modul und die Kirchenglocken nachgebaut. Bei der 1. Version hatte ich keinen originalen Arduino Nano. Bei diesem hatte ich den Bootloader verwendet, wie du ihn angegeben hast und es klappte alles. Bei der 2. Version hatte ich einen originalen Arduino Nano. Da klappte das Aufspielen mit der Einstellung für den “alten Bootloader” nicht. Erst nachdem ich auf Atmega328P umgestellt hatte. ließ sich der Sketch für die Kirchenglocken aufspielen. Das wollte ich nur mal zur Info geben.
      Deine Sketche finde ich sehr gut beschrieben und sie lassen sich einfach nachbauen. In einigen verwendest du einen Taster. Gibt es einen bestimmten, wegen der Größe?

      Viele Grüße
      Dieter

      1. Hallo Dieter,

        vielen Dank für die Info, das ist mir tatsächlich neu. Das muss ich mir genauer ansehen. Bei den Tastern gibt es keinen bestimmten. Da kann man vom Mikrotaster bis zum Wohnungslichttaster alles verwenden.

        Liebe Grüße
        Stefan

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

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