YX5300 mp3 плеер

Привет, дрзья, давненько я здесь не был.)
Ну-ну, вот_вот с большой, привет.
Нужно просто чтобы плейлист выводился в монитор,
Далее просто при i++ следующий трек гавакал. а при i=i-1; пред. И хорошо бы, друзья мои, чтобы можно было паузу делать и начинать стой же папке

#include <SoftwareSerial.h>

#define ARD_RX 8 // подключить к TX модуля
#define ARD_TX 9 // подключить к RX модуля
#define BUTTON_PIN 2 // кнопка к GND (INPUT_PULLUP)

SoftwareSerial mp3(ARD_RX, ARD_TX);

uint8_t sendBuf[8];

void sendCommand(uint8_t cmd, uint8_t p1 = 0, uint8_t p2 = 0) {
  sendBuf[0] = 0x7E;
  sendBuf[1] = 0xFF;
  sendBuf[2] = 0x06;
  sendBuf[3] = cmd;
  sendBuf[4] = 0x01; // feedback on (можно 0x00 если не нужно)
  sendBuf[5] = p1;
  sendBuf[6] = p2;
  sendBuf[7] = 0xEF;
  for (uint8_t i = 0; i < 8; ++i) mp3.write(sendBuf[i]);
}

// DFPlayer команды
#define CMD_PLAY_TRACK   0x03
#define CMD_SEL_DEV      0x09
#define CMD_FOLDER_CYCLE 0x17
#define CMD_PAUSE        0x0E
#define CMD_START        0x0D // resume
#define DEV_TF           0x02

// Debounce
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
int lastButtonState = HIGH;
int buttonState = HIGH;

// Pause state machine (non-blocking)
enum PauseState { IDLE, PAUSED_WAIT };
PauseState pauseState = IDLE;
unsigned long pauseStartMillis = 0;
const unsigned long pauseDuration = 55000UL; // 55 секунд

void setup() {
  Serial.begin(9600);
  mp3.begin(9600);
 

  // выбрать TF (SD) на DFPlayer
  sendCommand(CMD_SEL_DEV, 0, DEV_TF);
  delay(1500); // даём модулю немного времени

  // Запустить цикл по папке 01 (файлы в /01/)
  sendCommand(CMD_FOLDER_CYCLE, 1, 0);
  Serial.println("Started folder cycle (folder 01). Press button to pause 55s.");
}

void loop() {
      delay(2222);
      sendCommand(CMD_PAUSE);
      delay(2222);
      sendCommand(CMD_START);
      delay(222222);
      
  // Здесь можно обрабатывать другие события / читать данные от модуля, если нужно.
  // Небольшая пауза для стабилизации цикла
  delay(5);
}

Это фантастика. Df pleer не умеет имена файлов читать.

1 лайк


И вот там посмотри, при 3х секундном осмотре кода увидел функционал переключения треков. Далее не смотрел.

Пожалуйста, попроще, друзья,
мне нужно только:

  1. play/pause/next/prev.
  2. (При окончании одного, воспроизводился другой)
  3. Текущий_track.getName();

А почему тема разделе “Песочница”, а не в “Ищу исполнителя”?

// Воспроизвести трек номер 1 (0001.mp3)
// Для треков больше 255 нужно использовать оба байта
sendCommand(CMD_PLAY_TRACK, 0x00, 0x01); // 0x03, p1=0, p2=1

// Воспроизвести трек номер 300
// 300 в hex = 0x012C, значит p1=0x01, p2=0x2C
sendCommand(CMD_PLAY_TRACK, 0x01, 0x2C);
// Воспроизвести файл 001.mp3 из папки 01
sendCommand(0x0F, 0x01, 0x01); // Папка 1, трек 1

// Воспроизвести файл 123.mp3 из папки 02  
sendCommand(0x0F, 0x02, 0x7B); // Папка 2, трек 123 (0x7B в hex)
// Воспроизвести файл 0012.mp3 из папки MP3
sendCommand(0x12, 0x00, 0x0C); // 12 в hex = 0x0C
// Циклическое воспроизведение папки 03
sendCommand(CMD_FOLDER_CYCLE, 0x03, 0x00); // 0x17

// Включить повтор текущего трека
sendCommand(0x19, 0x00, 0x01);

// Выключить повтор
sendCommand(0x19, 0x00, 0x00);
// Установить режим "Rock"
// 0=Normal, 1=Pop, 2=Rock, 3=Jazz, 4=Classic, 5=Bass
sendCommand(0x07, 0x00, 0x02); // Rock

