3D Print Your Own Mini Macintosh WeMos MP3 Player

3D Print Your Own Mini Macintosh WeMos MP3 Player

Ah Yes! Bieber has never sounded so good - (haha). Music does sound just a little bit better though when it's your own self-made retro mini Macintosh MP3 player with working SD card/diskette slot. So load up as many favorites as you can think of then slide the SD card into the mini Macintosh card slot and enjoy. 


To get started we have provided a list that will help you gather up everything you will need. This does include use or access to use of a 3D printer or friend with a 3D printer.

Shopping List

WeMos D1 Mini  WeMos dual base

  • WeMos D1 mini
  • WeMos dual base
  • Catalex MP3 Player - (we will be stocking this item shortly)
  • SD Card
  • micro USB to USB cable - (you should have one around if you have an android phone).
  • 4x - male to female jumper wires
  • 4x - #4-40 1 3/8" screws and nuts
  • 1x - $4-40 1/2" screw and nut 
  • 3D printed parts provided by GadgetsThatGo @ Thingiverse.com


To start putting things together you will need to screw the WeMos dual base to the inside of the back case as pictured below.


With the dual base secure you can mount the WeMos D1 mini to the above slot on the dual base as pictured below.


Moving onto the front panel you will need to mount the Catalex MP3 card to the backside of the front panel. It is important that the sd card slot is lined up correctly so you can add and remove cards properly when the case is closed. 


To secure the MP3 card in place you will attach the holding pin securing it by sliding a screw through the holding pin and two extruding screw holes on the backside of the front panel. The screw can then be capped off with a nut and tightened so the holding pin holds the MP3 card securely in place as shown below.


Connecting the MP3 board will require the use of four male to female jumper wires. I have included the fritzing diagram below to help as well. The pins on the Catalex MP3 are naturally bent at a 90-degree angle. This will not allow enough room for the jumper wires so gently bending them more upright was an adjustment I made before connecting the wires.


 Catalex MP3 Player WeMos
Tx D1 (code defined as Rx)
Rx D2 (code defined as Tx)




Before closing up the mini Macintosh you will want to upload the code necessary to play the MP3's on your SD Card. I have added what you will need to get started below. I found demo code for the Catalex MP3 player and made a small tweak so music auto-plays when you supply power through the micro USB. Feel free to make modifications to make your mini that more unique.

/* Demo for the Serial MP3 Player Catalex (YX5300 chip)
 Hardware: Serial MP3 Player *1
 Board:  Arduino UNO

 Uncomment SoftwareSerial for Arduino Uno or Nano. */


#define ARDUINO_RX D1  //should connect to TX of the Serial MP3 Player module
#define ARDUINO_TX D2  //connect to RX of the module

SoftwareSerial mp3(ARDUINO_RX, ARDUINO_TX);

/* Uncomment next line if you are using an Arduino Mega.
#define mp3 Serial3   Connect the MP3 Serial Player to the Arduino MEGA Serial3 (14 TX3 -> RX, 15 RX3 -> TX)
static int8_t Send_buf[8] = {0}; // Buffer for Send commands.  // BETTER LOCALLY
static uint8_t ansbuf[10] = {0}; // Buffer for the answers.    // BETTER LOCALLY

String mp3Answer;           // Answer from the MP3.

String sanswer(void);
String sbyte2hex(uint8_t b);

/************ Command byte **************************/
#define CMD_NEXT_SONG     0X01  // Play next song.
#define CMD_PREV_SONG     0X02  // Play previous song.
#define CMD_PLAY_W_INDEX  0X03
#define CMD_VOLUME_UP     0X04
#define CMD_VOLUME_DOWN   0X05
#define CMD_SET_VOLUME    0X06

#define CMD_SNG_CYCL_PLAY 0X08  // Single Cycle Play.
#define CMD_SEL_DEV       0X09
#define CMD_SLEEP_MODE    0X0A
#define CMD_WAKE_UP       0X0B
#define CMD_RESET         0X0C
#define CMD_PLAY          0X0D
#define CMD_PAUSE         0X0E

#define CMD_STOP_PLAY     0X16  // Stop playing continuously. 
#define CMD_FOLDER_CYCLE  0X17
#define CMD_SHUFFLE_PLAY  0x18 //
#define CMD_SET_SNGL_CYCL 0X19 // Set single cycle.

#define CMD_SET_DAC 0X1A
#define DAC_ON  0X00
#define DAC_OFF 0X01

#define CMD_PLAY_W_VOL    0X22
#define CMD_PLAYING_N     0x4C
#define CMD_QUERY_STATUS      0x42
#define CMD_QUERY_VOLUME      0x43
#define CMD_QUERY_TOT_TRACKS  0x48
#define CMD_QUERY_FLDR_COUNT  0x4f

