Combining 3 DFPlayers

Hi, All:

I'm trying to combine three DFPlayers. So I have wired two of them. It reads the first, but not the second. Even if I comment out the first one it still does not work. Both DFPlayers work when placed in the first slot, but doesn't when I put it in the second slot. I know in the photo that the second one has a missing sd card.

I suspect I may not have the code right.

Can someone please tell me what I'm doing wrong? Thanks!

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

SoftwareSerial twoChannelSerial(4, 5); // RX, TX
SoftwareSerial oneChannelSerial(6, 7); // RX, TX

DFRobotDFPlayerMini myDFPlayerTwo;
DFRobotDFPlayerMini myDFPlayerOne;

void printDetail(uint8_t type, int value);

void setup()
{
twoChannelSerial.begin(9600);
oneChannelSerial.begin(9700);

Serial.begin(115200);

Serial.println();
Serial.println(F("DFRobot DFPlayer Mini Demo"));
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

if (!myDFPlayerTwo.begin(twoChannelSerial)) { //Use softwareSerial to communicate with mp3.
Serial.println(F("Two Unable to begin:"));
Serial.println(F("1.Please recheck the connection!"));
Serial.println(F("2.Please insert the SD card!"));
while(true);
}
Serial.println(F("DFPlayerTwo Mini online."));

if (!myDFPlayerOne.begin(oneChannelSerial)) { //Use softwareSerial to communicate with mp3.
Serial.println(F("One Unable to begin:"));
Serial.println(F("1.Please recheck the connection!"));
Serial.println(F("2.Please insert the SD card!"));
while(true);
}
Serial.println(F("DFPlayerOne Mini online."));

myDFPlayerOne.volume(10); //Set volume value. From 0 to 30
myDFPlayerOne.play(1); //Play the first mp3
myDFPlayerTwo.volume(10); //Set volume value. From 0 to 30
myDFPlayerOne.play(1); //Play the first mp3
}

void loop()
{
static unsigned long timer = millis();

if (millis() - timer > 3000) {
timer = millis();
}

if (myDFPlayerOne.available()) {
printDetail(myDFPlayerOne.readType(), myDFPlayerOne.read()); //Print the detail message from DFPlayer to handle different errors and states.
}
}

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("Number:"));
Serial.print(value);
Serial.println(F(" Play Finished!"));
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;
}
}

 oneChannelSerial.begin(9700);

Should it be 9600 as well?

Thanks!
Ricky

serial ports have certain standard speeds, 9600 seems to be the most common. it will not clash with other serial.begin(speed) instances

ricky_c:
SoftwareSerial twoChannelSerial(4, 5); // RX, TX
SoftwareSerial oneChannelSerial(6, 7); // RX, TX

Nope, you can't use more than one instance of SoftwareSerial unless you do some extra steps in the code. See here for more details.

You might also be interested in a more optimized and much faster DFplayerMini library here.

hi,

this is my code

working with two mp3 players

#include "SoftwareSerial.h"
SoftwareSerial mySoftwareSerialA(10, 11);
SoftwareSerial mySoftwareSerialB( 8, 9);

#include "DFRobotDFPlayerMiniA.h"
DFRobotDFPlayerMiniA myDFPlayerA;

#include "DFRobotDFPlayerMiniB.h"
DFRobotDFPlayerMiniB myDFPlayerB;

void setup()
{
mySoftwareSerialA.begin(9600);
if (!myDFPlayerA.begin(mySoftwareSerialA))
{
Serial.println(F("Nao inicializado:"));
Serial.println(F("1.Cheque as conexoes do DFPlayer Mini"));
Serial.println(F("2.Insira um cartao SD"));
while (true);
}
myDFPlayerA.setTimeOut(500); //Timeout serial 500ms
myDFPlayerA.EQ(DFPLAYER_EQ_BASS);
myDFPlayerA.outputDevice(DFPLAYER_DEVICE_SD);
myDFPlayerA.volume(15);

mySoftwareSerialB.begin(9600);
if (!myDFPlayerB.begin(mySoftwareSerialB))
{
Serial.println(F("Nao inicializado:"));
Serial.println(F("1.Cheque as conexoes do DFPlayer Mini"));
Serial.println(F("2.Insira um cartao SD"));
while (true);
}
myDFPlayerB.setTimeOut(500); //Timeout serial 500ms
myDFPlayerB.EQ(DFPLAYER_EQ_BASS);
myDFPlayerB.outputDevice(DFPLAYER_DEVICE_SD);
myDFPlayerB.volume(15);
}