// Выбрать устройство (если нужно переключиться)
sendCommand(CMD_SEL_DEV, 0x00, DEV_TF); // 0x09, выбор SD-карты
// Установить режим "Rock"
// 0=Normal, 1=Pop, 2=Rock, 3=Jazz, 4=Classic, 5=Bass
sendCommand(0x07, 0x00, 0x02); // Rock

// Выбрать устройство (если нужно переключиться)
sendCommand(CMD_SEL_DEV, 0x00, DEV_TF); // 0x09, выбор SD-карты
void loop() {
  // Проверяем кнопки (пример с 3 кнопками)
  if (digitalRead(BUTTON_NEXT) == LOW) {
    sendCommand(0x01); // Следующий трек
    delay(300); // защита от дребезга
  }
  
  if (digitalRead(BUTTON_PREV) == LOW) {
    sendCommand(0x02); // Предыдущий трек
    delay(300);
  }
  
  if (digitalRead(BUTTON_PLAY) == LOW) {
    static bool isPlaying = true;
    if (isPlaying) {
      sendCommand(CMD_PAUSE);
      isPlaying = false;
    } else {
      sendCommand(CMD_START);
      isPlaying = true;
    }
    delay(300);
  }
  
  // Ваш код с паузами (если нужен)
  // ...
}

Возможно YX5300 аналог DF mini?

Действительно запрос

case ‘c’:
Serial.println(“Query current file”);
sendCommand(CMD_PLAYING_N);
break;

наверное выдает порядковый номер проигрываемого файла.

Не видел в описаниях других ответов кроме цифр, в т.ч. коды состояния.

Может быть есть библиотека, как обращаться к SD карте через RX TX плеера?

Какая-нибудь команда SD_write_byte / SD_read_byte?

  1. Спасибо, BABOS, а как узнать имя текущего трека?

  2. Как узнать закончился ли трек текущий?

  3. Почему-то в этом коде не воспроизводится дальше треки прерывается цикличность папки, т.е. когда нажимаешь следующий трек, он воспроизводится до конца, а потом тишина.

#include <SoftwareSerial.h>

#define ARD_RX 8 // подключить к TX модуля
#define ARD_TX 9 // подключить к RX модуля
#define BUTTON_PIN 2 // кнопка к GND (INPUT_PULLUP)

SoftwareSerial mp3(ARD_RX, ARD_TX);

uint8_t sendBuf[8];

void sendCommand(uint8_t cmd, uint8_t p1 = 0, uint8_t p2 = 0) {
  sendBuf[0] = 0x7E;
  sendBuf[1] = 0xFF;
  sendBuf[2] = 0x06;
  sendBuf[3] = cmd;
  sendBuf[4] = 0x01; // feedback on (можно 0x00 если не нужно)
  sendBuf[5] = p1;
  sendBuf[6] = p2;
  sendBuf[7] = 0xEF;
  for (uint8_t i = 0; i < 8; ++i) mp3.write(sendBuf[i]);
}

// DFPlayer команды
#define CMD_PLAY_TRACK   0x03
#define CMD_SEL_DEV      0x09
#define CMD_FOLDER_CYCLE 0x17
#define CMD_PAUSE        0x0E
#define CMD_START        0x0D // resume
#define DEV_TF           0x02

/*
// Воспроизвести трек номер 1 (0001.mp3)
// Для треков больше 255 нужно использовать оба байта
sendCommand(CMD_PLAY_TRACK, 0x00, 0x01); // 0x03, p1=0, p2=1

// Воспроизвести трек номер 300
// 300 в hex = 0x012C, значит p1=0x01, p2=0x2C
sendCommand(CMD_PLAY_TRACK, 0x01, 0x2C);

// Воспроизвести файл 001.mp3 из папки 01
sendCommand(0x0F, 0x01, 0x01); // Папка 1, трек 1

// Воспроизвести файл 123.mp3 из папки 02  
sendCommand(0x0F, 0x02, 0x7B); // Папка 2, трек 123 (0x7B в hex)

// Воспроизвести файл 0012.mp3 из папки MP3
sendCommand(0x12, 0x00, 0x0C); // 12 в hex = 0x0C

// Циклическое воспроизведение папки 03
sendCommand(CMD_FOLDER_CYCLE, 0x03, 0x00); // 0x17

// Включить повтор текущего трека
sendCommand(0x19, 0x00, 0x01);

// Выключить повтор
sendCommand(0x19, 0x00, 0x00);

// Установить режим "Rock"
// 0=Normal, 1=Pop, 2=Rock, 3=Jazz, 4=Classic, 5=Bass
sendCommand(0x07, 0x00, 0x02); // Rock

// Выбрать устройство (если нужно переключиться)
sendCommand(CMD_SEL_DEV, 0x00, DEV_TF); // 0x09, выбор SD-карты
// Установить режим "Rock"
// 0=Normal, 1=Pop, 2=Rock, 3=Jazz, 4=Classic, 5=Bass
sendCommand(0x07, 0x00, 0x02); // Rock

sendCommand(CMD_PAUSE);
sendCommand(CMD_START);

*/










