How to read queried values from MP3 module DFPlayer mini without any library?

Hi!

I'm using the DFPlayer Mini module on a Digispark PRO (Attiny167).

I couldn't make any DFplayer-ready libraries (for arduino) I tried to work with it.

So I searched the internet and found some sketches that some people wrote that sends data via serial directly to the module, without any library, and I could make it work in most functions I needed, as Play, Pause, Next and Previous songs.

Still, I couldn't make the all files random command work, even by writing 0x08 with the value 3, as stated in the DFRobot wiki:

I using this partial sketch attached to send the needed values to the Player: For instance, this one with the function set the Volume.

So although I can send commands to the DFPlayer, I don't know how to read something from it.

I need to be able to query the number of files present on the SD card, so I can create a random-play function myself, based on the number of MP3 files present.

I need something that perform like this, extracted from this DFRobot Library:

// value = myDFPlayer.readFileCounts(); //read all file counts in SD card

But without using any library. I know the command to be queried is 0x47, but I don't know how to perform it.

The "execute_CMD" function I have only sends data using serial, but doesn't have an option to get a value back.

Can anyone help me in writing a small function (with no library - none worked so far) so I can read a value from the DFplayer?

Specifically my need is to query manually the number of files on the sd card...

Thanks!

Sketch.ino (895 Bytes)

Try this (it should automatically play all the files randomly without querying the number of files):

#include <SoftwareSerial.h>

//-------------------------------------------------------------------------------------//
// Packet Values
//-------------------------------------------------------------------------------------//
#define DFPLAYER_SEND_LENGTH    10
#define SB                      0x7E //start byte
#define VER                     0xFF //version
#define LEN                     0x6  //number of bytes after "LEN" (except for checksum data and EB)
#define FEEDBACK                1    //feedback requested
#define NO_FEEDBACK             0    //no feedback requested
#define EB                      0xEF //end byte

#define RAND_COMMAND            0x18

SoftwareSerial dfplayer(2, 3); // RX, TX

uint8_t sending[DFPLAYER_SEND_LENGTH] = {0};
  
uint8_t commandValue  = 0;
uint8_t feedbackValue = 0;
uint8_t paramMSB      = 0;
uint8_t paramLSB      = 0;
uint8_t checksumMSB   = 0;
uint8_t checksumLSB   = 0;

void setup()
{
  Serial.begin(115200);

  dfplayer.begin(9600);
}

void loop()
{
  random_all();
  delay(300000); // wait 5 min
}

void random_all()
{
  commandValue  = RAND_COMMAND;
  feedbackValue = NO_FEEDBACK;
  paramMSB = 0;
  paramLSB = 0;

  findChecksum();
  sendData();
}

void findChecksum()
{
  uint16_t checksum = (~(VER + LEN + commandValue + feedbackValue + paramMSB + paramLSB)) + 1;

  checksumMSB = checksum >> 8;
  checksumLSB = checksum & 0xFF;
}

void sendData()
{
  sending[0] = SB;
  sending[1] = VER;
  sending[2] = LEN;
  sending[3] = commandValue;
  sending[4] = feedbackValue;
  sending[5] = paramMSB;
  sending[6] = paramLSB;
  sending[7] = checksumMSB;
  sending[8] = checksumLSB;
  sending[9] = EB;
  
  dfplayer.write(sending, DFPLAYER_SEND_LENGTH);
}

The code in the previous reply was based off of the info from the DFPlayerMini datasheet:

Random playback of the whole storage device:
7E FF 06 18 00 00 00 FE E3 EF
1).This command is used to randomly play sound files in the storage device according to physical sequence and no matter if there is a folder or not in the device. The first sound file that is conducted to be played is the first one in the device.

Datasheet

@ Power_Broker!

Unfortunately the code didn´t work at all. I changed the rx and tx pins to 6 and 7 (Digispark PRO), changed the Software Serial Library to SoftSerial Library (the equivalent version of the library dedicaded to Digispark), and even tried the hardware serial instead of software serial.

Nothing was even played.

Any other ideas?

Thanks for answering so fast!

HI again

I´m using this function (execute_CMD) (not made by me) to write to the DFPlayer and it works nicely so far.

I found over the internet someone that made a code to read from the DFPlayer and I tried to combine both parts (reading and writing from serial) on the same function I already had (execute_CMD)

I don´t understand much about byte shifting and the calculations for the checksum.

I do understood the part for writing over serial with the checksum required (and it works).

But I didn´t get much over the part for extracting the values received from the checksum (when reading from the serial)

And it didn´t work for me either. As My Digispark PRO has no serial monitor, I have to blink the onboard led to check if the data (number of files: 4 actually) as received. And so far nothing.

So could someone check the reading from serial part of the code, and maybe correct it for me? Or make it more easier as the first part that gets the value and writes to the player?

The function I need to use is the checkFileCount. I then turn on and off the onboard led to check how many files are in the card...

long checkFileCount()
{
  drainResponses();
  delay(1500);
  file_Count = execute_CMD(0x48, 0, 0); // Queries for number of files present on the media
  delay(200);
}

void drainResponses()
{
  while (Serial.available())
  {
    Serial.read();
  }
}


int execute_CMD(byte CMD, byte Par1, byte Par2)
// Excecute the command and parameters
{
  byte received_Data[10];
  // Calculate the checksum (2 bytes)
  word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
  // Build the command line
  byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
                            Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte
                          };
  //Send the command line to the module
  for (byte k = 0; k < 10; k++)
  {
    Serial.write( Command_line[k]);
  }

  // If answer is expected from module

  if (CMD > 0x20) {

    delay(100);
    if (Serial.available() >= 10) {
      for (uint8_t j = 0; j < 10; j++)
      {
        received_Data[j] = Serial.read();
      }
      /* Flush exta bytes from receive buffer */
      while (Serial.available())
      {
        Serial.read();
      }

    }
    /* Compute checksum from receive buffer and compare it to the computed checksum */
    int16_t checksum2 = checkSum(received_Data);
    if (checksum2 == ((received_Data[7]  << 8) || received_Data[8]))
    {
      return ( ((received_Data[5] << 8) || received_Data[6])); // Returns the value expected from the Command sent
    }

  }
}
int16_t checkSum(uint8_t *received_Data)
{
  int16_t result = 0;
  for (uint8_t i = 1; i < 7; i++)
  {
    result += received_Data[i];
  }
  result *= -1;
  return (result);
}