void loop()
{

myDFPlayerA.playMp3Folder(1);
delay(800);
myDFPlayerB.playMp3Folder(2);
delay(800);

}

bye

  • @file DFRobotDFPlayerMiniA.h
  • @brief DFPlayer - An Arduino Mini MP3 Player From DFRobot
  • @n Header file for DFRobot's DFPlayer
  • @copyright DFRobot, 2016
  • @copyright GNU Lesser General Public License
  • @author Angelo
  • @version V1.0.3
  • @date 2016-12-07
    */

#include "Arduino.h"

#ifndef DFRobotDFPlayerMiniA_cpp
#define DFRobotDFPlayerMiniA_cpp

#define DFPLAYER_EQ_NORMAL 0
#define DFPLAYER_EQ_POP 1
#define DFPLAYER_EQ_ROCK 2
#define DFPLAYER_EQ_JAZZ 3
#define DFPLAYER_EQ_CLASSIC 4
#define DFPLAYER_EQ_BASS 5

#define DFPLAYER_DEVICE_U_DISK 1
#define DFPLAYER_DEVICE_SD 2
#define DFPLAYER_DEVICE_AUX 3
#define DFPLAYER_DEVICE_SLEEP 4
#define DFPLAYER_DEVICE_FLASH 5

#define DFPLAYER_RECEIVED_LENGTH 10
#define DFPLAYER_SEND_LENGTH 10

//#define _DEBUG

#define TimeOut 0
#define WrongStack 1
#define DFPlayerCardInserted 2
#define DFPlayerCardRemoved 3
#define DFPlayerCardOnline 4
#define DFPlayerPlayFinished 5
#define DFPlayerError 6
#define DFPlayerUSBInserted 7
#define DFPlayerUSBRemoved 8
#define DFPlayerUSBOnline 9
#define DFPlayerCardUSBOnline 10
#define DFPlayerFeedBack 11

#define Busy 1
#define Sleeping 2
#define SerialWrongStack 3
#define CheckSumNotMatch 4
#define FileIndexOut 5
#define FileMismatch 6
#define Advertise 7

#define Stack_Header 0
#define Stack_Version 1
#define Stack_Length 2
#define Stack_Command 3
#define Stack_ACK 4
#define Stack_Parameter 5
#define Stack_CheckSum 7
#define Stack_End 9

