0

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.

enter image description here

Thanks for any suggestion.

4
  • 1
    Have you googled for this? I directly found this site. The table under the image, that you have in your question, states, that the BUSY pin is LOW, when the DFPlayer is playing something. Isn't that exactly, what you want?
    – chrisl
    Feb 11 '20 at 14:29
  • Thank you. I'll try as soon as possibile and I'll give you a feedback in a few hours Feb 11 '20 at 15:03
  • 1
    Alternatively you could create a new audio file that has the bird song, repeated 10 times, in it. PS if you go with the repeated playback code, I'd have the song repeat till it reaches 120minutes (using millis()), instead of repeating it 10 times. That way if you ever change the sound file, and that file has a different length, you wouldn't have to update the code.
    – Gerben
    Feb 11 '20 at 16:48
  • @chrisl, I've solved checking the busy pin. If you like to put the comment as the answer I would be happy to accept it Feb 12 '20 at 13:26
1

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.

1
  • I've solved checking the busy pin, thank you Feb 12 '20 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.