Sending a command to MP3 Module

So I've bought a few of these MP3 modules from MDFLY.com intending to embed them in a couple of projects.
SD Card MP3 Player Module RS232-TTL - MDFLY
Manual attached, just 2 pages.
And I've written this sketch to read a keypad, and send a number to the module to play a file.
I made a bunch of short files that are just the word "zero", "one", "two", etc. up to "nine" and "invalid".
I have a MAX7219 with bubble display to show some status.
Rx/Tx go the module, not reading anything back yet (not sure if anything even comes back).

Got my control code figured out - but I can't get this thing to play the files I want.
I send it 1,01, 0x01, it plays file 008.mp3.
I send it 2, 02, 0x02, it plays file 009.mp3
I send it 3, 03, 0x03, it plays file 001.pm3
I send it A, it plays 008.mp3.

Have I got something really wrong here?

// test code for playing MP3s from MDFLY SD card module

// use MAX7219 to drive 7-segment display
// 12 button keypad like on a touchtone phone
// * and # to do what?

// files will be dialtone, 0-9, *, #, and 20 to 199

// display: 3 digits


#include <SPI.h>
#include <Keypad.h>

byte ssPin = 10; // MAX7219 slave select

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {
    '1','2','3','A'          }
  ,
  {
    '4','5','6','B'          }
  ,
  {
    '7','8','9','C'          }
  ,
  {
    '*','0','#','D'          }
  ,
};
// A,B,C,D,*,# not used

byte rowPins[ROWS] = {
  2,3,4,5}; //row pins
byte colPins[COLS] = {
  6,7,8,9}; //column pins
  // column 9 goes away with 12 button?

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

byte busyPin = 14;
byte stopped = 0;
byte playing = 1;
byte paused = 2;
byte playState = stopped; // stopped, playing, paused
byte songUpper = 0;
byte songMiddle = 0;
byte songLower = 1;
byte song = 1;

byte blank = 10;
byte P = 11;
byte L = 12;
byte A = 13;
byte Y = 14;
byte U = 15;
byte S = 16;
byte E = 17;
byte Q = 18;
byte T = 19;
byte O = 20;
byte commandArray[] = {
  S,T,O,P,blank,};

byte fontArray[] = {
  // D7-6-5-4-3-2-1-0 = DP-A-B-C-D-E-F-G
  0b01111110, // 0
  0b00110000, // 1
  0b01101101, // 2
  0b01111001, // 3
  0b00110011, // 4
  0b01011011, // 5
  0b01011111, // 6
  0b01110000, // 7
  0b01111111, // 8
  0b01111011, // 9
  0b00000000, // 10 blank
};

unsigned long currentMillis;
unsigned long buttonPressTime;
unsigned long elapsedButtonTime;
unsigned long displayOnTime = 30000; // 30 seconds

byte decrement = 0;
byte Apressed = 0;

// ***********************************

void setup(){

  pinMode (busyPin, INPUT_PULLUP);

  pinMode (ssPin, OUTPUT);
  SPI.begin();
  // MAX7219 setup:
  // shutdown mode 
  digitalWrite (ssPin, LOW);
  SPI.transfer(0x0C); 
  SPI.transfer(0);
  digitalWrite (ssPin, HIGH);

  // 8 digits 
  digitalWrite (ssPin, LOW);
  SPI.transfer(0x0B); 
  SPI.transfer(0x07);
  digitalWrite (ssPin, HIGH);

  // no decode mode 
  digitalWrite (ssPin, LOW);
  SPI.transfer(0x09); 
  SPI.transfer(0);
  digitalWrite (ssPin, HIGH);

  // display test off
  digitalWrite (ssPin, LOW);
  SPI.transfer(0x0F); 
  SPI.transfer(0);
  digitalWrite (ssPin, HIGH);

  // intensity
  digitalWrite (ssPin, LOW);
  SPI.transfer(0x0A); 
  SPI.transfer(7); // 1/2 bright
  digitalWrite (ssPin, HIGH);


  // all done, normal mode 
  digitalWrite (ssPin, LOW);
  SPI.transfer(0x0C); 
  SPI.transfer(1);
  digitalWrite (ssPin, HIGH);

  // display song & PLAY
  digitalWrite (ssPin, LOW);
  SPI.transfer(8); // address
  SPI.transfer(fontArray[songUpper]);
  digitalWrite (ssPin, HIGH);
  digitalWrite (ssPin, LOW);
  SPI.transfer(7); // address
  SPI.transfer(fontArray[songMiddle]);
  digitalWrite (ssPin, HIGH);
  digitalWrite (ssPin, LOW);
  SPI.transfer(6); // address
  SPI.transfer(fontArray[songLower]);
  digitalWrite (ssPin, HIGH);

  Serial.begin(4800);
} // end setup

