nk25719 / PMD___aka-KiCad-esp32-6leds-2switches-1pj-circuit-

In this repo I am practicing KICAD. Created an ESP32 DevKit V1 module and a PCB footprint. I designed a circuit around this ESP32 consisting of six lamps, four switches, and two power jacks and added a voltage regulater to Vin to maintain a supply of +5V. (This project was originally made of two switches and 1 power jack and was named homeWork2.)
0 stars 1 forks source link

Hardware Bug, DFPLayer TX Line Stopped Responding #55

Closed ForrestErickson closed 2 days ago

ForrestErickson commented 3 weeks ago

Describe the Failure / Bug A clear and concise description of what the failure / bug is. Short Summary of the expected behavior: Short Summary of the buggy behavior:

Lee was working with the DFPlayer on the MockingKrakeUSA1 and had noted that the DFPlayer responded to the ESP32 serial signal after less than 5mS delay image

However afternoon of 20240922 Lee found the DFPlayer unresponsive to the ESP signal. image

Device Under Test, aka DUT Steps to reproduce the behavior:

  1. Model Number: MokingKrake
  2. Serial Number(s): USA1
  3. Location where failure / bug occurred. Lee's work bench after some experimenting with firmware.
  4. Hardware configuration. (How connected, any accessories, what else it takes to replicate the system in which the failure occurred.) The DFPlayer did NOT have an SD card in it. Some of the firmware with which Lee experimented had the halting code on failure to find the SD card removed.
  5. Extent of Failure Is failure intermittent? NO. It is solid failure. Is failure fixed by power cycling? YES. ** Is failure permanent? NO

To Reproduce Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior A clear and concise description of what you expected to happen.

Screenshots If applicable, add screenshots to help explain your problem.

**Hardware description Model: Serial Number: Other:

**Test Equipment Model: Oscilloscope connected to the DFPlayer RX and TX pins. Scope triggered on the RX pin (the ESP32 TX) Serial Number:

Additional context Add any other context about the problem here.

ForrestErickson commented 3 weeks ago

More testing. I got the DFPlayer unresponsive again. Pressing reset alont did not clear the error.

Removing power from just the DFPlayer and then pressing reset and the DFPlayer was again responsive.

This screen shot of the serial port shows an initial failure to start the DFPlayer but then success. image

Lee concludes that the command "myDFPlayer.begin(mySerial1)" does not recover an unresponsive DFPlayer.

ForrestErickson commented 3 weeks ago

Lee found that after a reset the DFPlayer was unresponsive.

The way to reproduce the failure was simply to press reset. The firmware under test was: Krake_arduinoIDE_V2 modified with the DFPlayer commands moved before the WiFI.

ForrestErickson commented 3 weeks ago

@nk25719

Here is the DFPlayer resource I found https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299

Genuine DF Robot DFPlayer https://www.amazon.com/DFPlayer-A-Mini-MP3-Player/dp/B089D5NLW1/ref=sr_1_1 Photo showing the IC is DFRobot branded image

ForrestErickson commented 2 weeks ago

Hardware in Maryville

Here is the exact part Lee purchased: https://www.amazon.com/gp/product/B07Y2YKYRS
image
Brand UMLIFE

Reading product reviews at Amazon there are some negative reviews indicating that although the module works by switches on IO_1 and IO_2 commands through the UART did not work.

5.0 out of 5 stars Great low cost DIY solution! Reviewed in the United States on January 21, 2023 Color: 3PCS MP3 ModuleVerified Purchase The most BASIC function: grounding pin IO_1 or IO_2 for play next or previous. Longer ground adjusts volume fine. Haven't tried using a library to program my Arduino and ATtiny85 for specific file play yet, but need to soon.

The amp function works great with speaker positive to SPK_1, and negative on SPK_2 pins for mono audio on my 4 ohm 3 amp speaker in project box.

MicroSD cards hold snug in slot and haven't popped out.

Lee found that grounding IO_1 did indeed cause the speaker to play.

Photo of TD5580A

image

Tentative Conclusion, DFRobot Library Incompatibility with TD5580A

The commands throught UART are not compatible with the DFPLayer library from DFRobot. https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299#target_7

ForrestErickson commented 2 weeks ago

Lee has asked Facebook group for help on the TD5580A integrated circuit DFPlayer: https://www.facebook.com/groups/1606743019578078

ForrestErickson commented 2 weeks ago

Facebook came back with a suggestion:

``` Jonathan DeWitt Forrest Erickson back in 2022 I tried to save a little money by buying 10 knockoff DFPlayer Mini boards from AliExpress. I'm not certain if yours are the same (they probably are). I was not able to get them to work until a gentlemen named Simon Coward on the Arduino for Beginners Facebook group provided me some code. Here is that code: //This code was provided by Simon Coward of the Arduino for Beginners Facebook group on 12/21/2022 and is meant to test a DFPlayer Mini knockoff //this function sends the actual command //It receives the command byte and ParData is optional info such as track number or volume depending on the command void sendDFCommand(byte Command, int ParData) { //Start of sendDFCommand function definition byte commandData[10]; //This holds all the command data to be sent byte q; int checkSum; Serial.print("Com: "); Serial.print(Command, HEX); //Each command value is being sent in Hexadecimal commandData[0] = 0x7E;//Start of new command commandData[1] = 0xFF;//Version information commandData[2] = 0x06;//Data length (not including parity) or the start and version commandData[3] = Command;//The command that was sent through commandData[4] = 0x01;//1 = feedback commandData[5] = highByte(ParData);//High byte of the data sent over commandData[6] = lowByte(ParData);//low byte of the data sent over checkSum = -(commandData[1] + commandData[2] + commandData[3] + commandData[4] + commandData[5] + commandData[6]); commandData[7] = highByte(checkSum);//High byte of the checkSum commandData[8] = lowByte(checkSum);//low byte of the checkSum commandData[9] = 0xEF;//End bit for (q = 0; q < 10; q++) { Serial3.write(commandData[q]); } Serial.println("Command Sent: "); for (q = 0; q < 10; q++) { Serial.println(commandData[q],HEX); } Serial.println("End Command: "); delay(100); } //End of sendDFCommand function definition //play a specific track number void playTrack(int tracknum){ Serial.print("Track selected: "); Serial.println(tracknum); sendDFCommand(0x03, tracknum); } //plays the next track void playNext(){ Serial.println("Play Next"); sendDFCommand(0x01, 0); } //volume increase by 1 void volumeUp() { Serial.println("Vol UP"); sendDFCommand(0x04, 0); } //volume decrease by 1 void volumeDown() { Serial.println("Vol Down"); sendDFCommand(0x05, 0); } //set volume to specific value void changeVolume(int thevolume) { sendDFCommand(0x06, thevolume); } void setup() { Serial.begin(9600); Serial.println("DFPlayerMegaV2"); Serial3.begin (9600);//start the softwareSerial to DF player delay(3500);//let everything initialise changeVolume(10);//set volume to 20....30 is very loud even on small speaker. } int q = 1; void loop() { //Uncomment just to play through tracks one after another. //playNext(); //delay(2000); //Uncomment to play through a set of track for(q=1;q<22;q++){ playTrack(q); delay(2000); } }

ForrestErickson commented 2 weeks ago

Lee got DFRobot code working by adding delays.

Example:

/*
   File: DFPlayerTD5580ATest
   Author: Forrest Lee Erickson
   Date: 20240929
*/

#define COMPANY_NAME "pubinv.org "
#define PROG_NAME "DFPlayerTD5580ATest "
#define VERSION "V0.1 "
#define DEVICE_UNDER_TEST "PMD: LCD and DFPlayer"  //A PMD model number
#define LICENSE "GNU Affero General Public License, version 3 "
#define ORIGIN "USA"

#define BAUDRATE 115200
#define BAUD_DFPLAYER 9600

#include <DFRobotDFPlayerMini.h>

// Create a SoftwareSerial object with RX and TX pins
//SoftwareSerial mySerial(16, 17); // RX, TX

HardwareSerial mySerial1(2);  // Use UART2
DFRobotDFPlayerMini dfPlayer;

const int LED_PIN = 2; // ESP32 LED
const int LED_D6 = 23; // ESP32 GPIO23 pin 16 on kit.

const int trac1 = 1;
const int trac2 = 2;

//Functions
void setupDFPlayer() {
  //  Setup UART for DFPlayer
  Serial.println("UART2 Begin");
  mySerial1.begin(BAUD_DFPLAYER, SERIAL_8N1, 16, 17);
  while (!mySerial1) {
    ; // wait for DFPlayer serial port to connect.
  }
  // Essential Initialize of DFPlayer Mini
  Serial.println("DFPlayer begin with ACK and Reset");
  dfPlayer.begin(mySerial1, true, true); // (Stream &stream, bool isACK, bool doReset)

//  delay(30);
//  Serial.println("Reset DFPlayer.");
  dfPlayer.reset();
  delay(3000);
  Serial.println("Begin DFPlayer again.");
  if (!dfPlayer.begin(mySerial1, true, true)) {
    Serial.println("DFPlayer Mini not detected or not working.");
    while (true); // Stop execution
  }
  Serial.println("DFPlayer Mini detected!");

  delay(3000);  //Required for volum to set
  //  // Set volume (0 to 30)
//  dfPlayer.volume(30);       // Set initial volume max
  dfPlayer.volume(1);       // Set initial volume low
  delay(3000);
  Serial.print("Volume is set to: ");
  digitalWrite(LED_D6, HIGH); //Start of volume read.
  Serial.println(dfPlayer.readVolume());           //Causes program lock up  
  digitalWrite(LED_D6, LOW); //End of volume read.

  dfPlayer.setTimeOut(500);  // Set serial communictaion time out 500ms
  delay(100);

  //  dfPlayer.EQ(0);          // Normal equalization //Causes program lock up  

}//setupDFPLayer

void setup() {
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  pinMode(LED_D6, OUTPUT);
  digitalWrite(LED_D6, LOW); //Start out low

  // Start serial communication
  Serial.begin(BAUDRATE);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB
  }
  delay(500);
  Serial.println("===================================");
  Serial.println(DEVICE_UNDER_TEST);
  Serial.print(PROG_NAME);
  Serial.println(VERSION);
  Serial.print("Compiled at: ");
  Serial.println(F(__DATE__ " " __TIME__) ); //compile date that is used for a unique identifier
  Serial.println("===================================");
  Serial.println();

  setupDFPlayer();

  Serial.println("End of setup");
  digitalWrite(LED_PIN, LOW);
}// end of setup()

void loop() {
  Serial.println("Play a track");
  dfPlayer.play(1);
  delay(2000);
  Serial.println("Play MP3 folder");
  dfPlayer.playMp3Folder(1);
  delay(2000);

}// end of loop()
ForrestErickson commented 2 weeks ago

Code zipped: DFPlayerTD5580ATest.zip

Screen shot of the UART traffic of the working "dfPlayer.readVolume()" command. image

ForrestErickson commented 2 weeks ago

@nk25719 When I have more energy I hope to review the Krake code for what delays (eventualy using mills() ) may be required for compatibility with the TD5580A based DFPlayer.

ForrestErickson commented 2 weeks ago

This bug was discovered to be a TD5580A characteristic. It is probably caused by sending multiple commands to the DFPlayer with inadequate delay between commands. The DFPlayer became unresponsive until a power reset of the TD5580A.

A firm ware method of recover from the unresponsive state was developed in: Hardware Bug, DFPLayer TX Line Stopped Responding #55 of the https://github.com/nk25719/KiCad-esp32-6leds-2switches-1pj-circuit repository.

https://github.com/nk25719/KiCad-esp32-6leds-2switches-1pj-circuit/issues/55

ForrestErickson commented 2 weeks ago

Notes useful for understanding the speed at which the DFPlayer can be written: From the library file, "DFRobotDFPlayerMini.h" these functions return a value so finding how fast they can be called and return a valid value will give insight. image

Functions:

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();

ForrestErickson commented 2 weeks ago

@nk25719 Robert,

There are six libraries in the Arduino IDE library manager referencing DFPlayers
image

THe DFPLayerMini_Fast is one about which I read in an Arduino forum where the author explained some of his motivation and goals. See: https://forum.arduino.cc/t/dfplayer-without-delay/612757 I think it might useful for us all to review that forum discussion together.

I believe we will need to write stand alone programs(s) to learn the functionality of the DFPlayer on what ever library we choose.

ForrestErickson commented 2 weeks ago

This additional Arduino forum post by the author of the "DFPlayerMini_Fast" library is also insightful: https://forum.arduino.cc/t/new-and-improved-dfplayer-mini-library/492914/18

While perhaps specific to this library, there is intriguing (and useful?) discussion of naming conventions for tracks (the audio files).

See for example:

Dec 2019post #38 1.) Filenames do not matter - the track numbers with respect to the library are based solely on the order in which the files were saved to the SD card 2.) The folder structure of the SD card matters. Tbh, I forget exactly how it's supposed to be structured (I think you need to save all of your MP3s to a folder named "mp3" in the root directory)

ForrestErickson commented 2 days ago

I think the root cause of this was sending commands to the DFPlayer too fast. Unfortunately there is no specification for how much time needs to be between commands.

We should find a way in firmware to detect an non responsive DFPlayer and reset if (if possible).

Closing this issue (but will open another more descriptive issue).