MP3-Player YX5300

Über den Beitrag

In diesem Beitrag möchte ich ein auf dem YX5300 Chip basierendes MP3-Player Modul vorstellen. Folgende Themen behandele ich:

Serial MP3-Player YX5300

Eigenschaften / Technische Daten

Das MP3-Player YX5300 Modul  ist für 5-10 Euro z.B. bei Amazon zu haben. Die mitgelieferte Dokumentation ist – wie meist bei elektronischen Bauteilen – sehr dünn, aber im Netz gibt es ein Datenblatt dazu. Die Hauptmerkmale sind:

Stromversorgung3.2 – 5.2 V
Stromverbrauchmax. 200 mA
DateitypenWAV / MP3
SD-KarteMicro SD (<= 2 GB)

Micro SDHC (<=32 GB)
FormatFAT16 / FAT 32
KommunikationSeriell über RX/TX
Zulässige Spannung für TX/RX3.3 V / 5 V
Baudrate9600
Lautsprecher/Kopfhörer Anschluss3.5mm Klinke

Ich habe das Modul erfolgreich mit einer 2 GB SD-Karte und einer 16 GB SDHC Karte getestet. Solltet ihr, so wie ich zunächst auch, ein Problem mit eurer SD-Karte haben, dann hilft Euch vielleicht das Kapitel darüber weiter unten.

Das Modul erwartet auf der SD-Karte die Verzeichnisnamen im Format „01“, „02“, „03“, usw.. Die Dateien in den Verzeichnissen müssen das Format „001xxx.mp3“, „002xxx.mp3“, … haben. „xxx“ ist dabei frei wählbar. 

Den Klinkenanschluss kann man als Vor- oder Nachteil sehen. Zusätzliche Pins für den Anschluss an Selbstbauverstärker oder -boxen wären sinnvoll gewesen. Aber zunächst ist es natürlich sehr bequem direkt einen Kopfhörer oder (Aktiv-)Lautsprecher anschließen zu können. 

Das Modul wird seriell angesprochen und hat einen Anweisungsumfang implementiert, wie man ihn von einem MP3-Player erwarten würde. Ich will die Anweisungen hier nicht einzeln durchgehen. Entweder ihr schaut im Datenblatt nach oder in dem Beispielsketch der Bibliothek die ich gleich vorstellen möchte. Das Einzige was ich ein wenig vermisse ist eine Funktion zum Wechsel vom Einzelliedmodus zum Playlistmodus (bzw. zurück), der das momentan gespielte Stück nicht unterbricht.

SerialMP3Player Bibliothek

Eigentlich ist es nicht besonders schwer, das Modul ohne Bibliothek anzusteuern, aber es ist doch eine große Fleißarbeit die ganzen Befehle aus dem Datenblatt abzuschreiben. Mit der SerialMP3Player Bibliothek wird einem diese Arbeit abgenommen, so dass man sofort loslegen kann. Trotzdem empfehle ich grundsätzlich sich Datenblätter auch mal anzuschauen, z.B. um in der Lage zu sein Bibliotheken ggf. „aufzubohren“.

Mit Hilfe des Beispielsketches BasicCommands lässt sich das Modul ausgiebig testen. Der Sketch zaubert die Liste der verfügbaren Befehle auf den seriellen Monitor, die man dann entsprechend aufrufen kann.  Schön finde ich, dass auf dem seriellen Monitor auch die Rohdaten angezeigt werden die gesendet bzw. empfangen werden. Wer möchte kann das ändern indem er (oder sie!) in Zeile 42  die „1“ durch eine „0“ ersetzt und die Zeilen 67-69 auskommentiert.

Der Sketch ist gut verständlich und braucht glaube ich keine großen Erklärungen. In der Loop Funktion wird geprüft ob Eingaben am seriellen Monitor gemacht wurden. Die Eingaben werden durch die „decode_c“ Funktion aufbereitet und dann der „menu“ Funktion übergeben. Diese ruft dann die in der Bibliothek definierten Funktionen auf.  

/******************************************************************************
  Basic Commands examples for the SerialMP3Player YX5300 chip.

  Copy the files of "SDcard_example" to an empty SD card
  Connect the Serial MP3 Player to the Arduino board
    GND → GND
    VCC → 5V
    TX → pin 11
    RX → pin 10

  After compile and upload the code,
  you can test some basic commands by sending the letters
  ? - Display Menu options.
  P01 - Play 01 file
  F01 - Play 01 folder
  S01 - Play 01 file in loop
  p - play
  a - pause
  s - stop
  > - Next
  < - Previous
  ...

  Some commands like 'P' must be followed by two digits.

  This example code is in the public domain.

  https://github.com/salvadorrueda/ArduinoSerialMP3Player

  by Salvador Rueda
 *******************************************************************************/

#include "SerialMP3Player.h"

#define TX 11
#define RX 10

SerialMP3Player mp3(RX,TX);


void setup() {
  mp3.showDebug(1);       // print what we are sending to the mp3 board.

  Serial.begin(9600);     // start serial interface
  mp3.begin(9600);        // start mp3-communication
  delay(500);             // wait for init

  mp3.sendCommand(CMD_SEL_DEV, 0, 2);   //select sd-card
  delay(500);             // wait for init

  menu('?',0); // print the menu options.
}

 char c;  // char from Serial
 char cmd=' ';
 char cmd1=' ';


// the loop function runs over and over again forever
void loop() {

  if (Serial.available()){
    c = Serial.read();
    decode_c(); // Decode c.
  }
  // Check for the answer.
  if (mp3.available()){
    Serial.println(mp3.decodeMP3Answer()); // print decoded answers from mp3
  }
}

