Определение окончания воспроизведения MP3-файла с помощью библиотеки DFPlayerMini/DFRobotDFPlayerMini.h

Для проекта, который я делаю, я использовал ESP8266 / 12e, модуль DS3231 RTC и DFplayerMini

По сути, это абонент для птиц, и он должен воспроизводить 12-минутный MP3. MP3-файл должен воспроизводиться в течение 2 часов на восходе солнца и за 2 часа до захода солнца, поэтому каждый раз его следует воспроизводить 10 раз (10 × 12 = 120 минут (2 часа)).

Код, который я написал до сих пор (некоторые части опущены для краткости):

#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#include <Wire.h>       
#include <RtcDS3231.h>  

#define DELAY_ONPLAY 1000
#define DELAY_ONPAUSE 20000



// Библиотека RTC (I2C)
RtcDS3231<TwoWire> rtcObject(Wire); 

// Последовательная связь в формате MP3
SoftwareSerial mySoftwareSerial(14, 12);
DFRobotDFPlayerMini myDFPlayer;



// Переменные
int volume, mth, day, h, m;

// Состояние воспроизведения
int playbackCount = 0;
bool isPlaying = false;

RtcDateTime currentTime;

void setup() {

    mySoftwareSerial.begin(9600);
    // Начать последовательное подключение
    Serial.begin(115200);  
    // Запуск 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();    //получить время из 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 {
            // Ничего не делать в течение следующих 20 секунд
            delay(DELAY_ONPAUSE);
        }
    }

    else {


      // В данный момент играю
      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() {

    // Получить значение потенциометра в диапазоне [3..30]
    volume = map(analogRead(A0), 0, 1023, 2, 30);
    volume = constrain(volume, 3, 30);
    // Установите громкость проигрывателя 
    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;
}

Часть, на которой я застрял, это

  if (playbackCount < 10) {

      if (/* MP3mini_is_idle */) {

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

      }

  }

Как мне определить в условии if, действительно ли воспроизводится MP3, прежде чем воспроизводить его снова? Я думаю, что 12-минутная задержка () - неправильный подход.

На изображении ниже распиновка DFPlayerMini: я заметил, что у нее ЗАНЯТ пин, но пока я не нашел примеров, которые использовали бы этот контакт для определения состояния воспроизведения.

Спасибо за любое предложение.

, 👍0

Обсуждение

Вы искали это в Гугле? Я непосредственно нашел [этот сайт] (https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299 ). В таблице под изображением, которая есть у вас в вашем вопросе, указано, что вывод BUSY НИЗКИЙ, когда DFPlayer что-то воспроизводит. Разве это не именно то, чего ты хочешь?, @chrisl

Спасибо. Я постараюсь сделать это как можно скорее и дам вам отзыв через несколько часов, @Fabrizio Calderan loves trees

В качестве альтернативы вы можете создать новый аудиофайл, в котором песня птицы повторяется 10 раз. PS если вы используете код повторного воспроизведения, я бы повторял песню до тех пор, пока она не достигнет 120 минут (используя millis()), вместо того, чтобы повторять ее 10 раз. Таким образом, если вы когда-нибудь измените звуковой файл, и этот файл будет иметь другую длину, вам не придется обновлять код., @Gerben

@chrisl, я решил проверить занятый контакт. Если вы хотите поместить комментарий в качестве ответа, я был бы рад принять его, @Fabrizio Calderan loves trees


2 ответа


1

Как сказал @chrisl alread, вы могли бы использовать выход busy. Или простой последовательный запрос

myDFPlayer.readState();

Если результатом будет что-то вроде DFPlayerPlayFinishe, фактический трек завершен.

,

Я решил проверить занятый контакт, спасибо, @Fabrizio Calderan loves trees


1

PIN "Занято" означает, что осуществляется доступ к флэш-памяти. Так что это не то же самое, что "воспроизводимый трек".

,