// Debounce
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
int lastButtonState = HIGH;
int buttonState = HIGH;

// Pause state machine (non-blocking)
enum PauseState { IDLE, PAUSED_WAIT };
PauseState pauseState = IDLE;
unsigned long pauseStartMillis = 0;
const unsigned long pauseDuration = 55000UL; // 55 секунд

void setup() {
  Serial.begin(9600);
  mp3.begin(9600);
 

  // выбрать TF (SD) на DFPlayer
  sendCommand(CMD_SEL_DEV, 0, DEV_TF);
  delay(1500); 

  
  
  
  sendCommand(CMD_FOLDER_CYCLE, 0x01, 0x00); // Запустить цикл по папке 01 (папки можно 02 03)
  //sendCommand(0x02); // Следующий трек;
    //delay(300);
    sendCommand(0x01); // Следующий трек;
    sendCommand(CMD_PAUSE);
    delay(300);
    sendCommand(CMD_START);
    delay(300);
    sendCommand(0x01); // Следующий трек;
    delay(300);
    sendCommand(0x01); // Следующий трек;
    delay(300);
    //sendCommand(0x01); // Следующий трек;
    //delay(300);

}

void loop() {
  
    // sendCommand(CMD_PAUSE);
    //delay(300);
    // sendCommand(CMD_START);
    //delay(300);
    //  sendCommand(0x01); // Следующий трек;
    //  delay(300);
     // sendCommand(0x01); // Следующий трек;
     // sendCommand(0x01); // Следующий трек;
     //delay(300); //чтобы не дребезжало
      
      

}

Об этом еще во втором сообщении сказано

я вам больше скажу
эти плеера не смотрят на имена файлов вообще!
очи читают фат и порядок/нумерацию для себя определяют по нему.

может что и изменилось на данный момент, но лет 5 назад, я столкнулся с этой дичью.

на этом модуле никак, сигнал Busy на нем заведен только на светодиод, который горит во время воспроизведения трека.

Остался один вопрос:

Как сделать чтобы просто по папке играл,( а если нажму next/pause/prev/start, но все равно по папке играл и не затыкался)?

а даташит почитать самому в лом?

Вот в чем загвоздка.

 sendCommand(0x01); //Следующий трек;
delay(300);

//После этой команды, по окончании
звучании следующего трека: уже ничего не звучит: тупо пауза: и все: тишина, и тишина.

все, забей, это не твоё.

2 лайка

Что можно сделать: задача простая, ведь: next/prev/pause/play и все время по одной папке ехать. Что сложного-то. Дайте код что ли, рабочий полный?

пробуйте

Сделал, как сказали Вы, но почему-то после команд в
setup()'e тишина после оканчания воспроизведения трека.

#include <SoftwareSerial.h>

#define ARD_RX 8 // подключить к TX модуля
#define ARD_TX 9 // подключить к RX модуля
#define BUTTON_PIN 2 // кнопка к GND (INPUT_PULLUP)

SoftwareSerial mp3(ARD_RX, ARD_TX);

uint8_t sendBuf[8];

void sendCommand(uint8_t cmd, uint8_t p1 = 0, uint8_t p2 = 0) {
  sendBuf[0] = 0x7E;
  sendBuf[1] = 0xFF;
  sendBuf[2] = 0x06;
  sendBuf[3] = cmd;
  sendBuf[4] = 0x01; // feedback on (можно 0x00 если не нужно)
  sendBuf[5] = p1;
  sendBuf[6] = p2;
  sendBuf[7] = 0xEF;
  for (uint8_t i = 0; i < 8; ++i) mp3.write(sendBuf[i]);
}

// DFPlayer команды
#define CMD_PLAY_TRACK   0x03
#define CMD_SEL_DEV      0x09
#define CMD_FOLDER_CYCLE 0x17
#define CMD_PAUSE        0x0E
#define CMD_START        0x0D // resume
#define DEV_TF           0x02