void menu(char op, int nval){
  // Menu
  switch (op){
    case '?':
    case 'h':
        Serial.println("SerialMP3Player Basic Commands:");
        Serial.println(" ? - Display Menu options. ");
        Serial.println(" P01 - Play 01 file");
        Serial.println(" F01 - Play 01 folder");
        Serial.println(" S01 - Play 01 file in loop");
        Serial.println(" V01 - Play 01 file, volume 30");
        Serial.println(" p - Play");
        Serial.println(" a - pause");
        Serial.println(" s - stop ");
        Serial.println(" > - Next");
        Serial.println(" < - Previous");
        Serial.println(" + - Volume UP");
        Serial.println(" - - Volume DOWN");
        Serial.println(" v15 - Set Volume to 15");
        Serial.println(" c - Query current file");
        Serial.println(" q - Query status");
        Serial.println(" x - Query folder count");
        Serial.println(" t - Query total file count");
        Serial.println(" r - Reset");
        Serial.println(" e - Sleep");
        Serial.println(" w - Wake up");
        break;

    case 'P':
        Serial.println("Play");
        mp3.play(nval);
        break;

    case 'F':
        Serial.println("Play Folder");
        mp3.playF(nval);
        break;

    case 'S':
        Serial.println("Play loop");
        mp3.playSL(nval);
        break;

    case 'V':
        Serial.println("Play file at 30 volume");
        mp3.play(nval,30);
        break;


    case 'p':
        Serial.println("Play");
        mp3.play();
        break;

    case 'a':
        Serial.println("Pause");
        mp3.pause();
        break;

    case 's':
        Serial.println("Stop");
        mp3.stop();
        break;

    case '>':
        Serial.println("Next");
        mp3.playNext();
        break;

    case '<':
        Serial.println("Previous");
        mp3.playPrevious();
        break;

    case '+':
        Serial.println("Volume UP");
        mp3.volUp();
        break;

    case '-':
        Serial.println("Volume Down");
        mp3.volDown();
        break;

    case 'v':
        Serial.println("Set to Volume");
          mp3.setVol(nval);
          mp3.qVol();
        break;

    case 'c':
        Serial.println("Query current file");
        mp3.qPlaying();
        break;

    case 'q':
        Serial.println("Query status");
        mp3.qStatus();
        break;

    case 'x':
        Serial.println("Query folder count");
        mp3.qTFolders();
        break;

    case 't':
        Serial.println("Query total file count");
        mp3.qTTracks();
        break;

    case 'r':
        Serial.println("Reset");
        mp3.reset();
        break;

    case 'e':
        Serial.println("Sleep");
        mp3.sleep();
        break;

    case 'w':
        Serial.println("Wake up");
        mp3.wakeup();
        break;
  }
}

void decode_c(){
  // Decode c looking for a specific command or a digit

  // if c is a 'v', 'P', 'F', 'S' or 'V' wait for the number XX
  if (c=='v' || c=='P' || c=='F' || c=='S' || c=='V'){
    cmd=c;
  }else{
    // maybe c is part of XX number
    if(c>='0' && c<='9'){
      // if c is a digit
      if(cmd1==' '){
        // if cmd1 is empty then c is the first digit
        cmd1 = c;
      }else{
        // if cmd1 is not empty c is the second digit
        menu(cmd, ((cmd1-'0')*10)+(c-'0'));
        cmd = ' ';
        cmd1 = ' ';
      }
    }else{
      // c is not a digit nor 'v', 'P', 'F' or 'S' so just call menu(c, nval);
      menu(c, 0);
    }
  }
}

 

Anschluss an Arduino und Co

Einfacher geht es eigentlich nicht: GND and GND, VCC an 5V oder 3.3V, RX an TX und TX an RX. RX und TX sind im Beispielsketch über ein SoftwareSerial als PIN 10 und PIN 11 eingestellt.

MP3-Player YX5300 am Arduino
MP3-Player YX5300 am Arduino

Smartphone Steuerung für den MP3-Player YX5300

Alternative Steuerung

Den MP3-Player YX5300 über den seriellen Monitor steuern zu können ist schon mal ein erstes Erfolgserlebnis, aber auf Dauer möchte man wohl eher unabhängig vom PC arbeiten. Im Wesentlichen fallen mir drei Alternativen ein:

  • Für jede Funktion einen Taster installieren, ggf. in Verbindung mit einer kleinen Folientastatur (Suchbegriff „Matrix Folientastatur“ bei Amazon).
  • Ein Touchdisplay einsetzen (Suchbegriff „Touchdisplay Arduino“ bei Amazon, gibt’s für < 20€)
  • Smartphone Steuerung über Bluetooth

Da ich Smartphone Variante besonders spannend finde, werde ich darauf näher eingehen. 

Die Funktionalität der Smartphone App

Ich habe eine kleine App („Ardu YX5300 MP3 Player“) entwickelt, die die wichtigsten Funktionen für den Player implementiert hat. Ihr könnt die App aber auch problemlos erweitern und weitere Funktionen hinzufügen. Als besonderes Feature habe ich eine Sprachsteuerung („Talk2Me“ Button) hinzugefügt. 

Die Oberfläche der Smartphone App

Die „Continuous“ Check Box wechselt vom Einzelliedmodus in den Folderplaymodus bzw. zurück. Leider ist das damit verbunden, dass das aktuelle Lied unterbrochen wird. 

Was die App im Hintergrund genau macht und wie man so etwas ohne spezielle Kenntnisse in der App Programmierung entwickeln kann, erkläre ich weiter unten. 

Setup der Arduinoseite

Zunächst aber zum Aufbau der Arduinoseite. Dem Arduino verleihen wir mit einem HC-05 oder HC-06 Modul Bluetoothfähigkeiten. Wie man mit diesen Modulen umgeht habe ich hier beschrieben. Das Bluetooth Modul kommuniziert über eine SoftwareSerial Verbindung mit dem Arduino. In meinem Sketch dazu (weiter unten) habe ich Pin 5 und 6 als RX bzw. TX definiert. Als Lautsprecher habe ich eine kleine Aktivbox eingesetzt. Auf dem Breadboard sieht das dann so aus:

Um mich unabhängig vom PC zu machen, habe ich den Arduino Uno durch einen Pro Mini ersetzt, das Ganze in ein Gehäuse gepackt, auf Batteriebetrieb umgestellt und noch eine Kontrollleuchte für die Stromversorgung spendiert. Der Batterieanschluss erfolgt extern und wird über eine Buchse ins Gehäuse geführt. Wie man einen Pro Mini programmiert habe ich hier beschrieben. Der Schaltplan sieht dann so aus: 

Schaltung für den smartphonegesteuerten MP3-Player
Und so sieht das vollständige Projekt aus

Vorbereitung – Anpassung des Sketches

Für den Sketch nehme ich den BasicCommand Sketch als Grundlage und nutze dessen „Infrastruktur“. Ich habe ihn in Ardu_YX5300_MP3_player.ino umbenannt. Ihr findet den Sketch weiter unten.