/************ Options **************************/
#define DEV_TF            0X02


void setup()

  sendCommand(CMD_SEL_DEV, 0, DEV_TF);

void loop()
  char c = ' ';

  // If there a char on Serial call sendMP3Command to sendCommand
  if ( Serial.available() )
    c = Serial.read();

  // Check for the answer.
  if (mp3.available())

Function sendMP3Command: seek for a 'c' command and send it to MP3  
Parameter: c. Code for the MP3 Command, 'h' for help.                                                                                                     
Return:  void  */

void sendMP3Command(char c) {
  switch (c) {
    case '?':
    case 'h':
      Serial.println("HELP  ");
      Serial.println(" p = Play");
      Serial.println(" P = Pause");
      Serial.println(" > = Next");
      Serial.println(" < = Previous");
      Serial.println(" s = Stop Play"); 
      Serial.println(" + = Volume UP");
      Serial.println(" - = Volume DOWN");
      Serial.println(" c = Query current file");
      Serial.println(" q = Query status");
      Serial.println(" v = Query volume");
      Serial.println(" x = Query folder count");
      Serial.println(" t = Query total file count");
      Serial.println(" f = Play folder 1.");
      Serial.println(" S = Sleep");
      Serial.println(" W = Wake up");
      Serial.println(" r = Reset");

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

    case 'P':

    case '>':
      sendCommand(CMD_PLAYING_N); // ask for the number of file is playing

    case ' Memory card inserted.";

    case 0x3D:
      decodedMP3Answer += " -> Completed play num " + String(ansbuf[6], DEC);

    case 0x40:
      decodedMP3Answer += " -> Error";

    case 0x41:
      decodedMP3Answer += " -> Data recived correctly. ";

    case 0x42:
      decodedMP3Answer += " -> Status playing: " + String(ansbuf[6], DEC);

    case 0x48:
      decodedMP3Answer += " -> File count: " + String(ansbuf[6], DEC);

    case 0x4C:
      decodedMP3Answer += " -> Playing: " + String(ansbuf[6], DEC);

    case 0x4E:
      decodedMP3Answer += " -> Folder file count: " + String(ansbuf[6], DEC);

    case 0x4F:
      decodedMP3Answer += " -> Folder count: " + String(ansbuf[6], DEC);

  return decodedMP3Answer;

Function: Send command to the MP3                                            
Parameter: byte command  
Parameter: byte dat1 parameter for the command 
Parameter: byte dat2 parameter for the command */

void sendCommand(byte command){
  sendCommand(command, 0, 0);

void sendCommand(byte command, byte dat1, byte dat2){
  Send_buf[0] = 0x7E;    //
  Send_buf[1] = 0xFF;    //
  Send_buf[2] = 0x06;    // Len
  Send_buf[3] = command; //
  Send_buf[4] = 0x01;    // 0x00 NO, 0x01 feedback
  Send_buf[5] = dat1;    // datah
  Send_buf[6] = dat2;    // datal
  Send_buf[7] = 0xEF;    //
  Serial.print("Sending: ");
  for (uint8_t i = 0; i < 8; i++)
    mp3.write(Send_buf[i]) ;

Function: sbyte2hex. Returns a byte data in HEX format.                      
Parameter:- uint8_t b. Byte to convert to HEX.  
Return: String  */

String sbyte2hex(uint8_t b)
  String shex;

  shex = "0X";

  if (b < 16) shex += "0";
  shex += String(b, HEX);
  shex += " ";
  return shex;

Function: shex2int. Returns a int from an HEX string. 
Parameter: s. char *s to convert to HEX. 
Parameter: n. char *s' length. 
Return: int  */

int shex2int(char *s, int n){
  int r = 0;
  for (int i=0; i='0' && s[i]<='9'){
      r *= 16; 
      r +=s[i]-'0';
     }else if(s[i]>='A' && s[i]<='F'){
      r *= 16;
      r += (s[i] - 'A') + 10;
  return r;

Function: sanswer. Returns a String answer from mp3 UART module. 
Parameter:- uint8_t b. void.  
Return: String. If the answer is well-formated answer.   */

String sanswer(void)
  uint8_t i = 0;
  String mp3answer = "";

  // Get only 10 Bytes
  while (mp3.available() && (i < 10))
    uint8_t b = mp3.read();
    ansbuf[i] = b;

    mp3answer += sbyte2hex(b);

  // if the answer format is correct.
  if ((ansbuf[0] == 0x7E) && (ansbuf[9] == 0xEF))
    return mp3answer;

  return "???: " + mp3answer;

To finish assembly you will need to connect the front and backside. the easiest way to do this is to line up all the fittings as they would be attached slowly working both pieces in evenly.


Leave a comment

Please note, comments must be approved before they are published