class DFRobotDFPlayerMiniA {
Stream* _serial;

unsigned long _timeOutTimer;
unsigned long _timeOutDuration = 500;

uint8_t _received[DFPLAYER_RECEIVED_LENGTH];
uint8_t _sending[DFPLAYER_SEND_LENGTH] = {0x7E, 0xFF, 06, 00, 01, 00, 00, 00, 00, 0xEF};

uint8_t _receivedIndex=0;

void sendStack();
void sendStack(uint8_t command);
void sendStack(uint8_t command, uint16_t argument);
void sendStack(uint8_t command, uint8_t argumentHigh, uint8_t argumentLow);

void enableACK();
void disableACK();

void uint16ToArray(uint16_t value,uint8_t *array);

uint16_t arrayToUint16(uint8_t *array);

uint16_t calculateCheckSum(uint8_t *buffer);

void parseStack();
bool validateStack();

uint8_t device = DFPLAYER_DEVICE_SD;

public:

uint8_t _handleType;
uint8_t _handleCommand;
uint16_t _handleParameter;
bool _isAvailable = false;
bool _isSending = false;

bool handleMessage(uint8_t type, uint16_t parameter = 0);
bool handleError(uint8_t type, uint16_t parameter = 0);

uint8_t readCommand();

bool begin(Stream& stream, bool isACK = true, bool doReset = true);

bool waitAvailable(unsigned long duration = 0);

bool available();

uint8_t readType();

uint16_t read();

void setTimeOut(unsigned long timeOutDuration);

void next();

void previous();

void play(int fileNumber=1);

void volumeUp();

void volumeDown();

void volume(uint8_t volume);

void EQ(uint8_t eq);

void loop(int fileNumber);

void outputDevice(uint8_t device);

void sleep();

void reset();

void start();

void pause();

void playFolder(uint8_t folderNumber, uint8_t fileNumber);

void outputSetting(bool enable, uint8_t gain);

void enableLoopAll();

void disableLoopAll();

void playMp3Folder(int fileNumber);

void advertise(int fileNumber);

void playLargeFolder(uint8_t folderNumber, uint16_t fileNumber);

void stopAdvertise();

void stop();

void loopFolder(int folderNumber);

void randomAll();

void enableLoop();

void disableLoop();

void enableDAC();

void disableDAC();

int readState();

int readVolume();

int readEQ();

int readFileCounts(uint8_t device);

int readCurrentFileNumber(uint8_t device);

int readFileCountsInFolder(int folderNumber);

int readFileCounts();

int readFolderCounts();

int readCurrentFileNumber();

};

#endif

CONTINUE.... LIMIT 9K CARACTERS

CREATE too files DFRobotDFPlayerMiniB.cpp and DFRobotDFPlayerMiniB.h in folder DFRobotDFPlayerMiniB

change letters "A" the example to "B"

sorry my english

/*!

  • @file DFRobotDFPlayerMiniA.cpp
  • @brief DFPlayer - An Arduino Mini MP3 Player From DFRobot
  • @n Header file for DFRobot's DFPlayer
  • @copyright DFRobot, 2016
  • @copyright GNU Lesser General Public License
  • @author Angelo
  • @version V1.0.3
  • @date 2016-12-07
    */

#include "DFRobotDFPlayerMiniA.h"

void DFRobotDFPlayerMiniA::setTimeOut(unsigned long timeOutDuration){
_timeOutDuration = timeOutDuration;
}

void DFRobotDFPlayerMiniA::uint16ToArray(uint16_t value, uint8_t *array){
*array = (uint8_t)(value>>8 );
*(array+1) = (uint8_t)(value);
}

uint16_t DFRobotDFPlayerMiniA::calculateCheckSum(uint8_t buffer){
uint16_t sum = 0;
for (int i=Stack_Version; i<Stack_CheckSum; i++) {
sum += buffer
;*
}
return -sum;
}
void DFRobotDFPlayerMiniA::sendStack(){
if (_sending[Stack_ACK]) { //if the ack mode is on wait until the last transmition

  • while (_isSending) {*
  • delay(0);*
  • available();*
  • }*
    }
    #ifdef _DEBUG
    Serial.println();
    Serial.print(F("sending:"));
    for (int i=0; i<DFPLAYER_SEND_LENGTH; i++) {
    Serial.print(sending*,HEX);
    _
    Serial.print(F(" "));*

    }
    Serial.println();
    #endif
    _serial->write(_sending, DFPLAYER_SEND_LENGTH);
    _timeOutTimer = millis();
    _isSending = _sending[Stack_ACK];

if (!_sending[Stack_ACK]) { //if the ack mode is off wait 10 ms after one transmition.
* delay(10);*
}
}
void DFRobotDFPlayerMiniA::sendStack(uint8_t command){
sendStack(command, 0);
}
void DFRobotDFPlayerMiniA::sendStack(uint8_t command, uint16_t argument){
_sending[Stack_Command] = command;
uint16ToArray(argument, _sending+Stack_Parameter);
uint16ToArray(calculateCheckSum(_sending), _sending+Stack_CheckSum);
sendStack();
}
void DFRobotDFPlayerMiniA::sendStack(uint8_t command, uint8_t argumentHigh, uint8_t argumentLow){
uint16_t buffer = argumentHigh;
buffer <<= 8;
sendStack(command, buffer | argumentLow);
}
void DFRobotDFPlayerMiniA::enableACK(){
_sending[Stack_ACK] = 0x01;
}
void DFRobotDFPlayerMiniA::disableACK(){
_sending[Stack_ACK] = 0x00;
}
bool DFRobotDFPlayerMiniA::waitAvailable(unsigned long duration){
unsigned long timer = millis();
if (!duration) {
* duration = timeOutDuration;
_
}*

while (!available()){
* if (millis() - timer > duration) {*
* return false;*
* }*
* delay(0);*
}
return true;
}
bool DFRobotDFPlayerMiniA::begin(Stream &stream, bool isACK, bool doReset){
_serial = &stream;

if (isACK) {
* enableACK();*
}
else{
* disableACK();*
}

continue.... limit 9k caracters

continuing.....

if (doReset) {
reset();
waitAvailable(2000);
delay(200);
}
else {
// assume same state as with reset(): online
_handleType = DFPlayerCardOnline;
}

return (readType() == DFPlayerCardOnline) || (readType() == DFPlayerUSBOnline) || !isACK;
}

