Оглавление:

Воспроизведение аудио-звуковых файлов (Wav) с помощью Arduino и DAC: 9 шагов
Воспроизведение аудио-звуковых файлов (Wav) с помощью Arduino и DAC: 9 шагов

Видео: Воспроизведение аудио-звуковых файлов (Wav) с помощью Arduino и DAC: 9 шагов

Видео: Воспроизведение аудио-звуковых файлов (Wav) с помощью Arduino и DAC: 9 шагов
Видео: Воспроизведение WAV файла на Arduino 2024, Июль
Anonim
Воспроизведение аудио-звуковых файлов (Wav) с помощью Arduino и DAC
Воспроизведение аудио-звуковых файлов (Wav) с помощью Arduino и DAC
Воспроизведение аудио-звуковых файлов (Wav) с помощью Arduino и DAC
Воспроизведение аудио-звуковых файлов (Wav) с помощью Arduino и DAC
Воспроизведение аудио-звуковых файлов (Wav) с помощью Arduino и DAC
Воспроизведение аудио-звуковых файлов (Wav) с помощью Arduino и DAC

Воспроизведение аудио из файла wav с SD-карты Audino. Эта инструкция покажет вам, как wav-файл на вашей SdCard может быть воспроизведен через простую схему с динамиком.

Файл wav должен быть 8-битным моно. У меня не было проблем с воспроизведением файлов с частотой 44 кГц.

Хотя качество звука невысокое, оно очень удовлетворительное.

Монитор последовательного порта используется для выбора файла. Файлы должны находиться в папке с названием adlog.

Это руководство следует из более раннего проекта, в котором я сохранял записи в формате WAV на SDCard:

В схеме используется дешевый 8-битный цифро-аналоговый преобразователь (ЦАП) и однокристальный аудиоусилитель.

Ключевые разделы для настройки прерываний были взяты из прекрасной статьи Аманды Гассаи:

Шаг 1. Требования

Требования
Требования
Требования
Требования

Arduino - я использую Mega, однако нет причин, по которым Uno не должен работать.

Считыватель SDCard - программа настроена для: MicroSD Breakout Board, регулируемой с помощью логического преобразования V2

См. Инструкции по настройке SdCard:

DAC0832 LCN - отличный 8-битный цифро-аналоговый преобразователь - несколько фунтов.

Операционный усилитель LM386 N-1 - дешевый как микросхемы

20-контактное гнездо для микросхемы

8-контактное гнездо для микросхемы

Блок питания на 9 вольт - подойдет аккумулятор.

LM336 опорное напряжение 2,5 В

Конденсатор 10 мкФ * 3 (любое напряжение более 9 В)

Резистор 10 ом

Конденсатор 50nF- (или где-то около-47nF, 56nf, 68nf- подойдет)

Конденсатор 220 мкФ

64 Ом динамик

Линейный потенциометр 10K

Кабель для соединения 8 линий данных между Arduino и схемой-

На Uno 8 подключений в линию, на Mega - попарно.

На Mega я использовал 10-контактный ленточный кабель с 10-контактным разъемом IDC. (2 провода запасные)

Гнездовые разъемы для выхода 0 В, 9 В и ЦАП

Доска из медной ленты, припой, проволока, резаки и т. Д.

Шаг 2: Технические характеристики

Технические характеристики
Технические характеристики

Последовательный установлен на 115200 бод.

Имеется поддержка платы Hobbytronics MicroSD Breakout Board с использованием Mega. Выбор микросхемы и другие порты будут меняться между Mega и Uno.

Файлы Wav должны существовать в каталоге с именем adlog. Не стесняйтесь называть его как-нибудь иначе и изменить необходимую кодировку.

Файл wav должен быть 8-битным моно. Я тестировал до 44 кГц.

Монитор последовательного порта отображает файлы WAV в папке журнала объявлений. Имена файлов отправляются из выходной строки монитора.

Размер файла ограничен только размером SdCard.

