user52075: For a project I'm doing I've used an ESP8266/12e, a RTC Module DS3231 and a DFplayerMini
Basically it's a caller for birds and it has to play a 12-minute long MP3. The MP3 file should be played for 2 hours at the sunrise and 2 hours before the sunset, so each time it should be played 10 times (10 × 12 = 120 minutes (2 hours))
The code I wrote so far (some parts are omitted for brevity):
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#include <Wire.h>       
#include <RtcDS3231.h>  

#define DELAY_ONPLAY 1000
#define DELAY_ONPAUSE 20000



// RTC Library (I2C)
RtcDS3231<TwoWire> rtcObject(Wire); 

// MP3 Serial communication
SoftwareSerial mySoftwareSerial(14, 12);
DFRobotDFPlayerMini myDFPlayer;



// Variables
int volume, mth, day, h, m;

// State of the playback
int playbackCount = 0;
bool isPlaying = false;

RtcDateTime currentTime;

void setup() {

    mySoftwareSerial.begin(9600);
    // Start serial connection
    Serial.begin(115200);  
    // Start I2C
    rtcObject.Begin();    

    if (!myDFPlayer.begin(mySoftwareSerial)) {  
      while(true){
        delay(10);
      }
    }

    /* Get the value of potentiometer in the range of [3..30] and
     * set the volume
     */    
    setVolume();


}



void loop() {

    setVolume();
    currentTime = rtcObject.GetDateTime();    //get the time from the RTC

    mth  = currentTime.Month();
    day  = currentTime.Day();
    h    = currentTime.Hour();
    m    = currentTime.Minute();


    /* The caller is not playing: check if date and time should
     * start the playback
     */
    if (isPlaying == false) {

        if (startSunrise() || startSunset()) {
            isPlaying = true;
        }

        else {
            // Nothing to do for the next 20 seconds
            delay(DELAY_ONPAUSE);
        }
    }

    else {


      // Currently playing
      if (playbackCount < 10) {

          if (/* MP3mini_is_idle */) {

            myDFPlayer.play(1);
            playbackCount = playbackCount + 1;

          }
      }

      else {
        playbackCount = 0;
        isPlaying = false;
        Serial.print("End of playback");
      }

      delay(DELAY_ONPLAY); 

    }
}



void setVolume() {

    // Get the value of potentiometer in the range of [3..30]
    volume = map(analogRead(A0), 0, 1023, 2, 30);
    volume = constrain(volume, 3, 30);
    // Set the player volume 
    myDFPlayer.volume(volume);  
    Serial.println(String(volume));

}



bool startSunrise() {

    /* at the sunrise the call has to be played for 2 hours */

    if (mth == 2) {
        if ((day == 20 && h == 7 && m == 8) ||
            (day == 21 && h == 7 && m == 6) ||
            ...
            (day == 28 && h == 6 && m == 54) ||
            (day == 29 && h == 6 && m == 52)) { return true; }
    }

    if (mth == 3) {
        if ((day == 1  && h == 6 && m >= 49) ||
            (day == 2  && h == 6 && m >= 47) ||
            (day == 3  && h == 6 && m >= 45 ) ||
            (day == 4  && h == 6 && m >= 43) ||
            ...
            (day == 27 && h == 6 && m >= 0) ||
            (day == 28 && h == 5 && m >= 58)) { return true; }
    }

    return false;
}



bool startSunset() {

    /* 2 hours before sunset the call has to be played for 2 hours */

    if (mth == 2) {
        if ((day == 20 && h == 15 && m >= 41) ||
            (day == 21 && h == 15 && m >= 42) ||
            ...
            (day == 28 && h == 15 && m >= 52) ||
            (day == 29 && h == 15 && m >= 54)) { return true; }
    }

    if (mth == 3) {
        if ((day == 1  && h == 15 && m >= 56) ||
            (day == 2  && h == 15 && m >= 58) ||
            (day == 3  && h == 15 && m >= 59) ||
            (day == 4  && h == 16 && m >= 1) ||
            ...
            (day == 27 && h == 16 && m >= 31) ||
            (day == 28 && h == 16 && m >= 33)) { return true; }
    }

    return false;
}

The part I'm stuck on is
  if (playbackCount < 10) {

      if (/* MP3mini_is_idle */) {

        myDFPlayer.play(1);
        playbackCount = playbackCount + 1;

      }

  }

How do I detect in the if condition if the MP3 is actually playing before play it again? 
I think a 12-minute delay() is not the right approach. 
In the image below the DFPlayerMini pinout: I noticed It has a BUSY pin  but I haven't found examples so far that uses this pin to detect the playback state.

Thanks for any suggestion.

user60070: As @chrisl alread said, you could use the busy pin. Or a simple serial query
myDFPlayer.readState();

If the result is something like DFPlayerPlayFinishe the actual track is complete.

user85155: The busy pin, means that the flash memory is being accessed. So its not the same as "track being played".

52075: <p>For a project I'm doing I've used an ESP8266/12e, a RTC Module DS3231 and a DFplayerMini</p>

<p>Basically it's a caller for birds and it has to play a 12-minute long MP3. The MP3 file should be played for 2 hours at the sunrise and 2 hours before the sunset, so each time it should be played 10 times (<em>10 &times; 12 = 120 minutes (2 hours)</em>)</p>

<p>The code I wrote so far (some parts are omitted for brevity):</p>

<pre><code>#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#include &lt;Wire.h&gt;       
#include &lt;RtcDS3231.h&gt;  

#define DELAY_ONPLAY 1000
#define DELAY_ONPAUSE 20000