uint8_t DFRobotDFPlayerMiniA::readType(){
_isAvailable = false;
return _handleType;
}

uint16_t DFRobotDFPlayerMiniA::read(){
_isAvailable = false;
return _handleParameter;
}

bool DFRobotDFPlayerMiniA::handleMessage(uint8_t type, uint16_t parameter){
_receivedIndex = 0;
_handleType = type;
_handleParameter = parameter;
_isAvailable = true;
return _isAvailable;
}

bool DFRobotDFPlayerMiniA::handleError(uint8_t type, uint16_t parameter){
handleMessage(type, parameter);
_isSending = false;
return false;
}

uint8_t DFRobotDFPlayerMiniA::readCommand(){
_isAvailable = false;
return _handleCommand;
}

void DFRobotDFPlayerMiniA::parseStack(){
uint8_t handleCommand = *(_received + Stack_Command);
if (handleCommand == 0x41) { //handle the 0x41 ack feedback as a spcecial case, in case the pollusion of _handleCommand, _handleParameter, and _handleType.
_isSending = false;
return;
}

_handleCommand = handleCommand;
_handleParameter = arrayToUint16(_received + Stack_Parameter);

switch (_handleCommand) {
case 0x3D:
handleMessage(DFPlayerPlayFinished, _handleParameter);
break;
case 0x3F:
if (_handleParameter & 0x01) {
handleMessage(DFPlayerUSBOnline, _handleParameter);
}
else if (_handleParameter & 0x02) {
handleMessage(DFPlayerCardOnline, _handleParameter);
}
else if (_handleParameter & 0x03) {
handleMessage(DFPlayerCardUSBOnline, _handleParameter);
}
break;
case 0x3A:
if (_handleParameter & 0x01) {
handleMessage(DFPlayerUSBInserted, _handleParameter);
}
else if (_handleParameter & 0x02) {
handleMessage(DFPlayerCardInserted, _handleParameter);
}
break;
case 0x3B:
if (_handleParameter & 0x01) {
handleMessage(DFPlayerUSBRemoved, _handleParameter);
}
else if (_handleParameter & 0x02) {
handleMessage(DFPlayerCardRemoved, _handleParameter);
}
break;
case 0x40:
handleMessage(DFPlayerError, _handleParameter);
break;
case 0x3C:
case 0x3E:
case 0x42:
case 0x43:
case 0x44:
case 0x45:
case 0x46:
case 0x47:
case 0x48:
case 0x49:
case 0x4B:
case 0x4C:
case 0x4D:
case 0x4E:
case 0x4F:
handleMessage(DFPlayerFeedBack, _handleParameter);
break;
default:
handleError(WrongStack);
break;
}
}