Шаг 3. Начало работы

Начиная
Начиная

Подключите кардридер SD. Это соединения для Mega.

0, 5В

CLK к выводу 52

D0 к выводу 50

D1 к выводу 51

CS к выводу 53

(См. Веб-сайт поставщиков для подключения порта Uno)

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

Нам нужно сделать небольшую схему

Мы собираемся отправить поток байтов аудио из Arduino.

Эти числа находятся в диапазоне от 0 до 255. Они представляют напряжение.

Тишина 127-128.

255 - односторонний диффузор динамика.

0 - это конус динамика в противоположную сторону.

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

Мы можем отправлять числа из 8 строк на Arduino одновременно, используя «порт».

Если мы подадим 8 линий в цифро-аналоговый преобразователь, он сделает то, что написано на жестяной банке, и выдает аналоговое напряжение, пропорциональное цифровому числу.

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

Шаг 4: Малая схема

Малая схема
Малая схема
Малая схема
Малая схема
Малая схема
Малая схема
Малая схема
Малая схема

DAC0832 LCN

Это превосходный дешевый 8-битный цифро-аналоговый преобразователь. (ЦАП)

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

Или его можно настроить так, чтобы все это выполнялось автоматически в «Проточной операции».

Процитируем руководство:

Простое заземление CS, WR1, WR2 и XFER и привязка ILE к высокому уровню позволяет обоим внутренним регистрам следовать применяемым цифровым входам (сквозным) и напрямую влиять на аналоговый выход ЦАП.

Хорошо, это четыре подключения к низкому уровню микросхемы и одно подключение к 9В - легко.

Мы не хотим никаких отрицательных напряжений, поэтому в руководстве говорится, что мы должны использовать «режим переключения напряжения», и они предоставляют диаграмму.

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

Аудиоусилитель LM386-N

В руководстве к усилителю приведена минимальная диаграмма компонентов, обеспечивающая усиление 20 (для нас это слишком много, но есть регулятор громкости).

Все, что нам нужно сделать, это добавить конденсатор между ЦАП и усилителем, чтобы мы усиливали только сигналы переменного тока.

Мы также должны добавить пару конденсаторов рядом с выводом питания каждой из наших микросхем, иначе мы получим гудение от нашего источника питания 9 В.

Шаг 5: достаньте паяльник

Достать паяльник
Достать паяльник
Достаньте паяльник
Достаньте паяльник
Достаньте паяльник
Достаньте паяльник

Поскольку схема проста, я не собираюсь вдаваться в подробности.

Вот несколько указателей:

  • Подготовьте кусок медной планки размером не менее 28 на 28 отверстий. (Да, я знаю, что нейрохирурги могут сделать его меньше)
  • Если вы собираетесь закрепить его винтами, учтите их с самого начала!
  • Установите микросхемы на розетки. Вставляйте фишки только тогда, когда все проверено.
  • Держите входные провода подальше от выхода.
  • Соблюдайте правильную полярность конденсаторов.
  • См. Схему базового вида источника опорного напряжения LM336. Регулировочная ножка не используется и ее можно обрезать.
  • Обратите внимание на прямое подключение к выводу 8 ЦАП - это очень полезно для тестирования.
  • Я подключился к Audino с помощью ленточного кабеля и 10-контактного разъема IDC.
  • На Uno соединения расположены по прямой линии - вы можете обнаружить, что расположение 8 входных соединений в одну прямую линию позволяет вам подключаться к Arduino с помощью купленного, готового 8-контактного разъема,

Когда все будет готово - проверьте пайку и проверьте зазоры между медными дорожками.

Я считаю, что ножовочное полотно для младших моделей 36 tpi очень полезно для очистки от мусора. Я удаляю установочные штифты лезвия и вставляю кончик лезвия в гусеницу. Очевидно, лезвие не в раме.

Шаг 6: Тестирование ЦАП

Тестирование ЦАП
Тестирование ЦАП