// RTC Library (I2C)
RtcDS3231&lt;TwoWire&gt; rtcObject(Wire); 

// MP3 Serial communication
SoftwareSerial mySoftwareSerial(14, 12);
DFRobotDFPlayerMini myDFPlayer;



// Variables
int volume, mth, day, h, m;

// State of the playback
int playbackCount = 0;
bool isPlaying = false;

RtcDateTime currentTime;

void setup() {

    mySoftwareSerial.begin(9600);
    // Start serial connection
    Serial.begin(115200);  
    // Start I2C
    rtcObject.Begin();    

    if (!myDFPlayer.begin(mySoftwareSerial)) {  
      while(true){
        delay(10);
      }
    }

    /* Get the value of potentiometer in the range of [3..30] and
     * set the volume
     */    
    setVolume();


}



void loop() {

    setVolume();
    currentTime = rtcObject.GetDateTime();    //get the time from the RTC

    mth  = currentTime.Month();
    day  = currentTime.Day();
    h    = currentTime.Hour();
    m    = currentTime.Minute();


    /* The caller is not playing: check if date and time should
     * start the playback
     */
    if (isPlaying == false) {

        if (startSunrise() || startSunset()) {
            isPlaying = true;
        }

        else {
            // Nothing to do for the next 20 seconds
            delay(DELAY_ONPAUSE);
        }
    }

    else {


      // Currently playing
      if (playbackCount &lt; 10) {

          if (/* MP3mini_is_idle */) {

            myDFPlayer.play(1);
            playbackCount = playbackCount + 1;

          }
      }

      else {
        playbackCount = 0;
        isPlaying = false;
        Serial.print("End of playback");
      }

      delay(DELAY_ONPLAY); 

    }
}



void setVolume() {

    // Get the value of potentiometer in the range of [3..30]
    volume = map(analogRead(A0), 0, 1023, 2, 30);
    volume = constrain(volume, 3, 30);
    // Set the player volume 
    myDFPlayer.volume(volume);  
    Serial.println(String(volume));

}



bool startSunrise() {

    /* at the sunrise the call has to be played for 2 hours */

    if (mth == 2) {
        if ((day == 20 &amp;&amp; h == 7 &amp;&amp; m == 8) ||
            (day == 21 &amp;&amp; h == 7 &amp;&amp; m == 6) ||
            ...
            (day == 28 &amp;&amp; h == 6 &amp;&amp; m == 54) ||
            (day == 29 &amp;&amp; h == 6 &amp;&amp; m == 52)) { return true; }
    }

    if (mth == 3) {
        if ((day == 1  &amp;&amp; h == 6 &amp;&amp; m &gt;= 49) ||
            (day == 2  &amp;&amp; h == 6 &amp;&amp; m &gt;= 47) ||
            (day == 3  &amp;&amp; h == 6 &amp;&amp; m &gt;= 45 ) ||
            (day == 4  &amp;&amp; h == 6 &amp;&amp; m &gt;= 43) ||
            ...
            (day == 27 &amp;&amp; h == 6 &amp;&amp; m &gt;= 0) ||
            (day == 28 &amp;&amp; h == 5 &amp;&amp; m &gt;= 58)) { return true; }
    }

    return false;
}



bool startSunset() {

    /* 2 hours before sunset the call has to be played for 2 hours */

    if (mth == 2) {
        if ((day == 20 &amp;&amp; h == 15 &amp;&amp; m &gt;= 41) ||
            (day == 21 &amp;&amp; h == 15 &amp;&amp; m &gt;= 42) ||
            ...
            (day == 28 &amp;&amp; h == 15 &amp;&amp; m &gt;= 52) ||
            (day == 29 &amp;&amp; h == 15 &amp;&amp; m &gt;= 54)) { return true; }
    }

    if (mth == 3) {
        if ((day == 1  &amp;&amp; h == 15 &amp;&amp; m &gt;= 56) ||
            (day == 2  &amp;&amp; h == 15 &amp;&amp; m &gt;= 58) ||
            (day == 3  &amp;&amp; h == 15 &amp;&amp; m &gt;= 59) ||
            (day == 4  &amp;&amp; h == 16 &amp;&amp; m &gt;= 1) ||
            ...
            (day == 27 &amp;&amp; h == 16 &amp;&amp; m &gt;= 31) ||
            (day == 28 &amp;&amp; h == 16 &amp;&amp; m &gt;= 33)) { return true; }
    }

    return false;
}
</code></pre>

<p>The part I'm stuck on is</p>

<pre><code>  if (playbackCount &lt; 10) {

      if (/* MP3mini_is_idle */) {

        myDFPlayer.play(1);
        playbackCount = playbackCount + 1;

      }

  }
</code></pre>

<p>How do I detect in the <code>if</code> condition if the MP3 is actually playing before play it again? 
I think a 12-minute <code>delay()</code> is not the right approach. </p>

<p>In the image below the DFPlayerMini pinout: I noticed It has a <code>BUSY</code> pin  but I haven't found examples so far that uses this pin to detect the playback state.</p>

<p><a href="https://i.stack.imgur.com/XiOuV.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/XiOuV.jpg" alt="enter image description here"></a></p>

<p>Thanks for any suggestion.</p>
 60070: <p>As @chrisl alread said, you could use the busy pin. Or a simple serial query</p>

<pre><code>myDFPlayer.readState();
</code></pre>

<p>If the result is something like <code>DFPlayerPlayFinishe</code> the actual track is complete.</p>
 85155: <p>The busy pin, means that the flash memory is being accessed. So its not the same as &quot;track being played&quot;.</p>