uint16_t DFRobotDFPlayerMiniA::arrayToUint16(uint8_t *array){
uint16_t value = *array;
value <<=8;
value += *(array+1);
return value;
}

bool DFRobotDFPlayerMiniA::validateStack(){
return calculateCheckSum(_received) == arrayToUint16(_received+Stack_CheckSum);
}

bool DFRobotDFPlayerMiniA::available(){
while (_serial->available()) {
delay(0);
if (_receivedIndex == 0) {
_received[Stack_Header] = _serial->read();
#ifdef _DEBUG
Serial.print(F("received:"));
Serial.print(_received[_receivedIndex],HEX);
Serial.print(F(" "));
#endif
if (_received[Stack_Header] == 0x7E) {
_receivedIndex ++;
}
}
else{
_received[_receivedIndex] = _serial->read();
#ifdef _DEBUG
Serial.print(_received[_receivedIndex],HEX);
Serial.print(F(" "));
#endif
switch (_receivedIndex) {
case Stack_Version:
if (_received[_receivedIndex] != 0xFF) {
return handleError(WrongStack);
}
break;
case Stack_Length:
if (_received[_receivedIndex] != 0x06) {
return handleError(WrongStack);
}
break;
case Stack_End:
#ifdef _DEBUG
Serial.println();
#endif
if (_received[_receivedIndex] != 0xEF) {
return handleError(WrongStack);
}
else{
if (validateStack()) {
_receivedIndex = 0;
parseStack();
return _isAvailable;
}
else{
return handleError(WrongStack);
}
}
break;
default:
break;
}
_receivedIndex++;
}
}

if (_isSending && (millis()-_timeOutTimer>=_timeOutDuration)) {
return handleError(TimeOut);
}

return _isAvailable;
}

void DFRobotDFPlayerMiniA::next(){
sendStack(0x01);
}

void DFRobotDFPlayerMiniA::previous(){
sendStack(0x02);
}

void DFRobotDFPlayerMiniA::play(int fileNumber){
sendStack(0x03, fileNumber);
}

void DFRobotDFPlayerMiniA::volumeUp(){
sendStack(0x04);
}

void DFRobotDFPlayerMiniA::volumeDown(){
sendStack(0x05);
}

void DFRobotDFPlayerMiniA::volume(uint8_t volume){
sendStack(0x06, volume);
}

void DFRobotDFPlayerMiniA::EQ(uint8_t eq) {
sendStack(0x07, eq);
}

void DFRobotDFPlayerMiniA::loop(int fileNumber) {
sendStack(0x08, fileNumber);
}

void DFRobotDFPlayerMiniA::outputDevice(uint8_t device) {
sendStack(0x09, device);
delay(200);
}

void DFRobotDFPlayerMiniA::sleep(){
sendStack(0x0A);
}

void DFRobotDFPlayerMiniA::reset(){
sendStack(0x0C);
}

void DFRobotDFPlayerMiniA::start(){
sendStack(0x0D);
}

void DFRobotDFPlayerMiniA::pause(){
sendStack(0x0E);
}

void DFRobotDFPlayerMiniA::playFolder(uint8_t folderNumber, uint8_t fileNumber){
sendStack(0x0F, folderNumber, fileNumber);
}

void DFRobotDFPlayerMiniA::outputSetting(bool enable, uint8_t gain){
sendStack(0x10, enable, gain);
}

void DFRobotDFPlayerMiniA::enableLoopAll(){
sendStack(0x11, 0x01);
}

void DFRobotDFPlayerMiniA::disableLoopAll(){
sendStack(0x11, 0x00);
}

void DFRobotDFPlayerMiniA::playMp3Folder(int fileNumber){
sendStack(0x12, fileNumber);
}

void DFRobotDFPlayerMiniA::advertise(int fileNumber){
sendStack(0x13, fileNumber);
}

