MFRC522 + DFPlayer + WiFi AP

Hello together,

Trying to make small project with RFID, DFPlayer and WIFI AP.

My problem is, if I reconect my ESP32-WROOM-32 to the USB, then after not always my DFPlayer works. I need to RST or again and again reconnect.

Connections:
RFID
SDA -> G5
SCK -> G18
MOSI -> G23
MISO -> G19
GND -> GND (separate)
RST -> G15
3.3V -> 3.3V

DFPlayer
VCC -> 5V
RX -> G26
TX -> G27
SPK1 -> SPK -
GND -> GND (separate)
SPK2 -> SPK +

Here is my code:

#include <SPI.h>                  // Include SPI library for RFID communication
#include <MFRC522.h>              // Include MFRC522 library for RFID
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
//Webserver
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Wire.h>
// RFID pins
#define SS_PIN 5                 // Define Slave Select pin for RFID
#define RST_PIN 15                 // Define Reset pin for RFID - was 2?
#define BatteryPin 35                 // Define pin for Battery

// Use pins 2 and 3 to communicate with DFPlayer Mini
static const uint8_t PIN_MP3_TX = 26; // Connects to module's RX  26
static const uint8_t PIN_MP3_RX = 27; // Connects to module's TX  27
SoftwareSerial softwareSerial(PIN_MP3_RX, PIN_MP3_TX);
//
MFRC522 rfid(SS_PIN, RST_PIN);    // Create MFRC522 instance with defined SS and RST pins
// Create the Player object
DFRobotDFPlayerMini player;
// GPIO
const int LED1 = 21; // RED
const int LED2 = 12; // GREEN
const int Button1 = 14; //
//DFPlayer + RFID
long randNumber;
int randNr;
String cardRFID = "";
int wrong = 0;
int volume = 20;
bool chooseON = 0;
bool colorsON = 0;
// Battery Status
int value = 0;
float voltage;
float perc;
float voltageLevel;
const float MAX_BATTERY_VOLTAGE = 4.2; //4.2
// WifiAP Data
const char* ssid = "ESP32";  
const char* password = "12345678"; 
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
WebServer server(80);
uint8_t LED1pin = 0;      // delete!
bool LED1status = LOW;     // delete!
uint8_t LED2pin = 0;      // delete!
bool LED2status = LOW;     // delete!
//

// -----------|------|--------|------ Setup -------|---------|-----------|--------- //
// -----------V------V--------V--------------------V---------V-----------V--------- //

