Недавно мы рассмотрели применение звуков в проекте, без использования дополнительных средств, использую по сути esp8266, усилитель и динамик. Но если в проекте предполагается использовать голос или музыку, лучше всё таки использовать внешний ЦАП, а если объёмы данных большие, то и microsd карту. Я впервые работаю с платой на базе esp32, поэтому добавим её в среду, таким же способом, как мы ранее добавляли ESP8266 в Arduino IDE. Затем на базе имеющихся библиотек сделаем сегодня плеер, с переключением файлов по нажатию кнопки. Заходим в настройки среды Arduino IDE.
Далее нужно указать ссылку на репозиторий, откуда мы скачаем необходимые библиотеки.
https://dl.espressif.com/dl/package_esp32_index.json
В настройках видим пункт дополнительных ссылок для менеджера плат, но у нас уже есть запись с ESP8266, поэтому, чтобы не нарушить работоспособности, я нажимаю справа на значок и добавляю новый репозиторий в новой строке. Но можно и просто разделить их запятыми.
Затем установим набор плат, для возможности прошить наш devboard. Перейдём в “инструменты” -> “плата” -> “менеджер плат…”
В поиске вводим ESP32 и устанавливаем необходимый набор плат. Устанавливаем
Следующим этапом нам нужно скачать архив с примером
https://github.com/schreibfaul1/ESP32-audioI2S
В скачанном архиве, с корня я запустил файл I2Saudio.
В примере сразу бросается в глаза странность, что как раз воспроизведение с sd карточки закомментировано
// audio.connecttoSD("/xxx.mp3");
// audio.connecttohost("http://www.wdr.de/wdrlive/media/einslive.m3u");
// audio.connecttohost("http://macslons-irish-pub-radio.com/media.asx");
// audio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.aac"); aacaudio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.mp3");
// audio.connecttospeech("Wenn die Hunde schlafen, kann der Wolf gut Schafe stehlen.", "de");
Я закинул на карточку 3 аудио-записи, с разными индексами. Для теста раскомментировал строчку и указал имя файла, остальное удалил
audio.connecttoSD("/ishome1.mp3");
Скомпилировал проект – вышла ошибка на счёт файла “audio.h”. Все действия я делал на голой Arduino IDE и ещё не устанавливал дополнительных библиотек звука. Необходимый файл лежал в папке src, и я просто поменял первые куски кода
#include "src/Audio.h"
Компиляция прошла успешно. Теперь соберём всё в железе. Схему можно взять из папки, скачанной с github. Сначала соберём схему с
PCM5102A
Мой DevBoard выглядит немного по другому, но сути это не меняет, назначения выводов такие же, только 5в, 3.3в и земля немного в разных местах.
Если вы первый раз работаете с ESP32, то после компиляции, когда Arduino IDE пытается соединиться с платой, нужно нажать кнопку boot на esp32, иначе получите ошибку
A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header
Звук играет отлично! Это не то, что эмуляция i2s на ноге ESP8266. Хорошо работает и наушники и обычные аудио-системы с усилителем. Также протестировал копию Adafruit MAX98357 I2S Class-D Mono Amp, на базе той же микросхемы, что и в оригинале.
Такая плата идёт сразу с усилителем, и можно использовать её в готовых поделках. На выход сразу подключается динамик.
Теперь посмотрим, что интересного есть в библиотеке. Первое что бросается в глаза – регулировка громкости. Значит без проблем можно любым способом менять громкость по ходу проекта.
audio.setVolume(6); // 0...21
Второй нюанс. Понятно, что композиция меняется путем смены файла-источника
audio.connecttoSD("/xxx.mp3");
А что заставляет играть её? В бесконечном цикле проекта есть функция
audio.loop();
Сначала я думал, что достаточно её объявить один раз и она запустит процесс аудио, но нет, она должна постоянно работать в теле void loop() {}. А как же управлять этим всем? В примере этого нет, но если покопаться в файле audio.h можно найти много интересного. Давайте сделаем три аппаратных кнопки.
#define nextsong 33 // кнопка следующей песни
#define stopsong 32 // кнопка остановки песни
#define pausesong 14 // кнопка паузы песни
Теперь переведём их в режим pull-ip
pinMode(nextsong, INPUT_PULLUP); // Вывод смены песни переключаем на вход
pinMode(stopsong, INPUT_PULLUP); // Вывод остановки песни переключаем на вход
pinMode(pausesong, INPUT_PULLUP); // Вывод паузы песни переключаем на вход
Для остановки песни используется команда audio.stopSong(); . Напишем для этой команды обработку события по нажатию кнопки
if (digitalRead(stopsong) == LOW) // Если нажата кнопка остановки песни
{
delay(200);
Serial.println("stop");
audio.stopSong();
}
Аналогичную команду можно сделать для паузы.
if (digitalRead(pausesong) == LOW) // Если нажата кнопка паузы песни
{
delay(200);
Serial.println("pause");
audio.pauseResume();
}
Я не делал отдельно кнопки “назад” “вперёд”, а просто реализовал следующий трек, путём изменения переменной в тексте строки. Мои композиции назывались ishome1, ishome2, ishome3, собственно я создал массив с названием трека
char song[] = "/ishome1.mp3";
И переменную состояния songstate. Вы же можете реализовать это вам угодно
if (digitalRead(nextsong) == LOW) // Если нажата кнопка следующей песни
{
delay(200);
songstate++;
if (songstate > 3) {
songstate = 1;
}
delay(200);
Serial.println("next");
song[7] = songstate + 48; // Меняем индекс песни в названии массива. Из-за особенностей ASCII +48
audio.connecttoSD(song); // Воспроизводим новую песню
}
Итоговая строчка
audio.connecttoSD(song);
Заберёт изменённое название трека и поставит её автоматически на воспроизведение. Так вы можете легко влиять на воспроизведение файлов по ходу проекта. Как можно убедиться из терминала, а главное благодаря своим ушам, что всё прекрасно работает
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.