void DFRobotDFPlayerMiniA::playLargeFolder(uint8_t folderNumber, uint16_t fileNumber){
sendStack(0x14, (((uint16_t)folderNumber) << 12) | fileNumber);
}

void DFRobotDFPlayerMiniA::stopAdvertise(){
sendStack(0x15);
}

void DFRobotDFPlayerMiniA::stop(){
sendStack(0x16);
}

void DFRobotDFPlayerMiniA::loopFolder(int folderNumber){
sendStack(0x17, folderNumber);
}

void DFRobotDFPlayerMiniA::randomAll(){
sendStack(0x18);
}

void DFRobotDFPlayerMiniA::enableLoop(){
sendStack(0x19, 0x00);
}

continue... limit caracters

continuing....

void DFRobotDFPlayerMiniA::disableLoop(){
sendStack(0x19, 0x01);
}

void DFRobotDFPlayerMiniA::enableDAC(){
sendStack(0x1A, 0x00);
}

void DFRobotDFPlayerMiniA::disableDAC(){
sendStack(0x1A, 0x01);
}

int DFRobotDFPlayerMiniA::readState(){
sendStack(0x42);
if (waitAvailable()) {
if (readType() == DFPlayerFeedBack) {
return read();
}
else{
return -1;
}
}
else{
return -1;
}
}

int DFRobotDFPlayerMiniA::readVolume(){
sendStack(0x43);
if (waitAvailable()) {
return read();
}
else{
return -1;
}
}

int DFRobotDFPlayerMiniA::readEQ(){
sendStack(0x44);
if (waitAvailable()) {
if (readType() == DFPlayerFeedBack) {
return read();
}
else{
return -1;
}
}
else{
return -1;
}
}

int DFRobotDFPlayerMiniA::readFileCounts(uint8_t device){
switch (device) {
case DFPLAYER_DEVICE_U_DISK:
sendStack(0x47);
break;
case DFPLAYER_DEVICE_SD:
sendStack(0x48);
break;
case DFPLAYER_DEVICE_FLASH:
sendStack(0x49);
break;
default:
break;
}

if (waitAvailable()) {
if (readType() == DFPlayerFeedBack) {
return read();
}
else{
return -1;
}
}
else{
return -1;
}
}

int DFRobotDFPlayerMiniA::readCurrentFileNumber(uint8_t device){
switch (device) {
case DFPLAYER_DEVICE_U_DISK:
sendStack(0x4B);
break;
case DFPLAYER_DEVICE_SD:
sendStack(0x4C);
break;
case DFPLAYER_DEVICE_FLASH:
sendStack(0x4D);
break;
default:
break;
}
if (waitAvailable()) {
if (readType() == DFPlayerFeedBack) {
return read();
}
else{
return -1;
}
}
else{
return -1;
}
}

int DFRobotDFPlayerMiniA::readFileCountsInFolder(int folderNumber){
sendStack(0x4E, folderNumber);
if (waitAvailable()) {
if (readType() == DFPlayerFeedBack) {
return read();
}
else{
return -1;
}
}
else{
return -1;
}
}

int DFRobotDFPlayerMiniA::readFolderCounts(){
sendStack(0x4F);
if (waitAvailable()) {
if (readType() == DFPlayerFeedBack) {
return read();
}
else{
return -1;
}
}
else{
return -1;
}
}

int DFRobotDFPlayerMiniA::readFileCounts(){
return readFileCounts(DFPLAYER_DEVICE_SD);
}

int DFRobotDFPlayerMiniA::readCurrentFileNumber(){
return readCurrentFileNumber(DFPLAYER_DEVICE_SD);
}

bye

sorry multiplys posts. limit caracters.

@jhugor - Wtf? You can easily post a zip containing your files instead of taking up literally 5 posts with little more than library contents.

In any event, that's a rather ridiculous way of getting it to work. A much easier and elegant solution would be to call swserialport.listen() before each function call of the ORIGINAL DFPlayer library.

Does this make sense?