Zum Inhalt springen
Jukebox mit Arduino

Jukebox mit Arduino

    In dieser Anleitung zeige ich dir, wie du eine Jukebox mit Arduino bauen kannst. Hier geht es um die Elektronik und die Tonausgabe. Die Musik werden wir von einer SD-Karte abspielen. Doch eine Jukebox besteht natürlich aus mehr: Licht, Oberflächen, liebevoll gestalteten Musikauswahlschildern, Holz, Chrom, Kunststoff – diesen Teil überlasse ich aber dir :-)

    Was brauchen wir für die Jukebox? Natürlich erstmal ein Arduino. Dazu eine Reihe von Tastern für die Auswahl und ein Modul, das MP3s abspielen kann. Dafür verwende ich gern den DFPlayer Mini, denn dieser ist nicht nur sehr günstig zu haben, sondern auch sehr einfach zu verwenden. Dann benötigst du entweder aktive Lautsprecher oder einen Vorverstärker. Zum Testen reicht aber auch erstmal ein normaler kleiner Lautsprecher. Fassen wir die Bauteile noch einmal zusammen:

    Bauteile

    Du kannst auch gebrauchte Desktop-Speaker von Ebay kaufen oder im Freundeskreis rumfragen. Bei vielen Leuten liegen solche Sachen im Keller. Besser werden sie da nicht ;-)


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


    Schaltung

    Die Schaltung unterscheidet sich kaum von der Schaltung für die Sound Machine mit Arduino. Unser Use Case ist aber natürlich ein anderer und hier verwenden wir zwei Lautsprecher (Stereo).

    Jukebox mit Arduino Stereo Lautsprecher Schaltung

    Die Schaltung besteht aus dem DFPlayer Mini, zwei Lautsprechern und 16 Taster, wobei die Anzahl an Tastern der Musikauswahl entspricht. Du kannst auch weniger Taster verwenden oder mithilfe eines Shift-Registers noch mehr Taster anschließen.

    Der DFPlayer wird mit GND und 5V versorgt und an die SoftwareSerial-Pins 10 und 11 verbunden. Die Verbindung mit dem Pin 11 bekommt noch einen 1kOhm Widerstand. Die Lautsprecher werden direkt an den DFPlayer angeschlossen.

    Wir verwenden für die Taster, die später die Musiktitel starten sollen, die internen Pull-up-Widerstände des Arduino-Boards. Alle Taster sind mit dem GND und jeweils einem digitalen oder analogen Pin des Arduinos verbunden. (Die analogen Input-Pins lassen sich nämlich auch einfach als digitale Pins zum Auslesen von Tastern verwenden.)

    Jukebox mit Arduino Stereo Lautsprecher Schaltung Korrekte Variante

    Das Datenblatt des DFPlayers gibt an, dass die Pins DAC R und DAC L zur Verwendung von Kopfhörern oder Vorverstärkern genutzt werden sollen. Allerdings erzeugen diese Anschlüsse bei mir extremes Rauschen, das wahrscheinlich durch die Spannungswandlung des Arduinos kommt.

    Besser funktioniert für mich die Verwendung der Speaker-Pins. Allerdings sollte die Lautstärke im Code sehr weit runtergeregelt werden:

    Wenn man das GND-Kabel so nah wie möglich am GND des DFPlayers anschließt, wird die Sound-Qualität erträglich.

    Ab hier wäre der weitere Weg also in die aktiven Lautsprecher oder den Vorverstärker. Das habe ich mal nicht extra aufgezeichnet.

    SD-Karte

    Kopiere jetzt deine Lieblings-Songs auf eine SD-Karte. Achte darauf, dass diese im FAT16 oder FAT32 Format formatiert ist. Die einzelnen MP3-Dateien müssen in einem Ordner mit dem Namen »MP3« im Hauptverzeichnis (root) der SD-Karte zu finden sein.

    Mac-User sollten beim Formatieren darauf achten, dass sie auch Master Boot Record im Festplattendienstprogramm auswählen.

    Code

    Binde für die Verwendung des DFPlayers die Programmbibliothek DFRobotDFPlayerMini ein. Gehe dafür in der Arduino-Software ins Menü Sketch>Programmbibliotheken einbinden>Programmbibliotheken verwalten … und gib im Suchfeld DFPlayer ein. Installiere die erwähnte Bibliothek DFRobotDFPlayerMini.

    #include "Arduino.h"
    #include "SoftwareSerial.h"
    #include "DFRobotDFPlayerMini.h"
    
    SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
    DFRobotDFPlayerMini myDFPlayer;
    
    int buttonPins[16] = {19,18,17,16,15,14,2,3,4,5,6,7,8,9,12,13};   // Pins, an denen die Taster angeschlossen sind
    
    void setup() {
      mySoftwareSerial.begin(9600);           // Start der SoftwareSerial Kommunikation
      Serial.begin(115200);                   // Start der "normalen" seriellen Kommunikation für den Serial Monitor
    
      if (!myDFPlayer.begin(mySoftwareSerial)) {  // Verbindung der Software Serial Kommunikation mit dem DFPlayer
        Serial.println(F("Unable to begin:"));
        Serial.println(F("1.Please recheck the connection!"));
        Serial.println(F("2.Please insert the SD card!"));
        while(true){                          // Programmabbruch -> while(true) ist Endlosschleife
          delay(0);                           // Code für den Watchdog des ESP8266, nicht relevant für Arduino UNO
        }
      }
        
      myDFPlayer.volume(10);                      // Lautstärke auf 10 ( Werte von 0 – 30 ist möglich)
      for (int i=0; i<16; i++){                   // wiederhole 16 Mal (für jeden Taster)
        pinMode(buttonPins[i], INPUT_PULLUP);     // Taster werden mit internen Pullup-Widerständen verwendet  
      }
      
    }
    
    void loop() {
      for (int i=0; i<16; i++){                   // wiederhole 16 Mal (für jeden Taster)
        if (digitalRead(buttonPins[i]) == LOW){   // wenn ein Taster gedrückt wird
         Serial.println(i);
         myDFPlayer.playMp3Folder(i+1);                      // spiele das MP3 der Nummer des Tasters nach von der SD-Karte
         delay(200);
        }
      }
      delay(20);
    
      /* Alles ab hier dient dem Debugging und kommt aus den Beispiel-Dateien der Library */
      if (myDFPlayer.available()) {
        printDetail(myDFPlayer.readType(), myDFPlayer.read()); // Print the detail message from DFPlayer to handle different errors and states.
      }
    }
    
    void printDetail(uint8_t type, int value){
     
      switch (type) {
        case TimeOut:
          Serial.println(F("Time Out!"));
          break;
        case WrongStack:
          Serial.println(F("Stack Wrong!"));
          break;
        case DFPlayerCardInserted:
          Serial.println(F("Card Inserted!"));
          break;
        case DFPlayerCardRemoved:
          Serial.println(F("Card Removed!"));
          break;
        case DFPlayerCardOnline:
          Serial.println(F("Card Online!"));
          break;
        case DFPlayerUSBInserted:
          Serial.println("USB Inserted!");
          break;
        case DFPlayerUSBRemoved:
          Serial.println("USB Removed!");
          break;
        case DFPlayerPlayFinished:
          Serial.print(F("Number:"));
          Serial.print(value);
          Serial.println(F(" Play Finished!"));
          break;
        case DFPlayerError:
          Serial.print(F("DFPlayerError:"));
          switch (value) {
            case Busy:
              Serial.println(F("Card not found"));
              break;
            case Sleeping:
              Serial.println(F("Sleeping"));
              break;
            case SerialWrongStack:
              Serial.println(F("Get Wrong Stack"));
              break;
            case CheckSumNotMatch:
              Serial.println(F("Check Sum Not Match"));
              break;
            case FileIndexOut:
              Serial.println(F("File Index Out of Bound"));
              break;
            case FileMismatch:
              Serial.println(F("Cannot Find File"));
              break;
            case Advertise:
              Serial.println(F("In Advertise"));
              break;
            default:
              break;
          }
          break;
        default:
          break;
      }
    }

    User-Galerie

    Hier ein paar Bilder von Leuten, die das Projekt nachgebaut und angepasst haben. Vielen Dank dafür :-)


    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


    15 Gedanken zu „Jukebox mit Arduino“

    1. Ich baue mir gerade eine Jukebox mit 10 Tastern und 100 Titeln. Auch 1000 Titel wären damit möglich.
      Mit den 10 Tastern werde ich die Zahlen 0..9 auswerten.
      Mit der Variablen „Status“ können dann fast beliebig viele Titel kodiert werden. Für 100 Titel wären das dann die Nummern 00..99.
      Dafür müssen 2 Taster nacheinander gedrückt werden.
      Umsetzung über eine Status Variable im „Loop“:
      Status = 0 // Keine Auswahl / bzw. Titel spielt gerade
      Status = 1 // 0..9 als 00..90
      Beim Test auf Status = 1 und einem weiteren Taster-Druck wird die 2. Zahl angegeben (0..9) und die erste (00..90) addiert. Das ergibt dann die Titelnummer, welche nun gespielt wird. Der Status wird dann wieder auf 0 gesetzt.

      1. Hast du die Jukebox für 100 Titel fertig? Funktioniert das gut? ich brauche genau sowas. Kannst du mir den Code teilen? Ich möchte das in ein Seeburg Wall-o-matic 100 einbauen.
        Viele Grüße, Marcus

    2. Habe nun meine „Jukebox“ gebaut. Ich habe sie mit einem Arduino Mega und 30 Tastern für die Musikauswahl realisiert. Vielen Dank für die sehr gute Anleitung. Die notwendigen Änderungen im Sketch (Anzahl der Pins, Pinbelegung) konnte ich durch den vorgegebenen Sketch ohne Probleme durchführen.
      Jetzt benötige allerdings Hilfe bei einem Programmierproblem.
      Um noch mehr Musikfiles (MP3s) auf Tastendruck abzuspielen habe ich 2 weitere Ordner auf der SD-Karte mit jeweils 30 Files angelegt (Ordner01, Ordner02, Ordner03). Dazu verwende ich anstatt „myDFPlayer.playMp3Folder(i+1);“ den Befehl „myDFPlayer.playLargeFolder(2,i+1);“. Das funktioniert auch mit jedem einzelnen Ordner.
      Ich möchte nun mit 3 weiteren Tastern (oder Schiebeschalter), bevor ich meine schon vorhandenen 30 Taster zur File-Auswahl verwende, zuerst einen der angelegten Ordner auf der SD-Karte auswählen.
      Im Loop frage ich die neu definierten Taster ab. Diese Tasten wählen dann jeweils für einen angelegten Ordner eine „Funktion“ (Unterprogramm) aus.
      Das Problem ist nun, dass die Tasterabfrage für die Ordner im Loop ständig wiederholt wird und die Fileauswahl (30 Taster) nicht stabil in einem ausgewählten Ordner stattfindet. Es werden aus allen 3 Ordner je nach Zeitpunkt des Tasterdrucks die Files abgespielt.
      Daraufhin habe ich mich tagelang dann im Internet mit allen möglichen Themen zur Tasterabfrage
      beschäftigt (Entprellen, Interrupts, Enum, state machine und …..). Da meine Programmierkenntnisse noch sehr gering sind, ist es mir nicht gelungen eine Lösung für dieses Problem zu finden und umzusetzen.
      Gelunden sind mir einige Beispiel-Sketches für LED-Steuerungen. Hier wurden die „Unterprogramme“ korrekt ausgeführt.
      Vielleicht bin ich, was den Aufbau des Sketches betrifft auch auf dem Holzweg oder diese Idee lässt sich vielleicht überhaupt nicht umsetzen. Habe aber eher die Vermutung, dass meine Programmierkenntnisse dafür nicht ausreichen. Würde mich freuen wenn Sie sich das Problem anschauen und einen konkreten
      Lösungsvorschlag in den Sketch einbauen könnten. Schon mal vielen Dank im Voraus.

      Hier der veränderte Sketch:
      #include „SoftwareSerial.h“
      #include „DFRobotDFPlayerMini.h“
      SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
      DFRobotDFPlayerMini myDFPlayer;
      int buttonPins[30] = {22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51}; // Pins, an denen die Taster angeschlossen sind
      void setup() {
      mySoftwareSerial.begin(9600); // Start der SoftwareSerial Kommunikation
      Serial.begin(115200); // Start der „normalen“ seriellen Kommunikation für den Serial Monitor
      if (!myDFPlayer.begin(mySoftwareSerial)) { // Verbindung der Software Serial Kommunikation mit dem DFPlayer
      Serial.println(F(„Unable to begin:“));
      Serial.println(F(„1.Please recheck the connection!“));
      Serial.println(F(„2.Please insert the SD card!“));
      while(true){ // Programmabbruch -> while(true) ist Endlosschleife
      delay(0); // Code für den Watchdog des ESP8266, nicht relevant für Arduino UNO
      pinMode(4, INPUT_PULLUP);
      pinMode(7, INPUT_PULLUP);
      pinMode(8, INPUT_PULLUP);

      }
      }

      myDFPlayer.volume(20); // Lautstärke auf 10 ( Werte von 0 – 30 ist möglich)
      for (int i=0; i<30; i++){ // wiederhole 16 Mal (für jeden Taster)
      pinMode(buttonPins[i], INPUT_PULLUP); // Taster werden mit internen Pullup-Widerständen verwendet
      }

      }
      void loop()
      {
      if (digitalRead(2) == LOW){
      Serial.println(2);
      {
      Ordner01();
      delay(200);
      }
      }
      if(digitalRead(4) == LOW){
      Serial.println(4);
      {
      Ordner02();
      delay(200);
      }
      }
      if(digitalRead(8) == LOW){
      Serial.println(8);
      {
      Ordner03();
      delay(200);

      }
      }
      }

      void Ordner01(){
      for (int i=0; i<30; i++){ // wiederhole 30 Mal (für jeden Taster)
      if (digitalRead(buttonPins[i]) == LOW){ // wenn ein Taster gedrückt wird
      Serial.println(i);
      myDFPlayer.playLargeFolder(1,i+1); // spiele das MP3 der Nummer des Tasters nach von der SD-Karte
      delay(200);
      }

      void Ordner02(){
      for (int i=0; i<30; i++){ // wiederhole 30 Mal (für jeden Taster)
      if (digitalRead(buttonPins[i]) == LOW){ // wenn ein Taster gedrückt wird
      Serial.println(i);
      myDFPlayer.playLargeFolder(2,i+1); // spiele das MP3 der Nummer des Tasters nach von der SD-Karte
      delay(200);
      }

      void Ordner03(){
      for (int i=0; i<30; i++){ // wiederhole 30 Mal (für jeden Taster)
      if (digitalRead(buttonPins[i]) == LOW){ // wenn ein Taster gedrückt wird
      Serial.println(i);
      myDFPlayer.playLargeFolder(3,i+1); // spiele das MP3 der Nummer des Tasters nach von der SD-Karte
      delay(200);
      }

      delay(20);

      /* Alles ab hier dient dem Debugging und kommt aus den Beispiel-Dateien der Library */
      if (myDFPlayer.available()) {
      printDetail(myDFPlayer.readType(), myDFPlayer.read()); // Print the detail message from DFPlayer to handle different errors and states.
      }

      void printDetail(uint8_t type, int value){

      switch (type) {
      case TimeOut:
      Serial.println(F("Time Out!"));
      break;
      case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
      case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));
      break;
      case DFPlayerCardRemoved:
      Serial.println(F("Card Removed!"));
      break;
      case DFPlayerCardOnline:
      Serial.println(F("Card Online!"));
      break;
      case DFPlayerUSBInserted:
      Serial.println("USB Inserted!");
      break;
      case DFPlayerUSBRemoved:
      Serial.println("USB Removed!");
      break;
      case DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));
      break;
      case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
      case Busy:
      Serial.println(F("Card not found"));
      break;
      case Sleeping:
      Serial.println(F("Sleeping"));
      break;
      case SerialWrongStack:
      Serial.println(F("Get Wrong Stack"));
      break;
      case CheckSumNotMatch:
      Serial.println(F("Check Sum Not Match"));
      break;
      case FileIndexOut:
      Serial.println(F("File Index Out of Bound"));
      break;
      case FileMismatch:
      Serial.println(F("Cannot Find File"));
      break;
      case Advertise:
      Serial.println(F("In Advertise"));
      break;
      default:
      break;
      }
      break;
      default:
      break; }

    3. Plane ebenfalls mit dem MP3-Player-Modul ein Projekt.
      Welche Stromversorgungen werden bei euren Projekten verbaut? (z.B. Jukebox für Oma)
      Kann ich einen 9V-Block über Vin (Arduino Mega2560) nutzen? Man könnte,
      dann das Gehäuse relativ klein halten.

      1. Hallo Herr Lenz,

        für meine Jukebox für die Oma sind zwei Netzteile einmal 9V (Arduino) und einmal 12V für den Verstärker verbaut. Siehe Schaltplan.

        Wenn man das Soundmodul (DFPlayer Mini) nur verwendet wird es wohl ein 9V Block tun, es muss nur die
        Spannung auf 5Volt mit einem Spannungswandler herunter geregelt werden.

        Mit einem Arduino Mega wird die 9V Blockbatterie alsbald leer sein. Der Mega braucht schon für sich alleine im Betrieb ca. 70 mA und das Soundmodul nochmal ca 20 mA im Ruhezustand beim Anschluss eines Lautsprechers steigt die Stromaufnahme ins unendliche je nach Lautstärke.

        mit freundlichen Grüßen
        R. Gerlinger

    4. Pingback: DFPlayer Mini-MP3-Player für Arduino – Arduino Tutorial

      1. Hallo Stefan,
        habe jetzt die Jukebox mit Arduino Mega aufgebaut mit 23 Eingängen, möchte aber bei betätigung das eine Led
        bei jedem Eingang mit an geht und wieder ausgeht bei nächster Betätigung. Über eine Hilfe würde ich mich freuen. Kann Dir meine Prgrammierung zusenden.

        MfG
        Rudolf

    5. Hallo Stefan,
      da meine Juke Box (Musikbox) gut angekommen ist, kam die Frage auf ob man mehr als 16 Titel abspielen kann.
      Ich dachte da an den Arduino Mega…

      MfG
      Rudolf Gerlinger

      1. Hallo Rudolf,
        ich lesen deinen Kommentar gerade und möchte darauf hinweisen, dass kein Mega benötigt wird, da der DFPlayer selbständig von der (sehr großen) SD-Karte spielt.
        Du musst nur die Tasten als Matrix, in Zeilen und Spalten anordnen. Dann benötigst du soviel Ports am Arduino, wie die Summe aus Zeilen und Spalten ist.
        Also, wenn 32 Titel gespielt werden sollen, werden 4 Zeilen a 8 Tasten verwendet und 12 Ports benötigt. Das sind weniger als in diesem Beispiel.

    6. Moin,

      ich habe das Problem, das der Arduino nicht reagiert wenn ich ein Taster drücke.
      Ich habe alles korrekt angeschlossen etc. es klappt aber leider nicht.
      Wenn ich den DF Player Test auf den Arduino flashe klappt alles mit dem 3 Sekundne Test Sound.
      Ich bin überfragt was ich machen muss, damit die Taster das einzelne Lied abspielen.

    7. Hallo, ich habe mit einem Kollegen die Jukebox nachgebaut. Ich bin kein Elektroniker und es ist mein erstes Projekt dieser Art. Ich bin begeistert! Vielen Dank dafür!
      Eine Frage habe ich trotzdem: Ist es möglich die Files in einen Zwischenspeicher zu packen, sodass sie je nach Anwahl gespielt werden. Quasi wie nach einer Playlist? LG Stefan Kempf

      1. Hi Stefan, das freut mich sehr! Zu deiner Frage:
        Also entweder per Code, indem du DFPlayerPlayFinished nutzt um den nächsten Titel zu starten. Das könntest du ja gleich hier einfügen:

        case DFPlayerPlayFinished:
        Serial.print(F(“Number:”));
        Serial.print(value);
        Serial.println(F(” Play Finished!”));
        // hier der Code um den nächsten Titel zu starten
        break;

        Oder du guckt dir mal diesen Thread an:
        https://www.reddit.com/r/arduino/comments/75wz8f/dfplayer_mini_question_autoplay_autorepeat/ Scheint mir auch ganz plausibel zu sein. Ist eine kleine Herausforderung, aber ich drück dir die Daumen.

        Wenn Ihr daraus eine Jukebox baut, die mehr als Breadboard ist, will ich aber Fotos sehen ;-)

    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.