Как воспроизводить звук на Arduino с помощью SD-карты?

Я работаю над "личным помощником" с Arduino, и у меня возникли проблемы с воспроизведением звука с SD-карты... Я использую щит под названием "Easy Shield UNO" от Simkeim, и на нем есть устройство для чтения SD-карт. Он работает, потому что я проверил его через последовательный монитор, но когда я пытаюсь воспроизвести звук, ничего не происходит. (Динамик работает) Может кто-нибудь, пожалуйста, помочь мне проверить мой код или что-то еще, чтобы понять, что не так?

Вот код, который я нашел в Интернете, я только немного изменил его...

#include "SD.h"
#define SD_ChipSelectPin 10
#include "TMRpcm.h"
#include "SPI.h"

TMRpcm tmrpcm;

void setup(){
 tmrpcm.speakerPin = 7;
 Serial.begin(9600);

 tmrpcm.setVolume(255);
}
void loop() {
  if(!SD.begin(SD_ChipSelectPin)) {
    Serial.println("SD card not found");
    return;
}
  else{
    Serial.println("SD card reading sucess");
    tmrpcm.play("test1.wav");
  }
}

, 👍1

Обсуждение

А) Пожалуйста, добавьте ссылку на щит. Б) Пробовали ли вы использовать образец скетча, прилагаемый к библиотеке, чтобы убедиться, что все работает должным образом?, @Nino

Я купил щит, когда мы жили в Китае, так что это китайский веб-сайт. https://i-item.jd.com/59763201006.html. Да, я пробовал использовать образец скетча, все работает, но звук-это всего лишь два длинных статических звука, @Renier Jr.

Когда я меняю имя файла, динамик ничего не делает, но когда я использую настоящее имя файла, динамик издает скрипучие звуки, @Renier Jr.


1 ответ


Лучший ответ:

2

Я вижу три проблемы с вашим кодом:

  • Нет особого смысла снова и снова запускать SD-карту в цикле(). Пожалуйста, переместите эту часть в setup() или куда-нибудь еще, где она не вызывается на каждой итерации цикла.

  • Вы не должны вызывать tmrpcm.play() в каждой итерации цикла (). Он не ждет, пока песня будет закончена. Он просто начинает воспроизведение (которое контролируется прерыванием по таймеру) и завершается. И каждый его вызов будет запускать файл снова при его запуске. Поэтому, вызывая его снова и снова в быстрой последовательности, вы не оставляете достаточно времени для фактического воспроизведения файла, пока вы не воспроизведете его снова с самого начала. Чтобы предотвратить это, вы можете использовать оператор if только для запуска, если в данный момент файл не воспроизводится:

      if(!tmrpcm.isPlaying()){
          tmrpcm.play("test1.wav");
      }
    
  • Вы выбираете вывод 7 в качестве выходного вывода, но вы не можете выбрать вывод свободно, потому что он должен быть подключен к используемому таймеру и, следовательно, иметь возможность ШИМ. Это не относится к контакту 7. В вики-библиотеке TMRpcm вы можете найти следующую строку в разделе "Функции":

      audio.speakerPin = 11;     set to 5,6,11 or 46 for Mega, 9 for Uno, Nano, etc.
    

    Поэтому, пожалуйста, подключите динамик к контакту 9 и используйте tmrpcm.speakerPin = 9;.

,

Привет, спасибо за помощь! Я изменил его, как ты сказал, но он все еще издает тот статичный звук... Я также попробовал пример кода TMRpcm, но мой динамик все еще издает статический звук? Как вы думаете, это может быть связано с кодом или файлом? Потому что я попробовал это с двумя другими ораторами, и они сделали то же самое..., @Renier Jr.

@RenierJr. Я снова заглянул в библиотеку и обнаружил, что вы не можете свободно выбирать используемый контакт. Он должен быть с поддержкой ШИМ и принадлежать используемому таймеру (по умолчанию Timer1). Я добавил абзац об этом в свой ответ, @chrisl

Спасибо, крисл!! Я попробовал пример кода, и он использовал контакт 9, теперь он работает, но в музыке много статики. Я попытаюсь изменить частоту дискретизации, чтобы посмотреть, сработает ли это... Еще раз спасибо за время, которое вы потратили, чтобы помочь мне!, @Renier Jr.