Posted by lex232 on

MP3 на ESP32. Музыка и звуки с SD карты. Тестируем PCM5102A и MAX98357A

MP3 на ESP32. Музыка и звуки с SD карты. Тестируем PCM5102A и MAX98357A

Недавно мы рассмотрели применение звуков в проекте, без использования дополнительных средств, использую по сути 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

Смотрите также:  Proteus. Как добавить платы Arduino и получить прошивку hex в IDE

Мой 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);

Заберёт изменённое название трека и поставит её автоматически на воспроизведение. Так вы можете легко влиять на воспроизведение файлов по ходу проекта. Как можно убедиться из терминала, а главное благодаря своим ушам, что всё прекрасно работает

Смотрите также:  Знакомимся с EEPROM AVR в Arduino IDE.