/*
// Воспроизвести трек номер 1 (0001.mp3)
// Для треков больше 255 нужно использовать оба байта
sendCommand(CMD_PLAY_TRACK, 0x00, 0x01); // 0x03, p1=0, p2=1

// Воспроизвести трек номер 300
// 300 в hex = 0x012C, значит p1=0x01, p2=0x2C
sendCommand(CMD_PLAY_TRACK, 0x01, 0x2C);

// Воспроизвести файл 001.mp3 из папки 01
sendCommand(0x0F, 0x01, 0x01); // Папка 1, трек 1

// Воспроизвести файл 123.mp3 из папки 02  
sendCommand(0x0F, 0x02, 0x7B); // Папка 2, трек 123 (0x7B в hex)

// Воспроизвести файл 0012.mp3 из папки MP3
sendCommand(0x12, 0x00, 0x0C); // 12 в hex = 0x0C

// Циклическое воспроизведение папки 03
sendCommand(CMD_FOLDER_CYCLE, 0x03, 0x00); // 0x17

// Включить повтор текущего трека
sendCommand(0x19, 0x00, 0x01);

// Выключить повтор
sendCommand(0x19, 0x00, 0x00);

// Установить режим "Rock"
// 0=Normal, 1=Pop, 2=Rock, 3=Jazz, 4=Classic, 5=Bass
sendCommand(0x07, 0x00, 0x02); // Rock

// Выбрать устройство (если нужно переключиться)
sendCommand(CMD_SEL_DEV, 0x00, DEV_TF); // 0x09, выбор SD-карты
// Установить режим "Rock"
// 0=Normal, 1=Pop, 2=Rock, 3=Jazz, 4=Classic, 5=Bass
sendCommand(0x07, 0x00, 0x02); // Rock

sendCommand(CMD_PAUSE);
sendCommand(CMD_START);

*/










// Debounce
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
int lastButtonState = HIGH;
int buttonState = HIGH;

// Pause state machine (non-blocking)
enum PauseState { IDLE, PAUSED_WAIT };
PauseState pauseState = IDLE;
unsigned long pauseStartMillis = 0;
const unsigned long pauseDuration = 55000UL; // 55 секунд

void setup() {
  Serial.begin(9600);
  mp3.begin(9600);
 

  // выбрать TF (SD) на DFPlayer
  sendCommand(CMD_SEL_DEV, 0, DEV_TF);
  delay(1500); 

  
  
  
 sendCommand(CMD_FOLDER_CYCLE, 0x01, 0x00);//pапустить цикл по папке 01 (папки можно 02 03)
  //sendCommand(0x02); // Следующий трек;
    //delay(300);
   //  sendCommand(0x01); // Следующий трек;
 delay(2000);
     sendCommand(CMD_PAUSE);
 delay(2200);
    sendCommand(CMD_START);
  delay(1300);
    sendCommand(0x01); // Следующий трек;
    delay(2300);
  sendCommand(0x01); // Следующий трек;
    delay(2300);
}

void loop() {
  /*
  delay(2000);
     sendCommand(CMD_PAUSE);
 delay(2200);
    sendCommand(CMD_START);
  delay(1300);
    sendCommand(0x01); // Следующий трек;
    delay(2300);
     // sendCommand(0x01); // Следующий трек;
     // sendCommand(0x01); // Следующий трек;
     //delay(300); //чтобы не дребезжало
      
    */  

}

Нашел код, думаю проблема - не решена: когда переключаю на следующий трек, п,осле его окончания ни фига не воспроизводится, в чем может быть дело?

#include "Arduino.h"
#include "DFRobotDFPlayerMini.h"
#if (defined(ARDUINO_AVR_UNO) || defined(ESP8266))   // Using a soft serial port
#include <SoftwareSerial.h>
SoftwareSerial softSerial(/*rx =*/8, /*tx =*/9);
#define FPSerial softSerial
#else
#define FPSerial Serial1
#endif
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);
void setup()
{
#if (defined ESP32)
  FPSerial.begin(9600, SERIAL_8N1, /*rx =*/D3, /*tx =*/D2);
#else
  FPSerial.begin(9600);
#endif
  Serial.begin(115200);
 
  
  if (!myDFPlayer.begin(FPSerial, /*isACK = */true, /*doReset = */true)) {  //Use serial to communicate with mp3.
 
  }
  
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms
  myDFPlayer.volume(30);  //Set volume value (0~30).
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
   myDFPlayer.loopFolder(1); //loop all mp3 files in folder SD:/01.
  //delay(1000);


  
  myDFPlayer.next();  //start the mp3 from the pause
  delay(1000);




  
 
}

void loop()
{
}

