`.readFileCounts()` не работает в мини-модуле DFPlayer

Я только что поигрался с модулем MP3-TF-16P, он же DFPlayer mini. Библиотеку и примеры, которые я взял за основу, можно найти здесь.

Моя текущая настройка содержит кнопку (NC, нормально закрытая), которая подключена к контакту D2 и к ней прикреплен прерыватель. Ввод кнопки устраняется за счет использования разницы во времени внутри ISR. Код (на основе примера getStarted) можно найти ниже.

Использование кнопки для воспроизведения следующей песни работает должным образом. Однако при попытке получить общее количество дорожек, расположенных на SD-карте, путем вызова Serial.println(player.readFileCounts()), как показано в файле Пример FullFunction плата ничего не печатает и не отвечает на дальнейшие команды. Даже использование примера FullFunction ничего не печатает.

Может ли кто-нибудь перепроверить это поведение? Это проблема, связанная с модулем или с библиотекой, поскольку я использую модуль MP3-FT-16P, который может быть дешевым клоном исходного модуля DFPlayer mini ? Работает ли это с другими модулями MP3-FT-16P, что означает, что мой неисправен?

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

#define interruptPin 2
#define softSerialRx 10
#define softSerialTx 11
#define debounceDelayMillis 1000


volatile uint32_t lastInterruptTime = 0;
volatile bool interruptOccured = false;

SoftwareSerial softSerial(softSerialRx, softSerialTx);
DFRobotDFPlayerMini player;


void setup() {
  softSerial.begin(9600);
  Serial.begin(115200);

  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), interruptHandler, FALLING);

  Serial.println(F("Initing player ..."));
  // `player.begin(stream)` возвращает true при инициализации модуля
  if (!player.begin(softSerial)) {
    Serial.println(F("... failed"));
    while(true) {
      // никогда не покидаем этот цикл, так как инициализация пошла не так
    }
  }
  Serial.println(F("... ready."));

  // объем: 0...30
  player.volume(30);

  // при использовании `player.readFileCounts()` модуль плеера не отвечает на дальнейшие команды
  // Serial.println(player.readFileCounts());
}


void loop() {
  // читаем сообщения о состоянии от DFPlayerMini через последовательный порт программного обеспечения, если он доступен
  if (player.available()) {
    printPlayerStatus(player.readType(), player.read());
  }

  if (interruptOccured) {
    Serial.println("Button pressed");
    player.next();
    interruptOccured = false;
  }
}


void interruptHandler() {
 uint32_t interruptTime = millis();
 if (interruptTime - lastInterruptTime > debounceDelayMillis) {
   interruptOccured = true;
 }
 lastInterruptTime = interruptTime;
}


void printPlayerStatus(uint8_t type, uint16_t 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;
  }
}

, 👍0


3 ответа


2

Управлять этими модулями DFPlayer сложнее, чем можно предположить из примеров. Всякий раз, когда вы отправляете команду DFPlayer (например, player.setVolume(30)) модуль возвращает какое-то подтверждение или команду статуса. Вам нужно постоянно вызывать метод player.available(), а затем player.readType() и player.read() в цикле(), чтобы буфер SoftwareSerial оставался свободным, прежде чем вы попытаетесь отправить команды. Таким образом, вызов player.setVolume(30), а затем player.readFileCounts() в setup() может привести к переполнению буфера до того, как вы начнете его очищать, и буфер будет содержать непрочитанные сообщения, которые не являются ожидаемым ответом на количество файлов, что запутывает библиотеку. Еще одна вещь, которую следует учитывать, это то, что модулю требуется секунда или две для инициализации SD-карты после .begin(), и вам действительно нужно дождаться сообщения о состоянии DFPlayerCardOnline, прежде чем вы сможете запросить количество файлов.

Я написал более полную библиотеку для их реализации, но она еще недостаточно развита, чтобы ею можно было поделиться.

,

Пытался реализовать ваши предложения, но безуспешно. Есть ли у вас подобное оборудование, чтобы опробовать мой код с добавленными к нему вашими предложениями?, @albert


0

ОК... Для тех, кто ищет ответ, я нашел его сложным способом, читая файл библиотеки. При выполнении задачи Begin() в параметрах требуется COM-порт, но также разрешены еще два параметра: ACK и doReset. Затем начните (com_player, false, true); параметр ACK блокирует ответы последовательного анализа.

,

1

Мне это помогло:

int fileCounts = 0;

myDFPlayer.readFileCounts();
fileCounts = myDFPlayer.readFileCountsInFolder(0);

Serial.println(fileCounts);
,