Самодельная ударная установка. Как ускорить время отклика после срабатывания датчика?

Я пытаюсь сделать псевдо-ударную установку с помощью моего Arduino Due и пары резисторов, чувствительных к силе (активируется пальцами, без барабанных палочек). Пока в своем тестировании я использую только один FSR. Я подключил устройство для чтения SD-карт и записал туда WAV-файл (44 100 Гц, 16 бит, стерео). В моем «Цикле» я считываю сопротивление FSR, чтобы узнать, сработало ли оно, а затем соответствующим образом воспроизводю файл WAV. Работает, но не так быстро. Если этот проект будет работать, время отклика должно быть намного быстрее.

Вот мой код:

#include "SD.h" //Библиотека для чтения SD-карты
#include "SPI.h" //Библиотека SPI для SD-карты
#include <Audio.h>

#define SD_ChipSelectPin 2

const int FSR_PIN = A0; // Вывод, подключенный к FSR/резисторному делителю

const float VCC = 4.875; 
const float R_DIV = 10000.0; 

void setup() 
{
  Serial.println("Starting Drum Kit!");
  Serial.begin(9600);
  while (!Serial) {}

  pinMode(FSR_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);


  Serial.print("Initializing SD Card...");
  if (!SD.begin(SD_ChipSelectPin)) {
    Serial.println("FAILED!");
    while(true);
  }
  Serial.println("done");

  // 44100 кГц стерео => частота дискретизации 88200
  // 100 мс предварительной буферизации.
  Audio.begin(88200, 100);

  void loop() 
{
  File snare_file;
  short snare_buffer[1024];
  int fsrADC = analogRead(FSR_PIN);
  if (fsrADC > 20) // Если аналоговое показание не равно нулю
  {
    Serial.println(String(fsrADC));

    snare_file = SD.open("606snare.wav");
    while (snare_file.available()) {   
      snare_file.read(snare_buffer, 1024);
      Audio.prepare(snare_buffer, 1024, 1024);
      Audio.write(snare_buffer, 1024);
    }
    snare_file.close();
  }
}

Если я удерживаю датчик (постоянное срабатывание), файл воспроизводится быстрее всего каждые полсекунды. Вот серийный вывод:

15:12:28.453 -> Initializing SD Card...done
15:12:28.487 -> 1023
15:12:28.930 -> 1023
15:12:29.510 -> 1023
15:12:30.050 -> 1023
15:12:30.628 -> 1023
15:12:31.136 -> 1023
15:12:31.744 -> 1023
15:12:32.328 -> 1023
15:12:32.834 -> 1023
15:12:33.411 -> 1023
15:12:33.955 -> 1023

Я пытался поиграться с загрузкой файла и буфера в разделе setup, но не могу заставить его работать должным образом. Также не так много документации по библиотеке Audio.

Если вы знаете лучший способ ускорить это или мне следует использовать другую библиотеку, сообщите мне об этом.

, 👍1

Обсуждение

Вы написали, что пытались загрузить файл в setup(), но это не сработало. Как это не сработало? Я думаю, что перемещение загрузки туда действительно занимает много времени. Хотя с постоянной загрузкой звука могут возникнуть проблемы, когда вам нужно загрузить несколько файлов для нескольких барабанных пэдов., @chrisl

Я попытался создать глобальный файл snare_buffer. Затем в настройках я открывал файл, читал его в глобальный sare_buffer и закрывал файл. Затем в цикле я бы вызвал две команды Audio: Audio.prepare и Audio.write. Это привело к тому, что звук не воспроизводился. Я не уверен, как работает аудио библиотека. Документации на него было не так много. Не уверен, что есть лучший способ или лучшая библиотека., @alexs973

Я бы попытался также выполнить подготовку в настройке, а затем вызвать запись только в цикле. Также не закрывает файл. Если это по-прежнему не дает вам требуемой производительности, вам может понадобиться внешний проигрыватель, который просто запускается Arduino., @chrisl


1 ответ


1

На самом деле это не "решение", но оно может помочь вам выяснить, в чем заключается настоящая проблема.

Проверьте, какие операторы в функции loop занимают больше всего времени;

  1. int fsrADC = AnalogRead(FSR_PIN);
  2. Serial.println(String(fsrADC));
  3. snare_file = SD.open("606snare.wav");
  4. пока (snare_file.available()) {
  5. snare_file.read(snare_buffer, 1024);
  6. Audio.prepare(snare_buffer, 1024, 1024);
  7. Audio.write(snare_buffer, 1024);
  8. snare_file.close()

По возможности попробуйте улучшить самый трудоемкий элемент.

Некоторые возможности, которые вы можете попробовать в описанных выше шагах:

  1. Не используйте AnalogRead, а используйте прямые команды порта
  2. Удалите это полностью или, по крайней мере, удалите экземпляр String.
  3. Вы мало что можете здесь сделать, за исключением того, что не используете файловую систему, а читаете сырой SD (у вас могут возникнуть проблемы с получением файлов на SD) без специальной программы на вашем ПК.
  4. Не уверен, стоит ли его улучшать.
  5. Чтение меньшего количества байтов, хотя это может даже ухудшить ситуацию. Или прочитайте байты ПЕРЕД ожиданием триггера (если вы знаете, какой семпл будет воспроизводиться).
  6. Выполните подготовку, как перед триггером, как 5, если это возможно.
  7. Не уверен насчет этого... Скорее всего, вы не сможете одновременно открывать слишком много файлов.

Афаик в моем синтезаторе (Korg Kronos) читает из всех семплов начальную часть, то есть может запускать данные из ОЗУ, а остальное считывается через SSD (в вашем случае SD). Однако у вас может не хватить памяти в Arduino для этого.

,

Я знаю, что это не оператор AnalogRead или print. Если я прокомментирую все остальное и просто оставлю эти два в цикле(), время отклика будет очень быстрым. Должен быть способ прочитать мой файл в буфер в setup(). Я думаю, что основным узким местом является открытие и закрытие файла каждый раз. Я не уверен, как обойти это., @alexs973

С помощью millis вы можете точно рассчитать время (запустить каждую команду 1000 раз, вывести время ПОСЛЕ и разделить его на 1000). Затем вы должны проверить в библиотеке, что именно происходит. Когда открытие/закрытие файла занимает слишком много времени, объедините все файлы, которые вам нужны, и прочитайте вручную из части большого файла то, что вам нужно., @Michel Keijzers