Оставьте соединение между схемой и Arduino выключенным.

Установите регулятор громкости на вашей цепи на полпути.

Включите питание 9 В постоянного тока на новую цепь.

Убедитесь, что схема в порядке - я не несу ответственности за вашу схему!

Выключить

Подключите вашу схему к Arduino.

На Mega используйте контакты 22-29. (ПОРТА) Не перепутайте два контакта 5V выше!

На Uno используйте контакты 0-7. Это ПОРТД

Подключите 0 В источника питания к 0 В на Arduino.

Включите.

Откройте эту тестовую программу DAC_TEST

Для UNO заменить все ссылки на PORTA на PORTD.

Заменить DDRA на DDRD - эта инструкция устанавливает все 8 строк для вывода за один раз. Это регистр направления данных.

Установите серийный монитор на 115200.

Подключите вольтметр между выходом ЦАП и ОВ.

Программа установит выход на 255 - все линии включены - максимальное напряжение.

Выход 128 - половина максимального напряжения.

Выход 0- нулевое напряжение (или, вероятно, почти нулевое).

Затем он будет поэтапно: 1, 2, 4, 8, 16, 32, 64, 128

Напряжение должно постоянно увеличиваться.

Если напряжение падает, а число увеличивается, возможно, два соединительных провода перевернуты.

Вы также должны услышать тихий щелчок динамика при изменении напряжения.

Шаг 7: чтение заголовка Wav

Чтение заголовка Wav
Чтение заголовка Wav

Файлы Wav сохраняются с указанной частотой и размером данных.

Эта информация содержится в заголовке размером 44 байта в начале файла wav.

Хотя некоторые программы расширяют заголовок (после байта 35), что затрудняет определение местоположения размера данных.

Чтобы прочитать заголовок, мы создаем буфер и копируем начало файла.

Частота хранится в 4 байтах, начиная с 24 байтов в файле.

// частота чтения указана в заголовке wav файла

byte headbuf [60]

tempfile.seek (0);

tempfile.read (headbuf, 60);

retval = headbuf [27];

retval = (retval << 8) | headbuf [26];

retval = (retval << 8) | headbuf [25];

retval = (retval << 8) | headbuf [24];

Serial.print (F ("Частота файла"));

Serial.print (retval);

Лучший способ найти информацию о размере данных - это поискать слово «данные» в заголовке.

Затем извлеките следующие за ним 4 байта, которые составляют длинное значение

беззнаковый длинный retval;

int mypos = 40;

for (int i = 36; i <60; i ++) {

if (headbuf == 'd') {

if (headbuf [i + 1] == 'a') {

if (headbuf [i + 2] == 't') {

if (headbuf [i + 3] == 'a') {

// наконец-то он у нас есть

mypos = я + 4;

i = 60;

}

}

}

}

}

tempfile.seek (mypos);

retval = headbuf [mypos + 3];

retval = (retval << 8) | headbuf [mypos + 2];

retval = (retval << 8) | headbuf [mypos + 1];

retval = (retval << 8) | headbuf [mypos];

Хорошо, у нас есть длина и частота данных!

Аудиоданные следуют за 4 байтами, составляющими значение длины данных.

Шаг 8: Прерывание, прерывание…

Прерывание, прерывание…
Прерывание, прерывание…

Мы используем информацию о частоте для создания программного прерывания на требуемой частоте или около нее.

Не всегда можно точно установить прерывание, но этого достаточно. Частота, считанная из файла, передается в подпрограмму setintrupt.