void loop(){

  char key = keypad.getKey();

  if (key != NO_KEY){
    // for debug:
    //Serial.println(key);
//    buttonPressTime = currentMillis;
    // if display was off, turn it on
    // normal mode 
    digitalWrite (ssPin, LOW);
    SPI.transfer(0x0C); 
    SPI.transfer(1);
    digitalWrite (ssPin, HIGH);

    // act on key press
    switch(key){
    case '0':
      // move data across 'screen'
      songUpper = songMiddle;
      songMiddle = songLower;
      songLower = 0;

      // send data to 'screen'
      digitalWrite (ssPin, LOW);
      SPI.transfer(8); // address
      SPI.transfer(fontArray[songLower]);
      digitalWrite (ssPin, HIGH);
      digitalWrite (ssPin, LOW);
      SPI.transfer(7); // address
      SPI.transfer(fontArray[songMiddle]);
      digitalWrite (ssPin, HIGH);
      digitalWrite (ssPin, LOW);
      SPI.transfer(6); // address
      SPI.transfer(fontArray[songUpper]);
      digitalWrite (ssPin, HIGH);

      // send number file
      Serial.write(A); // 1010
      //Serial.println ("Case 0");
      delay(100);

      break;

    case '1':
      // move data across 'screen'
      songUpper = songMiddle;
      songMiddle = songLower;
      songLower = 1;

      // send data to 'screen'
//(same as above, deleted for brevity here)

      // send number file
      Serial.write( 1); // 0001
      //Serial.println ("Case 1");
      delay(100);

      break;

// cases 2-3-4-5-6--8 deleted for brevity here - 9000 char limit!

    case '9':
      // move data across 'screen'
      songUpper = songMiddle;
      songMiddle = songLower;
      songLower = 9;

      // send data to 'screen'
//(same as above, deleted for brevity here) - can see a need for a function call!

      // send number file
      Serial.write(9); // 1001
      //Serial.println ("Case 9");
      delay(100);
      
      break;
    
      Serial.write(11); // should be "invalid" message

    } // end switch:case for keypad entry
  } // end key check

} // end loop

MP3 Module.pdf (83.1 KB)

Hello,

On the website of that MP3 thing, there is a comment that says:

The tracks are not played in the order they are numbered/named (001, 002, etc) but the order they are uploaded to the SD card (FAT 16/32 entry for the file name). So track name really doesn't matter. Track order can be controlled by either uploading tracks in the order you want to be played or using an external program to automate it like DriveSort.

It's not the first time I read about files not being "sorted" on the SD card. It might be your problem ?

So the note on the 2-page spec sheet:
"For example: If you want to pay song 001, just send 01 to the module, play song 010 send 0A"
is totally incorrect?
If true, that totally stinks!
Can't be totally correct - I can press the buttons in any order, and it always plays the same file for the same button.

What would be the FAT16/32 entry for these files:

00A.mp3, 00B.mp3, 001.mp3 up to 009.mp3?
00A & 00B do not play with any button press.
1 plays 8
2 -> 9
3 -> 1
4 -> 2
5 -> 3
6 -> 4
7 -> 5
8 -> 6
9 -> 7
0 -> 8 (00A expected).

Try to format the SD card and then copy only file 001.mp3, will it play with button 1 or still button 3?

Off to work - will try that when I get home.

Got this from MDFLY overnight, seems to back up what said guix:
"Hi,
The default baud rates is 4800,N,1. Start with a clean formatted SD card and then
drag each file, one at a time and in order from your computer to your SD card. This ensures that
they will be played back correctly. The MP3 module that might cause the
wrong file to be played if they are not copied to the SD card in the order that you want them
played.

Thanks,
Regards

MDFLY"

Not ideal, but I think this can be made to work. I think. I hope!

That seems to work. Formatted the drive, put on files 001, 002, 003, ... 00A, and they play back correctly when 1,2,3,..8,9, 0x0A are sent to the module. On to the next step!

Most of these MP3 boards are based on a VLSI decoder chip with a custom third party kernel that provides the command set. Is that 8-pin chip flash memory that's being used to hold the kernel? Your board seems to have a pretty limited command set for a chip with 45 pins.

I think the Serial Tx/Rx TTL levels should be 3.3V. Your running them at 5V.

Had 2 cards break on me - serial interface works, but only getting high pitch whine for audio.
MDFLY suggested putting caps in series with the line level out to the amps.
Are sending me two replacement cards.

Rx/Tx - spec sheet forVS1003 and VS1053b VLSI Solution website (Finland!) site shows digital IO at 3.3V +0.3V max.
I am thinking the IO lines must be protected a little as the serial interface is still working - can send a track #, and pause/stop/play commands and the status light that shows playback still operates the same, and the whining stops when playback stops.
The Typical connection diagram does not show any protection. I can put a meter on the pins and see if they're being held low.

vs1003.pdf (614 KB)

vs1053.pdf (832 KB)

I agree, doesn't do a whole lot of functions. I am only using it for Mp3 playback tho.

And I found this yesterday while looking for amps

Great for more interactive use - I am setting up for more of a standalone, embedded function.

This looks fun to play with too
https://www.parts-express.com/parts-express-bt-1a-bluetooth-receiver-module-for-wireless-reception-of-bluetooth-audio-sig--320-353