Die Verbindung mit dem Bluetoothmodul wird in Zeile 40 vereinbart:

SoftwareSerial BT_Module(5,6);

In der loop Funktion wird in den Zeilen 74-76 überprüft, ob Daten zum Abruf vorhanden sind:

if(BT_Module.available()){ decode_BT(); }.

Über die neue Funktion „decode_BT“ in den Zeilen 206 – 216 werden die erhaltenen Anweisungen ausgewertet, so dass die menu Funktion sie versteht. Als erstes Zeichen wird „BT_START_CMD_CHAR“ erwartet, dass am Anfang des Sketches als „*“ definiert wurde. 

void decode_BT(){
  char cmdType = ' ';
  int value = 0;
  char getChar = ' ';  //read serial
  if(BT_Module.find(BT_START_CMD_CHAR)){
    while(BT_Module.available()<1);
    cmdType = BT_Module.read(); // read the command
    value = BT_Module.parseInt();
  }
  menu(cmdType,value); 
}      

Und so sieht dann der vollständige Sketch aus:

/******************************************************************************
  Salavdor Rueda's Basic Commands examples for the SerialMP3Player YX5300 chip.

  Modified by Wolfgang Ewald in order to communicate with a smartphone app. 

    GND → GND
    VCC → 5V
    YX 5300 TX → pin 10
    YX 5300 RX → pin 11
    BT Modul TX → pin 5
    BT Modul RX → pin 6

  After compile and upload the code,
  you can test some basic commands by sending the letters
  ? - Display Menu options.
  P01 - Play 01 file
  F01 - Play 01 folder
  S01 - Play 01 file in loop
  p - play
  a - pause
  s - stop
  > - Next
  < - Previous
  ...

  Original:
  "This example code is in the public domain.
  https://github.com/salvadorrueda/ArduinoSerialMP3Player
  by Salvador Rueda"
  
 *******************************************************************************/

#include "SerialMP3Player.h"
#define TX 11
#define RX 10
#define BT_START_CMD_CHAR '*'
int statusLEDPin = 4;

SerialMP3Player mp3(RX,TX);
SoftwareSerial BT_Module(5,6);

void setup() {
  mp3.showDebug(0);       // print what we are sending to the mp3 board. 1= active
  Serial.begin(9600);     // start serial interface
  mp3.begin(9600);        // start mp3-communication
  BT_Module.begin(9600);   // start serial connection to BT Modul
  delay(500);             // wait for init
  pinMode(statusLEDPin, OUTPUT);
  digitalWrite(statusLEDPin, HIGH);

  mp3.sendCommand(CMD_SEL_DEV, 0, 2);   //select sd-card
  mp3.setVol(15); 
  mp3.playF(1);  // Folder 1, cycle play
  delay(500);    // wait for init

  menu('?',0); // print the menu options.
}

 char c;  // char from Serial
 char cmd=' ';
 char cmd1=' ';


// the loop function runs over and over again forever
void loop() {
  if (Serial.available()){
    c = Serial.read();
    decode_c(); // Decode c.
  }
  // Check for the answer.
//  if (mp3.available()){
//    Serial.println(mp3.decodeMP3Answer()); // print decoded answers from mp3
//  }
  if(BT_Module.available()){
    decode_BT();
  }
}

void menu(char op, int nval){
  // Menu
  switch (op){
    case '?':
    case 'h':
        Serial.println("SerialMP3Player Basic Commands:");
        Serial.println(" ? - Display Menu options. ");
        Serial.println(" P01 - Play 01 file");
        Serial.println(" F01 - Play 01 folder");
        Serial.println(" S01 - Play 01 file in loop");
        Serial.println(" V01 - Play 01 file, volume 30");
        Serial.println(" p - Play");
        Serial.println(" a - pause");
        Serial.println(" s - stop ");
        Serial.println(" > - Next");
        Serial.println(" < - Previous");
        Serial.println(" + - Volume UP");
        Serial.println(" - - Volume DOWN");
        Serial.println(" v15 - Set Volume to 15");
        Serial.println(" c - Query current file");
        Serial.println(" q - Query status");
        Serial.println(" x - Query folder count");
        Serial.println(" t - Query total file count");
        Serial.println(" r - Reset");
        Serial.println(" e - Sleep");
        Serial.println(" w - Wake up");
        break;

    case 'P':
        Serial.println("Play");
        mp3.play(nval);
        break;

    case 'F':
        Serial.println("Play Folder");
        mp3.playF(nval);
        break;

    case 'S':
        Serial.println("Play loop");
        mp3.playSL(nval);
        break;

    case 'V':
        Serial.println("Play file at 30 volume");
        mp3.play(nval,30);
        break;


    case 'p':
        Serial.println("Play");
        mp3.play();
        break;

    case 'a':
        Serial.println("Pause");
        mp3.pause();
        break;

    case 's':
        Serial.println("Stop");
        mp3.stop();
        break;

    case '>':
        Serial.println("Next");
        mp3.playNext();
        break;

    case '<':
        Serial.println("Previous");
        mp3.playPrevious();
        break;

    case '+':
        Serial.println("Volume UP");
        mp3.volUp();
        break;

    case '-':
        Serial.println("Volume Down");
        mp3.volDown();
        break;

    case 'v':
        Serial.println("Set to Volume");
          mp3.setVol(nval);
          //mp3.qVol();
        break;

    case 'c':
        Serial.println("Query current file");
        mp3.qPlaying();
        break;

    case 'q':
        Serial.println("Query status");
        mp3.qStatus();
        break;

    case 'x':
        Serial.println("Query folder count");
        mp3.qTFolders();
        break;

    case 't':
        Serial.println("Query total file count");
        mp3.qTTracks();
        break;

    case 'r':
        Serial.println("Reset");
        mp3.reset();
        break;

    case 'e':
        Serial.println("Sleep");
        mp3.sleep();
        break;

    case 'w':
        Serial.println("Wake up");
        mp3.wakeup();
        break;
  }
}

void decode_BT(){
  char cmdType = ' ';
  int value = 0;
  char getChar = ' ';  //read serial
  if(BT_Module.find(BT_START_CMD_CHAR)){
    while(BT_Module.available()<1);
    cmdType = BT_Module.read(); // read the command
    value = BT_Module.parseInt();
  }
    menu(cmdType,value); 
}      