я думаю проблема в том что вы решили не проходить начальный курс)))
а люди устанут каждый раз решать ваши проблемы бесплатно)))
кстате из курса вы бы узнали про блоки setup loop и кучу других вещей

#include "Arduino.h"
#include "DFRobotDFPlayerMini.h"

#if (defined(ARDUINO_AVR_UNO) || defined(ESP8266))   // Using a soft serial port
#include <SoftwareSerial.h>
SoftwareSerial softSerial(/*rx =*/8, /*tx =*/9);
#define FPSerial softSerial
#else
#define FPSerial Serial1
#endif

DFRobotDFPlayerMini myDFPlayer;
unsigned long lastCheck = 0;
bool isPlaying = false;

void printDetail(uint8_t type, int value);

void setup()
{
#if (defined ESP32)
  FPSerial.begin(9600, SERIAL_8N1, /*rx =*/D3, /*tx =*/D2);
#else
  FPSerial.begin(9600);
#endif
  Serial.begin(115200);
  
  if (!myDFPlayer.begin(FPSerial, /*isACK = */true, /*doReset = */true)) {
    Serial.println("DFPlayer Mini initialization failed!");
    while(true);
  }
  
  myDFPlayer.setTimeOut(500);
  myDFPlayer.volume(30);
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
  myDFPlayer.loopFolder(1);  // Это должно зациклить папку, но не всегда работает стабильно
  
  // Вместо loopFolder лучше использовать:
  // myDFPlayer.playFolder(1, 1); // играть конкретный файл
  // или:
  // myDFPlayer.play(1); // играть трек 1
  
  delay(1000);
  myDFPlayer.next();
  
  Serial.println("DFPlayer Mini initialized!");
}

void loop()
{
  // Важно! DFPlayer требует периодического опроса
  static unsigned long timer = millis();
  
  if (millis() - timer > 100) {
    timer = millis();
    
    // Проверяем статус плеера
    if (myDFPlayer.available()) {
      printDetail(myDFPlayer.readType(), myDFPlayer.read());
    }
    
    // Проверяем, закончился ли трек
    if (!isPlaying && myDFPlayer.readState() != 0) {
      isPlaying = true;
      Serial.println("Playing started");
    }
    
    // Если трек закончился (статус 0 - остановлен)
    if (isPlaying && myDFPlayer.readState() == 0) {
      Serial.println("Track ended, starting next...");
      myDFPlayer.next(); // Запускаем следующий трек
      delay(100); // Небольшая задержка для стабильности
      isPlaying = false;
    }
  }
}

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 DFPlayerPlayFinished:
      Serial.print(F("Play Finished! File Number:"));
      Serial.println(value);
      // Явно запускаем следующий трек при окончании
      myDFPlayer.next();
      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;
  }
}

ну и что будите дальше делать ? курс проходить или за деньги каждый раз код покупать ?)))

Babos, ваш код играет только 2 трека, а потом тишина:

Короче нашлося решение.

  1. После первой загрузки нужно отключить USB и снова залить.
  2. Оказывается нужно проверять на событие окончание трека! (Если нужно добавлять там next/prev ). Вот вот.
#include "Arduino.h"
#include "DFRobotDFPlayerMini.h"

#if (defined(ARDUINO_AVR_UNO) || defined(ESP8266))
#include <SoftwareSerial.h>
SoftwareSerial softSerial(/*rx =*/8, /*tx =*/9);
#define FPSerial softSerial
#else
#define FPSerial Serial1
#endif

DFRobotDFPlayerMini myDFPlayer;

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

  if (!myDFPlayer.begin(FPSerial, true, true)) {
   
  }

  myDFPlayer.setTimeOut(500);
  myDFPlayer.volume(30);
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);

  // Если нужно бесконечно крутить все файлы в папке 01:
  myDFPlayer.loopFolder(1);

  // НЕ вызывать myDFPlayer.next() здесь без реакции на события
}

void loop() {
  // Обрабатываем входящие сообщения от DFPlayer (требуется isACK = true в begin)
  if (myDFPlayer.available()) {
    uint8_t type = myDFPlayer.readType();
    int value = myDFPlayer.read(); // или используйте read() по API вашей версии библиотеки

    // Вариант: проверяем код события окончания воспроизведения
    if (type == DFPlayerPlayFinished) {
      Serial.print(F("Track finished, value="));
      Serial.println(value);
      // Действие: перейти к следующему треку
      myDFPlayer.next();
       /*
       myDFPlayer.pause(); 
       delay(2000);
       myDFPlayer.start();
       */
    }

    
  }
}

Долго мучался с этим модулем, спасибо всем друзьям, по школе, и всем ребятам с района.