void setup() {
  Serial.begin(115200);                                 // Start serial communication at 9600 baud rate
  // ------------------------------- Initialize RFID ------------------------------- //
  SPI.begin();                                        // Initiate SPI bus
  rfid.PCD_Init();                                    // Initiate MFRC522 RFID module
  // ------------------------------- Init serial port for DFPlayer Mini ------------------------------- //
  softwareSerial.begin(9600);
  if (player.begin(softwareSerial)) {
    Serial.println("OK");
    player.volume(volume);                            // Set volume to maximum (0 to 30).
    player.readVolume();
  } else {
    Serial.println("Connecting to DFPlayer Mini failed!");
  }
  // ------------------------------- GPIO IN/OUT ------------------------------- //
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(Button1, INPUT_PULLUP);
  // ------------------------------- WiFi Setup ------------------------------- //
  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  delay(100);
  server.on("/", handle_OnConnect);
  server.on("/led1on", handle_led1on);
  server.on("/led1off", handle_led1off);
  server.on("/led2on", handle_led2on);
  server.on("/led2off", handle_led2off);
  server.onNotFound(handle_NotFound);
  server.begin();
  Serial.println("HTTP server started");
  if(!MDNS.begin("toy")){
    Serial.println("Error setting up MDNS responder!");
    while(1){
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");
  digitalWrite(LED1, HIGH);
}

// -----------|------|--------|------ Functions -------|---------|-----------|--------- //
// -----------V------V--------V------------------------V---------V-----------V--------- //

// ------------------------------- Battery Status ------------------------------- //
void batteryStatusf(){
value = analogRead(BatteryPin);
voltageLevel = (value / 4095.0) * 2 * 1.1 * 3.3; // calculate voltage level
float batteryFraction = voltageLevel / MAX_BATTERY_VOLTAGE;
perc =  batteryFraction*100;
}
// ------------------------------- Choose between diffetent games ------------------------------- //
void choosef(){  
  if (colorsON == 1)
  {
    chooseON = 1;
  }
}
// ------------------------------- Random function ------------------------------- //
void randomf() {                                    //to awoid the same numbers in sequence
    int newNr, oldNr;
    oldNr = randNr;
    randNr = random(4,7);
    newNr = randNr;
        if (newNr == oldNr){
        randNr = random(4,7);
    }
}
// ------------------------------- Play function ------------------------------- //
void playf(){                                       //playing different mp3 depends on random number
    randomf();
    Serial.print("randomNumber: ");
    Serial.println(randNr);
if (randNr == 4){
        cardRFID = "43 C9 EE 34";
        Serial.print("rfid string wrote: ");
        Serial.println(cardRFID); 
        player.volume(volume);
        player.play(4);
        delay(1000);
        Serial.print("Play done: ");
        Serial.println(randNr);    
      }
     if (randNr == 5){
        cardRFID  = "83 73 57 20";
        Serial.print("rfid string wrote: ");
        Serial.println(cardRFID);
        player.volume(volume);
        player.play(5);
        delay(1000);
        Serial.print("Play done: ");
        Serial.println(randNr);    
      }
      if (randNr == 6){
        cardRFID = "53 79 0A 14";
        Serial.print("rfid string wrote: ");
        Serial.println(cardRFID);
        player.volume(volume);
        player.play(6);
        delay(1000);
        Serial.print("Play done: ");
        Serial.println(randNr);    
      } 
  }
// ------------------------------- Webserver Functions ????  ------------------------------- //
void handle_OnConnect() {
  LED1status = LOW;
  LED2status = LOW;
  Serial.println("GPIO4 Status: OFF | GPIO5 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED2status)); 
  }
void handle_led1on() {
  LED1status = HIGH;
  Serial.println("GPIO4 Status: ON");
  server.send(200, "text/html", SendHTML(true,LED2status)); 
}
void handle_led1off() {
  LED1status = LOW;
  Serial.println("GPIO4 Status: OFF");
  server.send(200, "text/html", SendHTML(false,LED2status)); 
}
void handle_led2on() {
  LED2status = HIGH;
  Serial.println("GPIO5 Status: ON");
  server.send(200, "text/html", SendHTML(LED1status,true)); 
}
void handle_led2off() {
  LED2status = LOW;
  Serial.println("GPIO5 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,false)); 
}
void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}
// ------------------------------- HTML WebServer ------------------------------- //
String SendHTML(uint8_t led1stat,uint8_t led2stat){
  String ptr = "<!DOCTYPE html lang=uk-UA> <html>\n";
  ptr +="<head><meta charset='UTF-8' name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>LED Control</title>\n";
  ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr +=".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button-on {background-color: #3498db;}\n";
  ptr +=".button-on:active {background-color: #2980b9;}\n";
  ptr +=".button-off {background-color: #34495e;}\n";
  ptr +=".button-off:active {background-color: #2c3e50;}\n";
  ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>ESP32 Web Server</h1>\n";
  ptr +="<h3>Using Access Point(AP) Mode</h3>\n";
  //
  ptr +="<h3>Battery Status: </h3>" ;
  ptr +=(float)perc;
  ptr +="%";
  ptr +="\n";
  ptr +=(int)value;
  ptr +="\n";
  ptr +="\n";
  ptr +=(float)voltageLevel;
  ptr +="V";
  ptr +="\n";
  //
  if(led1stat)
  {ptr +="<p>LED1 Status: ON</p><a class=\"button button-off\" href=\"/led1off\">OFF</a>\n";}
  else
  {ptr +="<p>LED1 Status: OFF</p><a class=\"button button-on\" href=\"/led1on\">ON</a>\n";}
  if(led2stat)
  {ptr +="<p>LED2 Status: ON</p><a class=\"button button-off\" href=\"/led2off\">OFF</a>\n";}
  else
  {ptr +="<p>LED2 Status: OFF</p><a class=\"button button-on\" href=\"/led2on\">ON</a>\n";}
  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}

// -----------|------|--------|------ Loop -------|---------|-----------|--------- //
// -----------V------V--------V-------------------V---------V-----------V--------- //

void loop() {
  digitalWrite(LED2, HIGH);
  // ------------------------------- Functions call  ------------------------------- //
  batteryStatusf();
  choosef();
  // ------------------------------- WiFi ???  ------------------------------- //
  server.handleClient();
  if(LED1status)
  {digitalWrite(LED1pin, HIGH);}
  else
  {digitalWrite(LED1pin, LOW);}
  if(LED2status)
  {digitalWrite(LED2pin, HIGH);}
  else
  {digitalWrite(LED2pin, LOW);}

  // ------------------------------- Button READ ------------------------------- //
 if (digitalRead(Button1) == LOW) //
  {
    colorsON = 1;
    //randomf();
    Serial.println("Button pressed");
    digitalWrite(LED2, LOW);
    player.volume(volume);
    player.play(1);
    delay(2000);
    playf();
    // Serial.print("randomNumber: ");
    // Serial.println(randNr);
    // digitalWrite(LED2, HIGH); // Pin12 GREEN
    // digitalWrite(LED1, LOW);
    // Serial.println("Button pressed");
  }
  //  else{
  //   digitalWrite(LED1, HIGH); //PIN 21 Red
  //   digitalWrite(LED2, LOW);
  // }
  // ------------------------------- Look for new cards ------------------------------- //
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) {
    return;                                               // If no new card is present, exit the loop
  }
  // ------------------------------- Display UID on Serial Monitor ------------------------------- //
  Serial.print("UID tag: ");
  String content = "";                                   // Create a string to hold the UID content
  for (byte i = 0; i < rfid.uid.size; i++) {
    Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(rfid.uid.uidByte[i], HEX);             // Print each byte of the UID in HEX format
    content.concat(String(rfid.uid.uidByte[i] < 0x10 ? " 0" : " "));
    content.concat(String(rfid.uid.uidByte[i], HEX));   // Append each byte to the content string
  }
  Serial.println();
  Serial.println();


  rfid.PICC_HaltA();                                    // Halt the PICC (card)
  content.toUpperCase();
  // ------------------------------- Choosing game ------------------------------- //
  if (chooseON == 1){
  // ------------------------------- TRUE or FALSE ------------------------------- //
    if (content.substring(1) == cardRFID) //
    {
      Serial.print("rfid string: ");
      Serial.println(cardRFID);
      digitalWrite(LED2, HIGH);
      player.volume(volume);
      player.play(2);
      delay(1000);
      digitalWrite(LED2, LOW);
      delay(2000);
      wrong = 0;
      playf();
    }
    else{
      Serial.print("rfid string: ");
      Serial.println(cardRFID);
      wrong = wrong +1;
      Serial.print("wrong nr: ");
      Serial.println(wrong);
      digitalWrite(LED1, HIGH);
        if (wrong == 3){
        // player.volume(30);
        // player.play(7);
        delay(2000);
        digitalWrite(LED1, LOW);
        playf();
        wrong = 0;
      }
      else{
        player.volume(volume);
        player.play(3);
        delay(2000);
        digitalWrite(LED1, LOW);
      }
    }
  }
}

Sometimes in Serial Monitor i became like this:

After RST button i also became this message:

18:06:00.072 -> T�� Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
18:06:00.137 ->
18:06:00.169 -> Core 1 register dump:
18:06:00.169 -> PC : 0x40175c4d PS @@ : 0x00060a30 A0 : 0x3ff65000 A1 : 0x3ffb2070
18:06:00.266 -> A2 : 0x00000000 A3 : 0x00000000 A4 : 0x00000005 Guru Meditation Error: Core 0 panic'ed (Unhandled debug exception).
18:06:00.425 -> Debug exception reason: BREAK instr
18:06:00.457 -> Core 0 register dump:
18:06:00.490 -> PC : 0x4008501c PS : 0x00000016 A0 : 0x40080306 A1 : 0x3ffbbd50
18:06:00.586 -> A2 : 0x3ffaead4 A3 : 0xffffffff A4 : 0x00060d20 A5 : 0x00060d23
18:06:00.682 -> A6 : 0x3ffb6340 A7 : 0x0000cdcd A8 : 0x8008dc06 A9 : 0x00000001
18:06:00.747 -> A10 : 0x00000001 A11 : 0x0000008e A12 : 0xb33fffff A13 : 0x3f414a7c
18:06:00.842 -> A14 : 0x00000003 A15 : 0x0000cdcd SAR : 0x0000001d EXCCAUSE: 0x00000001
18:06:00.938 -> EXCVADDR: 0x00000000 LBEG : 0x40084639 LEND : 0x40084641 LCOUNT : 0x00000027
18:06:01.034 ->
18:06:01.034 ->
18:06:01.034 -> Backtrace: 0x40085019:0x3ffbbd50 0x40080303:0x3ffbbd80 0x4011be2e:0x3ffbbdc0 0x40086b69:0x3ffbbde0 0x4014a9d4:0x3ffbbe10 0x4013b539:0x3ffbbe30 0x4012712a:0x3ffbbe50 0x4008daa6:0x3ffbbe80
18:06:01.258 ->
18:06:01.258 ->
18:06:01.258 -> Core 1 register dump:
18:06:01.258 -> PC : 0x400e4461 PS : 0x00060334 A0 �Connecting to DFPlayer Mini failed!
18:06:02.207 -> HTTP server started
18:06:02.207 -> mDNS responder started

Could you help me to understand what it could be?

Thank you in advance

Regards
Taras

I'm not familiar with your devices, but at least try with some other pins. Gpio12 and 15 are both strapping pins, use any free pin between 16-33.

Also, when you get it working, consider using hardwareserial, Serial1 or Serial2 for Dfplayer

1 Like

The Nano ESP32 section of the forum is only for problems with the Arduino Nano ESP32, not for other ESP32 based boards. Hence your topic has been moved.

Sorry I cannot follow your word schematic. Drawing a proper one will help you get better answers faster.

Your circuit is a mess. There could be errors that you have not been able to find. The forum won't be able to find them either.

Get 2 large breadboards, clip them together and plug every component you can into the breadboards. Then re-wire your circuit.

If you use solid-core connection wire, cut to length and laid flat on the breadboard, this will be much more neat and reliable and make it easier to find errors. Use different colour wire for different types of signals and always and only use red and black for Vcc and ground.

1 Like

The comments in several places seem to contradict the code. One example:

// Use pins 2 and 3 to communicate with DFPlayer Mini
static const uint8_t PIN_MP3_TX = 26; // Connects to module's RX  26
static const uint8_t PIN_MP3_RX = 27; // Connects to module's TX  27

If you copy/pasted from another source it might help us if you show it.

Did you mean to KEEP these, despite your comment?

uint8_t LED1pin = 0;      // delete!
bool LED1status = LOW;     // delete!
uint8_t LED2pin = 0;      // delete!
bool LED2status = LOW;     // delete!

Try placing delay(1000) after any player commands in setup()

The photo is of no help in checking your wiring. A neat schematic is needed, possibly hand drawn.

1 Like

Hello Terrypin, thank you for your answer.

it was my test lines, they have no function. Sorry for that.

Here is the schematic:

And the answer?

Did you?

try this

// ESP32  DFRobotDFPlayer player

// **** Once the card is formatted, MP3 files can be copied to it. 
// **** They are played in the order in which they were copied to the card
// names make no difference

#include "DFRobotDFPlayerMini.h"

// ESP32  connections
// ESP32 3.3V to DFPlayer VCC (NOTE had to use 5V!!)
// ESP32 GND to DFPlayer GND
// ESP32 pin 16 RXD1 to DFPlayer TX
// ESP32 pin 17 TXD1 to DFPlayer RX
// ESP32 pin 4 to DFPlayer BUSY

#define RXD1 16
#define TXD1 17

#define mySoftwareSerial Serial1
#define BUSY 4

DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

void setup() {
  Serial.begin(115200);
  delay(1000);
  pinMode(4, INPUT_PULLUP);       // GPIO 4 is Busy signal
  Serial1.begin(9600, SERIAL_8N1, RXD1, TXD1);
  delay(3000);
  Serial.println();
  Serial.println(F("\nESP32 DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("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("DFPlayer Mini online."));
  myDFPlayer.volume(25);  //Set volume value. From 0 to 30
  //myDFPlayer.play(1);     //Play the first mp3
  delay(10);
  Serial.println("enter track to play (1, 2, 3, etc)");
}

void loop() {
  static unsigned long timer = millis();
  static int busy = -1;
  // check if player Busy status has changed
  if (digitalRead(BUSY) != busy) {
    if ((busy = digitalRead(BUSY)))
      Serial.println("busy " + String(busy) + " NOT playing");
    else
      Serial.println("busy " + String(busy) + " playing");
    ;
  }

  if (millis() - timer > 3000) {
    timer = millis();
    //myDFPlayer.next();  //Play next mp3 every 3 second.
  }
  // if new track (integer) entered play it
  if (Serial.available()) {
    int x = Serial.parseInt();                // read track number
    Serial.println("playing " + String(x));
    myDFPlayer.play(x);                       // play track
    while (Serial.available()) Serial.read(); // clear EOL etc
    delay(10);
  }

  // if player status changed display
  if (myDFPlayer.available()) {
    printDetail(myDFPlayer.readType(), myDFPlayer.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;
  }
}

serial monitor output

ESP32 DFRobot DFPlayer Mini Demo
Initializing DFPlayer ... (May take 3~5 seconds)
DFPlayer Mini online.
enter track to play (1, 2, 3, etc)
busy 1 NOT playing
playing 1
busy 0 playing
Number:1 Play Finished!
busy 1 NOT playing
playing 2
busy 0 playing
Number:2 Play Finished!
busy 1 NOT playing
playing 3
busy 0 playing
Number:3 Play Finished!
busy 1 NOT playing

your wiring connections for the MFRC522 RFID looks OK - similar to what I have used in the past

1 Like

Hello Terrypin,

i have found like different codes and tried to make it together, so i dont have "original" code.

it works, thank you! It is looks like, it is enough only to delay between Serial.begin:

void setup() {
  Serial.begin(115200);                                 // Start serial communication at 9600 baud rate
  delay(1000);
  // ------------------------------- Initialize RFID ------------------------------- //
  SPI.begin();                                        // Initiate SPI bus
  rfid.PCD_Init();                                    // Initiate MFRC522 RFID module
  // ------------------------------- Init serial port for DFPlayer Mini ------------------------------- //
  softwareSerial.begin(9600);
  delay(1000);
  if (player.begin(softwareSerial)) {
    Serial.println("OK");
    player.volume(volume);                            // Set volume to maximum (0 to 30).
    player.readVolume();
  } else {
    Serial.println("Connecting to DFPlayer Mini failed!");
  }

Thank you all guys!

Hello together, one more question.

I try now to make an external power supply with LiPo Battery 3.7V, StepUp Module MT3608 and charging module TP4056.

As already mentioned, if its supplied with USB Port everything is ok. But if i am going with Battery it is seems to be that my controller not starting. The LED (for tests) in setup() function, not even blinking.

A few scenario that i have seen:

  1. USB supply -> works well.
  2. batter supply + charging module connect to powerbank or usb -> sometimes works, but started after x times reboot.
  3. only battery supply -> has only i guess 2 times started, after few seconds was dead.

The voltage in all scenarios on the module is the same ~5.0-5.1V (between V5 and GND pins).

I have tried different batteries with capacity: 320mAh, 1000mAh and 1200mAh. No changes.

Also i have battery status in %, works now very well :melting_face: (Analog Pin35). Without this function make also no difference.

Do you have maybe some ideas?

Thank you in advance