void decode_c(){
  // Decode c looking for a specific command or a digit

  // if c is a 'v', 'P', 'F', 'S' or 'V' wait for the number XX
  if (c=='v' || c=='P' || c=='F' || c=='S' || c=='V'){
    cmd=c;
  }else{
    // maybe c is part of XX number
    if(c>='0' && c<='9'){
      // if c is a digit
      if(cmd1==' '){
        // if cmd1 is empty then c is the first digit
        cmd1 = c;
      }else{
        // if cmd1 is not empty c is the second digit
        menu(cmd, ((cmd1-'0')*10)+(c-'0'));
        cmd = ' ';
        cmd1 = ' ';
      }
    }else{
      // c is not a digit nor 'v', 'P', 'F' or 'S' so just call menu(c, nval);
      menu(c, 0);
    }
  }
}

 

Eine Anpassung muss wohl noch in der Bibliothek in SerialMP3Player.cpp vorgenommen werden, aber nichts Kompliziertes. Die Bibliothek sieht vor, dass zwischen zwei Anweisungen jeweils eine Sekunde gewartet wird. Das gibt Probleme mit dem Volume Regler in der App, denn jede kleine Verschiebung löst sofort eine entsprechende Anweisung aus. D. h. eine Verschiebung des Reglers von z. B. Lautstärkestufe 10 auf 20 würde 10 Sekunden dauern. Alles was ihr machen müsst, ist in SerialMP3Player.cpp die Zeile 185 (der delay Befehl) auskommentieren und das war es schon.  

Bevor es an die Smartphone Anbindung geht, kann man das Ganze schon mal testen, indem man die Anweisungen vom Smartphone über eine Terminal App wie z.B. Bluetooth Terminal sendet. Die App gibt es hier bei Google Play. Ein „*F*1“ sollte zum Beispiel alle Lieder im Verzeichnis 01 abspielen. 

Entwicklung der Smartphone App

Wer meinen letzten Beitrag Arduino mit dem Smartphone steuern gelesen hat, der kann die folgenden Ausführungen grob überfliegen. 

Smartphone Apps zu programmieren ist eigentlich nichts, was man mal so eben nebenbei erlernen kann. Wer richtig tief in dieses Thema einsteigen möchte, sollte die Programmiersprache Java erlernen und sich mit Entwicklungsumgebungen wie Eclipse oder Android Studio beschäftigen. Die gute Nachricht ist, dass es eine einfache, für unsere Zwecke völlig ausreichende Alternative gibt und die heißt MIT App Inventor. Wenn Ihr diesem Link folgt, bekommt Ihr viele Informationen, wer hinter diesem Projekt steht, wie es funktioniert, welche Tutorials es gibt (als Einstieg sehr empfehlenswert) und vieles mehr. Eine Schritt-für-Schritt Anleitung würde den Rahmen dieses Beitrags sprengen, ich werde aber versuchen Euch die wesentlichen Punkte zu vermitteln. 

Wie funktioniert MIT App Inventor?

Zunächst einmal handelt es sich bei MIT App Inventor um eine Online Lösung, d.h. es ist keine Installation eines Programmes erforderlich. Man schreibt bei der Appentwicklung keine einzige Programmzeile, sondern konstruiert Programmblöcke visuell aus vorgefertigten Einzelteilen. Wer schon mal mit Scratch gearbeitet hat, der wird sich hier schnell reinfinden.

Besonders cool ist, dass man die Entstehung seiner Apps direkt in Echtzeit auf dem Smartphone verfolgen kann. Das betrifft sowohl das Design wie auch die Funktionalität. Es ist nicht notwendig zwischendurch Code zu kompilieren und sich apk Dateien auf das Smartphone zu beamen. Das macht man erst ganz am Ende, wenn man mit seinem Ergebnis zufrieden ist und die App unabhängig von der Entwicklungsumgebung laufen soll.

Um das Smartphone mit MIT App Inventor zu verbinden, muss man zunächst die App MIT AI2 Companion installieren. MIT App Inventor stellt dann wahlweise einen Zahlen- oder QR-Code für die Verbindung zur Verfügung. Sehr bequem! Bei mir wurde allerdings mit Edge keine Verbindung aufgebaut, mit Chrome hingegen klappte es wunderbar.  

Mit diesem Link erreicht ihr die Programmieroberfläche, zu der man sich mit seinem Google Konto anmeldet. 

Der Designer Bildschirm

Wie schon erwähnt kann ich wegen des Umfanges hier keine Schritt-für-Schritt Anleitung bieten, sondern nur das Konzept erklären. Die App Entwicklung erfolgt in zwei grundlegenden Schritten, nämlich zunächst der Designentwicklung und anschließend der Definition der Funktionen dahinter. Dazu gibt es zwei Bildschirme zwischen denen man wechseln kann und zwar „Designer“ und „Blocks“. Der Designer Bildschirm für die Ardu_YX5300_MP3_Player App sieht so aus: 

Der Designer Bilschirm – Auswahl von Komponenten und Anordnung

Auf der linken Seite hat man die Palette mit den unterschiedlichen Elementen, die sich einfügen lassen. Im Untermenü „User Interface“ sind das Buttons, Checkboxen, Slider, usw. Unter „Layout“ findet man Elemente wie z.B. Horizontal und Vertical Arrangements, die der Abstandshaltung und Anordnung dienen. Die Bluetoothfunktion findet sich erwartungsgemäß unter Connectivity. Schaut einfach mal durch. 

Das Fenster „Components“ gibt die Struktur der Komponenten wieder. Hier kann man Komponenten auch umbenennen, was absolut ratsam ist, um nicht den Überblick zu verlieren. „Playbutton“ ist beispielsweise eine hilfreichere Bezeichnung als das voreinstellte „Button1“. 

Im Fenster „Properties“ kann man die Eigenschaften der Komponenten festlegen, z.B. Form, Farbe oder im Falle der Slider welche Werte abgebildet werden. Für den Volume Slider habe ich zum Beispiel einen Bereich von 0 bis 30 angegeben, da das die zulässigen Werte für den YX5300 sind.  

Der Blocks Bildschirm

Die im Designer Bildschirm zusammengestellten Komponenten können zunächst nichts. Was sie unter welchen Bedingungen auslösen oder wie sie sich verändern sollen, wird im Blocks Bildschirm festgelegt: 

Der Blocks Bildschirm – Funktion der Komponenten

Klickt man im Fenster „Blocks“ auf eine der Komponenten, bekommt man eine Auswahl verschiedener Blöcke zur Auswahl. Den ausgewählten Block zieht man in das Viewer Fenster Fenster, wo er frei verschiebbar ist. Da zum Beispiel ein Slider nur bestimmte Dinge kann, werden auch nur die entsprechenden Blöcke vorgeschlagen. Dadurch kann man recht intuitiv und schnell arbeiten. Zusätzlich gibt es unter „Built-In“ allgemeine Blöcke z.B. für Text, if-then-else Konstruktionen und vieles mehr. 

Eine weitere Hilfe ist, dass die Blöcke wie Puzzleteile geformt sind. Dadurch passen nur bestimmte Komponenten zusammen und alles muss abgeschlossen sein. Dadurch werden Syntaxfehler vermieden, auf die Logikfehler hingegen muss man natürlich selbst achtgeben. 

Die App sichern und installieren

Zum Schluss kann man unter dem Menüpunkt „Build“ eine apk Datei generieren, die bequem über einen QR-Code auf das Smartphone transferiert werden kann.  

Das Projekt wird online gespeichert. Man kann es aber auch als „.aia“-Datei exportieren, auf dem PC speichern, mit anderen teilen und dann wieder importieren. Die „.aia“-Datei für die hier vorgestellte Ardu_YX5300_MP3_Player App könnt ihr hier herunterladen (folgt dem Link und klickt rechts auf das Download-Symbol) und nach Lust und Laune anpassen. Alternativ findet Ihr das Projekt in der Galerie von MIT App Inventor, wenn ihr diesem Link folgt.

Probleme mit der SD-Karte?

Die SD-Karte funktioniert nicht? Das Problem hatte ich und es hat mich einige Zeit gekostet den Grund herauszufinden. Wenn der Player nicht spielen will, obwohl das Audioformat korrekt ist, die Verzeichnisstruktur wie vorgeschrieben angelegt wurde, die Verkabelung stimmt, usw., dann kann es an der Partitionierung der Karte liegen. Eine SD-Karte kann ab Werk oder wenn sie vorher für andere Zwecke benutzt wurde, eine kleine Bootpartition besitzen.  Entsprechend findet man im Datei-Explorer zwei Laufwerke: 

SD-Karte mit Bootsektor

Rechtsklick und Formatieren nützt nichts, da die Partitionen erhalten bleiben. Als das Problem bei mir auftrat, habe ich es mit dem kleinen Tool SD Card Formatter, dass es z.B. hier gibt, gelöst. Nach der Installation wählt man die kleine Bootpartition (sie muss nicht unbedingt „boot“ heißen) und aktiviert die Formatierungsoption „Overwrite Format“. Der Vorgang dauert mehrere Minuten. Danach hat man nur noch eine Partition und alles klappt wunderbar.

SD Card Formatter - Programmansicht
SD Card Formatter

Alternative MP3-Module

Alternativen zum MP3-Player YX5300

Es gibt eine Reihe von Alternativen zum MP3-Player YX5300. Auf diese stößt man, wenn man z.B. bei Amazon nach „MP3 Modul Arduino“ sucht. Ausprobiert habe ich das WTV020M01 Modul (oben rechts auf dem Foto) und den noname Player links auf dem Foto. 

Vom WTV020M01 würde ich sehr abraten, da das gute Stück sehr pingelig ist, was das Dateiformat und die Details der Audioaufnahme angeht. So muss z.B. der Pegel und das Rauschen bestimmten Vorgaben entsprechen. Falls ihr euch das trotzdem antun wollt, gibt es eine sehr kompakte und funktionierende Anleitung hier.  

Über den DFPlayer Mini habe ich hier etwas geschrieben. Von der Ansteuerung her ähnelt er stark dem YX5300. Wesentliche Vorteile sind die geringe Größe und dass man ihn sehr leicht mit Tastern bedienen kann. Für den MP3-Player YX5300 spricht wiederum die Klinkenbuchse.

Das noname Teil funktioniert einwandfrei, aber lässt sich anscheinend nur mechanisch bedienen. Zumindest habe ich keine Möglichkeit gefunden, es über eine Schnittstelle mittels Software anzusprechen. Da es aber sofort losspielt, wenn es mit Strom versorgt wird, könnte man eine arduinogesteuerte An-/Ausschaltung dranbasteln. 

Nicht ausprobiert (zumindest bisher) habe ich Module, die auf dem VS1053 Chip basieren. Die gibt es in verschiedenen Bauformen, z.B. als Shield, mit oder ohne SD-Kartenslot, mit oder ohne Mikrofon, usw. Das kommt vielleicht auch noch auf die To-do-Liste. 

Wer gute oder schlechte Erfahrungen mit diesen oder anderen alternativen Modulen gemacht hat, ist herzlich eingeladen, diese als Kommentar zu teilen.  