void setintrupt (частота с плавающей запятой) {число с плавающей запятой = 8; // 8 для 8-битных таймеров 0 и 2, 1024 для таймера 1 байт

setocroa = (16000000 / (freq * bitval)) - 0,5;

// Значение setocroa требует вычитания -1. Однако добавление 0,5 раунда к ближайшему 0,5

// Разрешение таймера ограничено

// Окончательно определяется величиной битового значения

cli (); // отключение прерываний // установка прерывания таймера 2

TCCR2A = 0; // устанавливаем весь регистр TCCR2A в 0

TCCR2B = 0; // то же самое для TCCR2B

TCNT2 = 0; // инициализируем значение счетчика 0

// установить регистр сравнения для приращений частоты (Гц)

OCR2A = setocroa; // = (16 * 10 ^ 6) / (частота * 8) - 1 (должно быть <256)

// включаем режим CTC

TCCR2A | = (1 << WGM21); // Устанавливаем бит CS21 для 8 предделителя

TCCR2B | = (1 << CS21); // разрешить прерывание сравнения таймера

// TIMSK2 | = (1 << OCIE2A); // это работает, как и следующая строка

sbi (TIMSK2, OCIE2A); // разрешить прерывание по таймеру 2

sei (); // разрешаем прерывания

Взыскательные читатели заметят sbi (TIMSK2, OCIE2A)

Я установил пару (приобретенных через Интернет) функций для установки и очистки битов регистра:

// Определяет очистку битов регистра # ifndef cbi

#define cbi (SFR, бит) (_SFR_BYTE (SFR) & = ~ _BV (бит))

#endif

// Определяет установку битов регистра

#ifndef sbi

#define sbi (sfr, бит) (_SFR_BYTE (sfr) | = _BV (бит))

#endif

Эти функции обеспечивают простой вызов для установки или сброса прерывания.

Итак, прерывание запущено, что мы можем сделать?

Шаг 9: прерывания и двойная буферизация

Прерывания и двойная буферизация
Прерывания и двойная буферизация
Прерывания и двойная буферизация
Прерывания и двойная буферизация

При 22 кГц байт аудиоданных выводится каждые 0,045 мс.

512 байт (размер буфера) читаются за 2,08 мс.

Таким образом, буфер не может быть прочитан с SDCard за один цикл записи.

Однако 512 байт записываются в порт за 23,22 мс.

Итак, все, что нам нужно сделать, это настроить чтение нового файла каждый раз, когда буфер опустеет, и у нас будет достаточно времени, чтобы получить данные до того, как потребуется новый блок данных… Предположим, мы используем два буфера, опустошая один по мере заполнения другого.

Это двойная буферизация.

Чтение файла будет замедлено повторным прерыванием, но оно будет выполнено.

Я установил два буфера по 512 байт, которые называются bufa и bufb.

Если флаг aready верен, мы читаем с порта, иначе мы читаем с порта b

Когда позиция буфера (bufcount) достигает размера буфера (BUF_SIZE 512), мы устанавливаем флаг readit в значение true.

Процедура цикла void ищет этот флаг и запускает чтение блока:

if (readit) {if (! aready) {

// инициируем чтение блока SDCard в bufa

tempfile.read (буфа, BUF_SIZE);

} еще {

// инициируем чтение блока SDCard в bufb

tempfile.read (bufb, BUF_SIZE);

}

readit = false;

}

По завершении подпрограмма отмечает readit = false.

В рамках процедуры прерывания мы должны проверить, что цикл void завершился, проверив, если readit == false.

В этом случае мы сигнализируем, что требуется еще одно чтение, и переключаем флаг области для переключения буферов.

Если SD-карта все еще читает, мы должны отследить одно чтение (счетчик--; bufcount--;) и выйти из прерывания, чтобы повторить попытку позже. (Щелчки в выходном аудиосигнале означают, что это произошло.)

Когда все данные прочитаны, прерывание отменяется, порт переустанавливается на среднее значение напряжения 128 и аудиофайл закрывается.

Перед первым запуском сценария dac2.ino установите громкость на 50%. Это будет слишком громко, но лучше, чем 100%!

Если ваш регулятор громкости работает в обратном направлении, поменяйте местами провода на противоположных концах потенциометра 10K.

Дай мне знать, как это звучит.

Рекомендуемые: