Issue with Blynk and MP3 Player Integration on Arduino

Hello Arduino Community,

I hope everyone is doing well. I'm currently facing an issue with integrating Blynk and an MP3 player on my Arduino project, and I could really use some assistance.

Here's the setup: I have an Arduino Uno board connected to a SIM800 GSM modem for internet connectivity. I'm using the Blynk platform for remote control of the Arduino, and I've also incorporated an MP3 player module (specifically the MP3_TF module) for playing audio tracks based on user commands.

The problem arises when I try to trigger the MP3 player to play a track via a Blynk button. While everything works fine individually (the MP3 player plays tracks when directly triggered from the Arduino sketch, and Blynk controls the Arduino effectively), there seems to be a conflict when I attempt to trigger the MP3 player from a Blynk button press.

Here's a brief overview of my setup:

  • Arduino Uno connected to a SIM800 GSM modem for internet connectivity.
  • Blynk app controlling the Arduino's GPIO pins.
  • MP3_TF module connected to the Arduino for audio playback.

I've tried debugging the issue, and it seems that when the Blynk button triggers the MP3 player function, it causes the code to freeze or hang, preventing further execution.

It all works up to the point of playing the sound, which it does and then it just can't move past that point.

Here's the code:

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

/* Fill in information from Blynk Device Info here */
#define BLYNK_TEMPLATE_ID "TMPL5lhTVjbnb"
#define BLYNK_TEMPLATE_NAME "Quickstart Template"
#define BLYNK_AUTH_TOKEN "W_Zv9MSFxztFJXj9D1SupiCBNARaypfh"

// Select your modem:
#define TINY_GSM_MODEM_SIM800

#include <TinyGsmClient.h>
#include <BlynkSimpleTinyGSM.h>

// SETUP THE MP3
#include "mp3tf16p.h"
MP3Player mp3(8, 9); // Ensure these pins do not conflict with other hardware

// Your GPRS credentials
char apn[]  = "everywhere";
char user[] = "eesecure";
char pass[] = "secure";

// Hardware Serial on Uno, Nano (define SerialAT Serial1)
#include <SoftwareSerial.h>
SoftwareSerial SerialAT(2, 3); // RX, TX

// Define pin_relay1
#define pin_relay1 10

int state_relay1 = 0;
#define virtual_pin1 V1

BLYNK_WRITE(virtual_pin1) {
  state_relay1 = param.asInt();
  digitalWrite(pin_relay1, state_relay1);

  if (state_relay1 == 1) {
    // If relay is turned on
    Serial.println("Relay ON");
    // Add more debug statements
    Serial.println("About to play MP3");
    mp3.playTrackNumber(2, 25);
   delay(10);
   pinMode(pin_relay1, OUTPUT);
   digitalWrite(pin_relay1, LOW);    
   Serial.println("MP3 playback initiated"); // To check if the code has frozen
   
  } else {
    // If relay is turned off
    Serial.println("Relay OFF");
  }
}

TinyGsm modem(SerialAT);

void setup() {
  // Debug console
  Serial.begin(9600);
  
  // Initialize MP3 player
  Serial.println("Initializing MP3 Player...");
  mp3.initialize();
  Serial.println("MP3 Player Initialized");
  mp3.playTrackNumber(2, 25);
  delay(10);
  pinMode(pin_relay1, OUTPUT);
  digitalWrite(pin_relay1, LOW);

  // Set GSM module baud rate
  SerialAT.begin(9600);
  delay(3000);

  // Restart modem
  Serial.println("Initializing modem...");
  modem.restart();

  // Blynk connection
  Blynk.begin(BLYNK_AUTH_TOKEN, modem, apn, user, pass);
}

void loop() {
  Blynk.run();
}

I don't have your MP3 module, (nor have I used Blynk), but using my DFR MP3 Player that very brief delay might cause a problem. Does it make any difference if you change it to say 2000?

Hi Terrypin, thanks for your reply. I have tried increasing the delay as you suggested and removing it all together but still not improvement :frowning:

Barely more than guesses from me until hopefully someone with your hardware comes along. But where in your code is the button you mention? And does it require debouncing?

I am wondering when mp3.playTrackNumber(2, 25) is being used it is something in the mp3 code that is affecting its ability to stay connected to blynk here is the mp3tf16p.h code:

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

#define MP3_ERROR_ONLY 1
#define MP3_ALL_MESSAGE 2

class MP3Player
{
private:
    SoftwareSerial *mySoftwareSerial;
    void statusOnSerial(uint8_t type, int value);
    void waitPlayIsTerminated(void);
    int p_RX;
    int p_TX;

public:
    DFRobotDFPlayerMini player;
    MP3Player(int RX, int TX);
    ~MP3Player();
    void playTrackNumber(int trackNumber, int volume, boolean waitPlayTerminated = true);
    boolean playCompleted(void);
    void initialize(void);
    int serialPrintStatus(int errorOnly);
};

MP3Player::MP3Player(int RX, int TX)
{
    p_TX = TX;
    p_RX = RX;
}

MP3Player::~MP3Player()
{
}

void MP3Player::initialize(void)
{
    mySoftwareSerial = new SoftwareSerial(p_RX, p_TX);

    mySoftwareSerial->begin(9600);
    Serial.println(F("Initializing MP3Player ..."));

    if (!player.begin(*mySoftwareSerial,true,false))
    {
        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)
            ;
    }
    player.volume(10);
    Serial.println(F("MP3Player online."));
}

void MP3Player::playTrackNumber(int trackNumber, int volume, boolean waitPlayTerminated)
{
    player.volume(volume);
    player.play(trackNumber);
    if (waitPlayTerminated)
    {
        waitPlayIsTerminated();
    }
}

void MP3Player::waitPlayIsTerminated(void)
{
    while (!playCompleted())
    {
    }
}

boolean MP3Player::playCompleted(void)
{
    if (player.available())
    {
        return player.readType() == DFPlayerPlayFinished;
    }
    return false;
}

// Print the detail message from DFPlayer to handle different errors and states.
// 
int MP3Player::serialPrintStatus(int verbose)
{
    if (player.available())
    {
        uint8_t type = player.readType();
        int value = player.read();
        if (verbose == MP3_ERROR_ONLY)
        {
            if (type == DFPlayerError)
            {
                statusOnSerial(type, value);
            }
        }
        else
        {
            statusOnSerial(type, value);
        }
        if(type == DFPlayerError) {
            return value;
        } else {
            return 0;
        }
    }
}

void MP3Player::statusOnSerial(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;
    }
}

There cannot be two instances of SoftwareSerial.
There's SoftwareSerial between the Arduino and Blynk - and another in that (odd) library there.

1 Like

The IO "pins" could be used, if clumsily, depending on what really needs to be done.

Couple of ideas:

  1. Ditch the Uno and go with a board with multiple hardware serial ports.

  2. If you're married to the idea of using an Uno, perhaps the AltSoftSerial library is worth a look. Though you'd have to modify the DFPlayer library to use it as well.

And I'm wondering why I didn't get a reply to my question 10 days ago in post #4?

I believe, Terrypin, that the "button" is a Blynk 'device' - it's on the app.

Thanks.

From my first reply to the OP:
"I don't have your MP3 module, (nor have I used Blynk)"

I hadn't realised that the button was Blynk software.

There's an introductory, base model, no charge version.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.