Определение окончания воспроизведения 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: я заметил, что у нее ЗАНЯТ
пин, но пока я не нашел примеров, которые использовали бы этот контакт для определения состояния воспроизведения.
Спасибо за любое предложение.
@Fabrizio Calderan loves trees, 👍0
Обсуждение2 ответа
Как сказал @chrisl alread, вы могли бы использовать выход busy. Или простой последовательный запрос
myDFPlayer.readState();
Если результатом будет что-то вроде DFPlayerPlayFinishe,
фактический трек завершен.
Я решил проверить занятый контакт, спасибо, @Fabrizio Calderan loves trees
PIN "Занято" означает, что осуществляется доступ к флэш-памяти. Так что это не то же самое, что "воспроизводимый трек".
- Как получить текущую дату
- Как найти разницу между двумя timestamp
- Как использовать память RTC в NodeMCU для подсчета пробуждений от глубокого сна?
- Контакты I2S не выводят звук в ESP8266
- Как восстановить звук из серии аналоговых целочисленных входов?
- Использование RTC для хранения
- RtcUtility.h: нет такого файла или каталога (No such file or directory)
- ESP8266 с экраном RTC DS1307 - Экран WS2818B не мигает - проблема с I2C?
Вы искали это в Гугле? Я непосредственно нашел [этот сайт] (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