34 thoughts on “MP3-Player YX5300

  1. Hallo Wolfgang,
    Vielen dank für dieses tolle Projekt.
    Ich habe ein Problem ich benutze einen ESP32 und würde gerne über denn YX5300 einen Sound abspielen.
    Der Sound soll über einen Bewegungsmelder gesteuert werden.
    Bei der Testdatei mit den BasicCommands wollte ich das ganze erst mal ausprobieren allerdings bekomme ich wenn ich versuche die Datei abzuspielen immer eine Fehlermeldung über den Serieller Monitor.
    Es ist diese Fehlermeldung:
    Guru Meditation Error: Core 1 panic’ed (InstrFetchProhibited). Exception was unhandled.
    Core 1 register dump:
    PC : 0xffffffff PS : 0x00060031 A0 : 0x400819f4 A1 : 0x3ffbe7a0
    A2 : 0x00000003 A3 : 0x3ffc00e8 A4 : 0x00000000 A5 : 0x00000008
    A6 : 0x3ffb8f20 A7 : 0x00000250 A8 : 0x80081204 A9 : 0x3ffb1de4
    A10 : 0xffffffff A11 : 0x3ffb1dc0 A12 : 0x8000bee0 A13 : 0x3ffb1dc0
    A14 : 0x3ffb80c0 A15 : 0x3ffb8f20 SAR : 0x00000015 EXCCAUSE: 0x00000014
    EXCVADDR: 0xfffffffc LBEG : 0x4000c349 LEND : 0x4000c36b LCOUNT : 0xffffffff
    Core 1 was running in ISR context:
    EPC1 : 0xffffffff EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x40082aab

    Backtrace: 0x7fffffff:0x3ffbe7a0 0x400819f1:0x3ffbe7c0 0x4000bfed:0x3ffb1d10 0x40088e51:0x3ffb1d20 0x4008aea3:0x3ffb1d40 0x4008b5ba:0x3ffb1d60 0x40084b92:0x3ffb1d80 0x40084bf2:0x3f

    Vielleicht können Sie ja etwas damit anfangen.
    Mit freundlichem Gruß

    Lars

    1. Hi Lars,

      ein „Guru Meditation Error“ mit einem „panischen Core 1“ klingt eigentlich mehr wie ein schlechter Scherz als eine Fehlermeldung, nicht wahr? Aber anscheinend gibt es das tatsächlich und es ist wohl ein recht unspezifischer Fehler, den man schwer einer konkreten Ursache zuordnen kann. Ich musste selber erst einmal ein wenig recherchieren, um mir ein Bild zu machen. Ich glaube, dass ich da aus der Ferne nicht so viel machen kann. Wenn ich einen Fehler habe, den ich mir nicht erklären kann, dann versuche ich systematisch Dinge herauszunehmen, bis es wieder funktioniert. Manchmal sind es aber auch völlig progane Dinge wie ein defektes Steckbrückenkabel, instabile Stromversorgung o.ä..Da hilft dann manchmal ein systematischer Austausch aller Komponenten.
      Aber du merkst wahrscheinlich schon: ich habe keine Ahnung wo der Fehler liegt!
      VG, Wolfgang

      1. Vielen dank Wolfgang,
        Ich probiere es mal aus, die Komponenten auszutauschen.
        Ich versuche es einfach mal weiter vll. finde ich ja den Fehler.
        Gruß Lars

        1. Hallo Lars,
          das hatte ich auch bei meinen ersten ESP32-Versuchen. Soweit ich mich erinnere, rannte die Hauptschleife ungebremst und fraß die Prozessorleistung weg. Einige Sleeps von wenigen ms haben das gelöst.

          Viel Glück, Micha

  2. Danke für Deine schnelle Antwort!
    Ja, ich würde sagen, das Knacken kommt in einer regelmäßigen Frequenz. Ungefähr alle 5 Sekunden. Es kommt aber nur wenn an dieser Stelle tatsächlich ein Sound abgespielt wird. Ist es zu dem Zeitpunkt/ an der Stelle der Audiodatei still, kommt das Knacken nicht. Könntest Du das mit der Stabilisierung der Stromversorgung durch einen Kondensator bitte nochmal genauer erläutern oder einen Link posten, wo das ersichtlich wird?

    P.S.: Ich habe gerade ein anderes YX5300 mp3- Player- Modul zur Überprüfung ins Setup eingebaut, am Knacken hat das nichts geändert. Ein Defekt des Bauteils kann also ausgeschlossen werden.

    1. Sry, jetzt habe ich aus Versehen Unordnung hier reingebracht, weil ich nicht direkt unter Deinem Post geantwortet habe, ich hoffe Du kannst das korrigieren:/

      1. Kein Problem, die Kommentare sind ja nah beieinander.
        Ich dachte an einen 10µF Kondensator, den du zwischen GND und VCC des YX5300 setzt. Ein Beinchen an GND das andere an VCC. Ich bin allerdings nicht allzu optimistisch, dass das etwas bringt. Dann könntest du auch mal versuchen andere Pins für die RX/TX Verbindung, also SoftwareSerial zu nehmen. Ist auch nur so ein Gedanke. Ich habe gerade noch einmal mein oben beschriebenes Projekt aus dem Schrank geholt und ich höre kein Knacken – vielleicht habe ich einfach zu viel laute Musik in meiner Jugend gehört… 😉
        Wenn es bei dir alle fünf Sekunden knackt, hängt das vielleicht mit irgendetwas anderem zusammen, was in dieser Frequenz angesprochen wird oder etwas tut. Kannst du da etwas identifizieren?
        Du kannst mir auch mal deinen Sketch schicken (Wolfgang.Ewald@wolles-elektronikkiste.de), vielleicht fällt mir dann noch etwas ein.

        1. Lieber Wolfgang,
          Ich habe das Problem identifiziert. Im void loop()- Teil stand der Befehl mp3.play(), der dadurch natürlich immer wieder neu ausgeführt wurde. Das hat nicht dazu geführt, dass die mp3- Datei immer wieder von vorne abgespielt wurde, aber definitiv das Knacken verursacht. Ein anderer Befehl, den ich stattdessen verwenden konnte „mp3.playSL(1);“, verursacht kein Knacken.

          Danke für Deine tolle Hilfe! 🙂

  3. Lieber Wolfgang Ewald,

    Ich habe ein ähnliches Projekt realisiert. Ein aktiver Lautsprecher ist auch bei mir an den YX5300 Player per Klinke angeschlossen. Leider taucht beim Abspielen meiner .mp3- Datei ein unregelmäßiges, leises aber doch störendes Knacken auf. Es liegt nicht an meinen Lautsprechern, wenn ich sie an den PC anschließe und die selbe .mp3 Datei abspiele ist das Knacken nicht vorhanden. Ist das Knacken bei Dir auch da? Hast Du einen Tipp für mich wie man das Knacken beseitigen könnte? Oder ein anderes mp3- Player- Modul, das eine bessere Soundqualität liefert (falls das Knacken normal sein sollte).

    Hier ist ein Link zu meinem Projekt für weitere Informationen: https://forum.arduino.cc/t/soundinstallation-mit-mp3-player-yx5300-reset-per-taster/942710

    Mfg Leonardo

    1. Hallo Leonardo, es ist längere Zeit her, dass ich mit dem YX5300 gearbeitet habe, aber ich denke ein Knacken wäre mir aufgefallen und in Erinnerung geblieben. Vielleicht ist es irgendetwas in der Schaltung / Stromversorgung? Vielleicht hilft die Stabilisierung der Stromversorgung mit einem Kondensator? Kommt das Knacken in einer regelmäßigen Frequenz?
      Wenn du ein anderes Modul probieren willst, dann kann ich den DFPlayer Mini empfehlen:
      https://wolles-elektronikkiste.de/dfplayer-mini-ansteuerung-mit-dem-arduino
      Eine Garantie, dass das Knacken weggeht, kann ich allerdings nicht geben.
      VG, Wolfgang
      PS: schönes Projekt – die Trockenhaube ist der Hammer!

  4. Lieber Wolfgang Ewald,

    Danke für die Teilhabe an Deinem Projekt! Du hast es super dokumentiert und mir damit sehr geholfen bei dem Rangehen an ein eigenes Projekt!
    Kannst Du mir bitte verraten wo Du das Gehäuse gekauft hast, das Du für Dein Projekt genutzt hast? Das wäre super nett von Dir!

    Herzliche Grüße und einen guten Rutsch ins neue Jahr wünscht Leonardo

  5. Hallo Wolfgang,

    ich bin am probieren mit dem YX5300 zusammen mit einem Mega2650.
    Grundsätzlich läuft die Demo, allerdings einmal einen mp3 file gestartet, läuft er in einer endlosschleife.
    Ist das so gewollt ? stoppen geht schon mit dem „Stop command“, aber ich hatte gedacht, wenn man mit play startet, läuft der file nur einmal.
    Was muss ich beachten ?

    Danke und Gruß aus Südhessen

    Michael Strebelow

    1. Hallo Michael,

      wie hast du den MP3 File denn gestartet? Mit „P01“ (oder entsprechend anderer Nummer), „S01“ oder einfach nur mit „p“? Mit „P01“ sollte er nur einmal laufen, mit „S01“ sollte er in Schleife laufen. Es ist etwas her, dass ich damit gearbeitet habe. Deshalb weiß ich nicht mehr so recht was passiert, wenn du einfach mit „p“. Wenn er schlau ist, dann merkt er sich die Einstellung, also ob du zuvor mit „P“ oder „S“ aufgerufen hast. Du kannst ja mal mit „P“ und „S“ spielen. VG, Wolfgang

  6. Hallo und danke für den ausführlichen Beitrag!
    Ich habe zwei dieser „YX5300“ Module vor mir liegen und werde bald verrückt.
    Das Abspielen in einer Schleife funktioniert tadellos, der Befehl eine spezielle Datei („P01“ in ihrem Sketch, 0x03 mit Parameter 0x01 laut Datenblatt) jedoch nur einmal abzuspielen hat aber seltsame Nebeneffekte.
    Dabei wird der Sound nicht in Originalgeschwindigkeit abgespielt sondern zu langsam und seltsam verzerrt. Sendet man den Befehl zwei mal sofort hintereinander wird der erste verzerrt und der zweite normal abgespielt.
    Ich habe zwei Module bestellt, da das erste einen „YX6300“ (nachgemacht?) drauf hatte. Das zweite Modul von anderem Händler hat jedoch auch einen „6300“ und genau den selben Fehler. Beide waren mit 5300 im Internet gelistet. Nebenbei sind auch RX und TX an den Teilen vertauscht und der Befehl 0x22 (Titel mit Lautstärke X abspielen) funktioniert überhaupt nicht.
    Tritt dieser seltsame Fehler auch bei ihrem Modul auf oder haben sie ein Idee woran es liegen kann (außer dass es vermutlich billige Kopien sind)?
    MfG,
    Max

    1. Hallo, den Fehler hatte ich nicht. Anscheinend gibt es tatsächlich auch den YX6300. Ich habe mir gerade ein Modul bestellt und werde das mal ausprobieren. Das wird jetzt aber ein paar Tage dauern.

      Ich habe nichts darüber gefunden, was den YX5300 vom YX6300 unterscheidet. Auch habe ich nur ein YX5300 Datenblatt gefunden.

      Vielleicht probierst du den mal aus:
      https://github.com/cefaloide/ArduinoSerialMP3Player/blob/master/ArduinoSerialMP3Player/ArduinoSerialMP3Player.ino

      Oder du fragst mal auf github bei dem Autor der Bibliothek an.

      Oder – nur eine Idee – füge mal
      #define NO_SERIALMP3_DELAY am Anfang des Sketches ein.

      1. Wahnsinn, so schnell habe ich nicht mit einer Antwort gerechent! Vielen Dank!
        Unterschiede habe ich online auch keine gefunden und wie sie schon sagten scheint das einzige existierende Datenblatt, das des Catalex YX5300 zu sein.
        Ich habe bis gerade noch einmal rumprobiert und wenn ich ein ganzes Lied (cd 2,5min) per 0x03 abspiele, dann klappt das doch ohne Probleme. Ich habe es bisher mit kurzen Sounds probiert (~150ms), da das ganze in einem Metronom bis 300BPM eingesetzt werden soll. Einige Sounds werden unter 200ms länge verzerrt, bei anderen klingt es noch ok. Sehr seltsam. Auch in Dauerschleife scheint die erste Wiedergabe einer Datei verzerrt zu sein bei kurzen Schnipseln, die Folgenden klingen normal. Auch WAV vs mp3 scheint keinen reproduzierbaren Unterschied zu machen. Leider schweigt sich auch das Datenblatt zu Details der unterstützten Dateiformate aus (Mindestlänge z.B.).

        Bisher nutze ich keine Bibliothek aber Code-Schnipsel aus dem Internet, die dem Link fast 1:1 entsprechen (sendCommand funktion, etc.). Ich werde die Tage auf jeden Fall nochmal das NO_SERIALMP3_DELAY ausprobieren.

        1. Soo, es hat mir keine Ruhe gelassen!
          Ich habe jetzt einen Sound von 200 ms auf genau 1 s „gestreckt“, indem ich mit Audacity hinten „Stille“ angehängt habe und siehe da …. es funktioniert! Auch bei 300bpm klappt es jetzt, da der neue Abspielbefehl den laufenden Titel einfach verdrängt. Dennoch sehr seltsames Verhalten bei kurzen Sounds und das ist auch eher ein Workaround um das Problem als eine richtige Lösung.
          Ich bin trotzdem gespannt, ob sie noch etwas dazu herausfinden.
          MfG

          1. Hallo, ich bin noch eine Antwort schuldig. Die YX6300 Module sind mittlerweile eingetroffen. Allerdings komme ich im Moment schlicht nicht dazu…..

            1. Sooo, ich melde mich nochmal kurz.
              Ich hab leider keine vernünftige Lösung mit dem YX5300 gefunden.
              Anscheinend ist er einfach nicht dafür ausgelegt so kurze Sounds schnell abzuspielen – ist ja auch ein eher spezielles Problem.
              Die Sound auf 1 sek. zu „strecken“ und immer wieder neu zu starten hat zwar halb funktioniert, aber auch zu vereinzeltem stottern geführt.

              Wir sind jetzt auf einen esp32 dev Board in Kombination mit einem MAX98357A Amplifier Board gewechselt. Die Sounds werden so per I2S direkt über den Mikrokontroller übertragen und geben uns mehr Kontrolle über abspielen und abbrechen von Sounds. Funktioniert tadellos. Wenn also noch jemand ein ähnliches Problem hat, da scheint die Grenze des YX5300 erreicht.

              Trotzdem vielen Dank für die schnellen Tipps und die gute Anleitung im Beitrag!
              MfG

              1. Vielen Dank. Das kann anderen unter Umständen viel Zeit sparen. Ich freue mich immer wenn Leute auch mitteilen, dass sie eine alternative Lösung gefunden haben.

              2. Hallo Max,
                wie ist es ihnen gelungen den MAX98357A in den obigen Sketch einzubauen? iIch versuche das schon seit einigen Wochen immer mal wieder, aber es ist mir bisher nicht gelungen. Haben Sie einen Tipp für mich oder sogar einen Sketch, das würde mir sehr weiterhelfen. Habe im Intenet noch keinen besseren MP3- player gefunden, würde auch gern Wolles MP3 weiter benutzen, mit I2s wäre mir das noch lieber.
                Vielen Dank im Voraus
                MfG.

  7. Vielen Dank für den tollen Beitrag zu dem YX5300.
    Aktuell bin ich dabei mit dem Arduino einen MP3-Player
    mit Touchscreen zu bauen und es funktioniert bereits
    alles soweit. Nur bei der Anzeige des aktuellen Titels
    und des „play-status“ habe ich mir die Zähne ausgebissen.
    Können Sie mir da eventuell weiterhelfen mit einen kurzen
    Beispiel-Code ? Ich wäre Ihnen sehr dankbar.

    1. Bei Verwendung der SerialMP3Player Bibliothek sind die Funktionen für die Abfrage – sofern dein Player „mp3“ heißt – mp3.qPlaying() bzw. mp3.qStatus(). Die Antwort wird dann in dem String gespeichert, den mp3.decodeMP3Answer() zurück liefert, also so wie oben im Sketch:

      if (mp3.available()){
      Serial.println(mp3.decodeMP3Answer());
      }

      Funktioniert das nicht oder habe ich vielleicht die Frage falsch verstanden?

      1. Vielen Dank für die schnelle Antwort.
        Genau so habe ich es gemacht, aber „Serial.println(mp3.decodeMP3Answer()“ gibt leider nichts aus.
        Ich weiss nicht was ich falsch mache:

        mp3.qStatus();
        Serial.println(mp3.decodeMP3Answer());

        Das sollte doch den Status ausgeben, oder verstehe ich es einfach falsch?

        1. Ich habe mir das noch mal angeschaut und probiert. Auf dem seriellen Monitor funktioniert es. Funktioniert es denn bei dir nur auf dem TFT Monitor nicht oder auch schon nicht auf dem seriellen Monitor? Wenn es nur auf dem TFT Monitor nicht geht, kann es sein, dass einfach der String zu lang ist? Es wird ja eine ganze Menge zurückgemeldet, eine typische Antwort sieht so aus:

          0X7e 0Xff 0X06 0X4c 0X00 0X00 0X04 0Xfe 0Xab 0Xef -> Playing: 4
          0X7e 0Xff 0X06 0X41 0X00 0X00 0X00 0Xfe 0Xba 0Xef -> Data recived correctly.

          Und alles was du wahrscheinlich haben willst, ist in diesem Fall die 4.

          Um nur das auf den Bildschirm zu beamen, was dich interessiert, könntest du folgendes versuchen:
          if (mp3.available()){
          String hilfstring = mp3.decodeMP3Answer();
          hilfstring.remove(0,54);
          if(hilfstring.startsWith("Playing")){
          hilfstring.remove(0,9);
          Serial.println(hilfstring);
          }
          if(hilfstring.startsWith("Status")){
          hilfstring.remove(0,8);
          Serial.println(hilfstring);
          }
          }

          Ich bekomme gerade die Einrückungen nicht hin….

          1. Ich habe das Problem sowohl auf dem LCD-Display als auch per seriellen Monitor.
            Ich erhalte nur die Meldung „0X7e 0Xff 0X06 0X41 0X00 0X00 0X00 0Xfe 0Xba 0Xef -> Data recived correctly. “ und sonst nichts.
            Wenn ich im Seriellen Monitor q eingebe sollte ich doch auch die Status-Meldung bekommen, richtig ?

            1. Das ist aber schon ein wertvoller Hinweis, denn das, was du bekommst ist der zweite Teil der Rückmeldung (in meinem letzten Kommentar siehst du wie eine vollständige Meldung aussieht). Die gute Nachricht ist also, dass die Kommunikation vom YX5300 zum Microcontroller prinzipiell funktioniert. Aus irgendwelchen Gründen wird der erste, relevante Teil der Meldung verschluckt. Funktioniert denn der Beispielsketch aus dem Beitrag? Oder auch nicht? Falls er funktioniert, würde ich mir deinen Sketch gerne mal anschauen. Falls der Beispielsketch nicht funktioniert, muss das Problem hardwareseitig liegen, dann schauen wir da weiter.

  8. Can guide me that how i can play a video on android devise controlled by an arduino.

    1. I can’t provide a detailed step by step instruction, but basically this should also work with App Inventor. In the palette menue you find under Media the VideoPlayer. If you then change to the Blocks screen you can choose from several options/actions for the VideoPlayer. The commands can be send via bluetooth from the Arduino. If your BT module is connected with a software serial it’s something like „mySerial.print(your command)“. On the App Inventor side you have insert a simple if-then-else block to interprete the received BT message and execute the action for the VideoPlayer. Hope this very rough description gives some guidance into the right direction.

Schreibe einen Kommentar

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