Установка ESP32 в Arduino IDE (руководство для ОС Windows)
Платы ESP 32 оснащены микроконтроллером ESP32-WROOM-32 с интерфейсом Wi-Fi, подключаются к компьютеру через WiFi или USB порт.
О том как установить «Arduino IDE» можно прочитать в статье Wiki — Установка среды разработки Arduino IDE для Windows .
Настройка Arduino IDE:
Писать скетчи под микроконтроллер ESP32 можно в среде разработки «Arduino IDE», но перед загрузкой скетча нужно выбрать тип используемой платы из списка меню «Инструменты» > «Плата», а там по умолчанию нет плат ESP32. Вся настройка сводится к тому, что бы в этом списке меню появились эти платы.
В среде «Arduino IDE» имеется «Менеджер плат» который поможет быстро добавить интересующие платы в список. Для этого нужно выполнить следующие действия:
Откройте «Arduino IDE» и выберите пункт меню: «Файл» > «Настройки»
В открывшемся окне заполните поле «Дополнительные ссылки для Менеджера плат» введя в него строку: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json И нажмите на кнопку «Ok».
Запустите «Менеджер плат» выбрав пункт меню «Инструменты» > «Плата» > «Менеджер плат».
В открывшемся окне «Менеджер плат» выберите пункт «esp32 by Espressif Systems» из списка сборок и нажмите на кнопку «Установка» (при желании можно выбрать версию устанавливаемой сборки).
Дождитесь окончания установки сборки.
После успешной установки сборки, в списке, напротив её названия «esp32 by ESP32 Systems» появится фраза «INSTALLED». Закройте «Менеджер плат» нажав на кнопку «Закрыть».
На этом настройка «Arduino IDE» завершена! Теперь в списке плат есть раздел «ESP32 Arduino».
Первая программа:
Самая первая программа для любой платы под управлением микроконтроллера — это «Hello, World!» (вывод строки) или «Blink» (мигание светодиодом). Данная статья не будет исключением, загрузим скетч для мигания светодиодом.
Для работы с платами ESP 32 нужно в пункте меню «Инструменты» > «Плата» > «ESP32 Arduino» выбрать соответствующую плату. В нашем случае это будет Piranha ESP32.
Так же нужно выбрать COM-порт после подключения платы к компьютеру через USB порт. На рисунке выбран порт «COM10», но Вам нужно выбрать тот порт, который появился у Вас в списке доступных портов после подключения платы. Если после подключения платы новый порт не появился, значит не установлен драйвер для чипа CH340C ссылки на драйверы указаны в конце данной статьи.
Осталось загрузить скетч и проверить его работу.
Скетч «Blink» можно загрузить из базовых примеров Arduino в меню «Файл» > «Примеры» > «01.Basic» > «Blink» . Макрос «LED_BUILTIN» содержит номер вывода к которому подключён встроенный в Piranha ESP32 светодиод. Если Вы используете другую плату, то необходимо указать соответствующий вывод в начале скетча, например:
#undef LED_BUILTIN #define LED_BUILTIN 2
или выбрать плату соответствующую Вашей в пункте меню «Инструменты» > «Плата» > «ESP32 Arduino»
Нажмите левой кнопкой мыши на кнопку загрузки скетча в плату (или на клавиатуре + ). Начнётся компиляция и загрузка двоичного кода в микроконтроллер платы.
В зависимости от конфигурации системы и используемой платы, возможно понадобится перевести плату в режим программирования. Для этого зажмите на плате одновременно RESET и BOOT, а затем отпустите RESET не отпуская BOOT. Через несколько секунд можно отпустить BOOT, начнётся загрузка кода в микроконтроллер платы.
Загрузка завершена!
Ссылки
Учебное пособие по звуку I2S для ESP32
В этом руководстве вы узнаете, как использовать протокол связи I2S для передачи цифровых звуковых сигналов для записи и визуализации данных микрофона и воспроизведения музыки из внутренней памяти, а также с внешней SD-карты.
Мы также сравним разные микроконтроллеры и увидим, почему мы предпочитаем микроконтроллер ESP32 для наших проектов I2S.
Зачем нам нужен протокол I2S?
Если мы хотим воспроизвести цифровой аудиофайл с помощью платы микроконтроллера, мы должны рассмотреть всю цепочку цифрового аудио. Следующий схематический рисунок показывает, как аудиофайл сохраняется на SD-карте и считывается с платы микроконтроллера. Затем плата подключается к динамику через цифровой контакт и землю.
В моем случае у меня есть образец аудиофайла с частотой дискретизации 44,1 кГц, стереоформатом и глубиной звука 16 бит. На нашей стороне ввода, где мы хотим прочитать музыкальный файл, у нас нет проблем, потому что соединение SPI достаточно быстрое, чтобы качество не ухудшалось во время передачи.
Но со стороны выхода мы должны преобразовать цифровой сигнал в аналоговый сигнал. Это делается с помощью цифро-аналогового преобразователя (ЦАП). В зависимости от используемого микроконтроллера возникают разные проблемы:
- Arduino и ESP8266: платы Arduino, а также ESP8266 в целом не имеют внутреннего ЦАП, и поэтому вам придется создавать ЦАП с внешними компонентами.
- ESP32: ESP32 имеет внутренний ЦАП для создания аналогового выходного сигнала, однако ЦАП имеет только 8-битное разрешение. Поскольку у нас есть 16-битный входной сигнал, мы немного потеряем качество.
Но как мы можем преобразовать цифровые данные из файла WAVE в динамик? Решением этой проблемы является протокол связи I2S, который поддерживает от 4 до 32 бит данных на выборку. Чтобы сделать нашу жизнь еще проще, мы используем коммутационную плату для аудио MAX98357 I2S. Но сначала мы углубимся в протокол связи I2S.
Протокол связи I2S
В этой части руководства по I2S мы хотим подробнее рассмотреть протокол связи I2S. Поэтому мы затрагиваем три важные темы.
- 3-проводное соединение I2S
- Сетевые компоненты I2S
- Временная диаграмма I2S
В следующей таблице показано, какие платы имеют интерфейс I2S, а какие нет.
Имеет интерфейс I2S | Не имеет интерфейса I2S | |
---|---|---|
Arduino | Платы Arduino Arduino Due, Arduino MKR Zero, Arduino MKR1000 WiFi | с микроконтроллером ATmega328P, такие как Arduino Uno или Arduino Nano. |
ESP | ESP8266 ESP32 |
Из таблицы видно, что только некоторые специальные платы Arduino имеют интерфейс I2S, но не наиболее используемые платы, такие как Arduino Uno. Также все платы ESP8266 и ESP32 поддерживают интерфейс I2S, поэтому я рекомендую использовать для этого руководства плату на базе микроконтроллера ESP8266 или ESP32. В моем случае я использую микроконтроллер ESP32, потому что библиотеки, которые мы используем, поддерживают ESP32 лучше, чем ESP8266, по моему опыту.
3-проводное соединение I2S
Протокол I2S использует для связи три провода.
Последовательные часы (SCK), также называемые линией битовых часов (BCLK), используются для получения всех компонентов в одном цикле. Частота тактовых импульсов последовательного интерфейса определяется следующим образом:
Частота = Частота дискретизации * Количество бит на канал * Количество каналов.Для моего WAVE-файла, который я использую в этом руководстве, мы уже знаем следующие переменные:
- Частота дискретизации: 44,1 кГц
- Бит на канал: 16
- Количество каналов: 2
Следовательно, тактовая частота последовательного интерфейса составляет 44,1 кГц * 16 * 2 = 1,411 МГц.
Вторая линия протокола связи I2S - это провод выбора слова (Word Select - WS) или выбора кадра (Frame Select - FS), который различает левый или правый канал.
- Если WS = 0 → используется канал 1 (левый канал)
- Если WS = 1 → используется канал 2 (правый канал)
Последний провод - это линия последовательных данных (Serial Data - SD), по которой полезная нагрузка передается с двумя дополнениями. Важно, чтобы старший бит передавался первым (сначала MSB), потому что передатчик и приемник могут иметь разную длину слова. Следовательно, ни передатчик, ни приемник не должны знать, сколько битов передается. Но что произойдет, если длина слова между передатчиком и приемником не совпадает?
- Если WS приемника > WS передатчика → слово усекается (младшие значащие биты данных устанавливаются в 0)
- Если WS приемника < WS передатчика → биты после LSB игнорируются
Сетевые компоненты I2S
Если есть несколько компонентов I2S, подключенных друг к другу, я называю это сетью I2S. Компоненты сети имеют разные имена, а также разные функции. На следующем рисунке показаны три разные сети, которые я опишу.
На первом изображении у нас есть передатчик, а также приемник. Передатчиком может быть плата ESP NodeMCU, а приемником - плата аудиоразъема I2S, которую мы описываем в следующем разделе. Также у нас есть три провода для подключения устройств I2S.
В этом первом случае передатчик является ведущим, потому что ведущий управляет последовательными линиями синхронизации (SCK) и линиями выбора слова (WS). На втором рисунке мы видим обратное, потому что получатель сообщений I2S также может быть ведущим. Следовательно, линии SCK и WS начинаются от приемника и заканчиваются на передатчике.
На третьем рисунке показано, что внешний контроллер также может быть ведущим устройством, которое генерирует SCK и WS. Контроллер подключен к узлам в сети.
Во всех сетях I2S есть только одно ведущее устройство. Может быть несколько других компонентов, которые принимают или передают звуковые данные.
Временная диаграмма I2S
Чтобы лучше понять поведение, а также функциональность протокола связи I2S, мы взглянем на следующую временную диаграмму I2S.
На временной диаграмме вы видите все три линии: SCK, WS и SD. Сначала у нас есть наши последовательные часы, которые имеют частоту дискретизации * бит на канал * количество каналов. В нашем примере 1,411 МГц. Второй канал - это строка выбора слова, которая изменяется от 1 для правого звукового канала до 0 для левого канала.
Из строки последовательных данных мы видим, что данные отправляются в каждом тактовом цикле на заднем фронте (красная пунктирная линия) → от HIGH до LOW. Для связи I2S также можно отправлять данные при изменении с НИЗКОГО на ВЫСОКИЙ.
Также мы видим, что строка WS изменяется за один такт до того, как будет передан самый старший бит (MSB). Это дает получателю время сохранить предыдущее слово и очистить входной регистр для следующего слова. MSB отправляется, когда SCK изменяется после изменения WS.
Плата MAX98357 I2S Audio Breakout
После того, как мы узнали, что можем использовать протокол связи I2S для получения звуковых данных из микроконтроллера без какого-либо снижения качества, следующая проблема заключается в том, что мы должны декодировать сигналы I2S в аналоговые сигналы, а также нам нужен усилитель для использования динамика.
- Декодер из сигнала I2S в аналоговый сигнал, потому что динамики работают только с аналоговыми сигналами.
- Усилитель увеличивает мощность аналогового сигнала для увеличения интенсивности звука.
MAX98357 - это входной усилитель с цифровой импульсно-кодовой модуляцией (PCM), который декодирует сигнал I2S в аналоговый сигнал с помощью цифроаналогового преобразователя (DAC), а также имеет встроенный усилитель. На следующем рисунке показана упрощенная блок-схема из таблицы MAX98357.
Из блок-схемы MAX98357 вы видите, что сначала сигнал I2S преобразуется в аналоговый сигнал через ЦАП, а послесловия усиливаются усилителем с заранее заданной регулировкой усиления.
Спецификация платы Audio Breakout Board MAX98357
Вы можете купить MAX98357 в качестве коммутационной платы у Adafruit или SparkFun. Продукция точно такая же. В следующей таблице показано техническое описание MAX98357.
Adafruit MAX98357A или SparkFun MAX98357A | Значение |
---|---|
Диапазон напряжения питания | 2,7… 5,5 В |
Выходная мощность | 3,2 Вт на 4 Ом при 5 В 1,8 Вт на 8 Ом при 5 В |
Выбор выходного канала | влево, вправо или влево / 2 + вправо / 2 (по умолчанию) |
Частота дискретизации | 8 кГц… 96 кГц |
Разрешение выборки | 16/32 бит |
Ток покоя | 2,4 мА |
Усилитель класса | D |
Коэффициент усиления | 3 дБ… 15 дБ (по умолчанию: 9 дБ) |
Требуются часы памяти (MCLK)? | Нет |
Рабочее напряжение MAX98357 составляет от 2,7 В до 5,5 В. Поэтому вы можете запитать микроконтроллер с платой на базе Arduino (5 В) или ESP (3,3 В). Выходная мощность составляет 3,2 Вт для динамика с сопротивлением 4 Ом и 1,8 Вт для динамика с сопротивлением 8 Ом.
Конфигурация платы по умолчанию - «моно», то есть левый и правый сигналы объединяются вместе для управления одним динамиком. Если вы хотите переключиться на стереозвук, вам нужно разрезать моно-перемычку на плате и припаять стерео соединение для левого или правого канала.
Частота дискретизации MAX98357 находится в диапазоне от 8 кГц до 96 кГц, поэтому музыка в нашем примере с частотой дискретизации 44,1 кГц идеально подходит для этой частоты дискретизации. Разрешение выборки составляет 16 или 32 бита, а ток покоя очень низкий - 2,4 мА.
Поскольку усилитель использует широтно-импульсную модуляцию для управления выходными устройствами, он относится к усилителю класса D. Коэффициент усиления усилителя составляет от 3 дБ до 15 дБ с коэффициентом усиления по умолчанию 9 дБ. В следующей таблице показано, как изменить коэффициент усиления. Ключевым моментом является то, что вывод усиления должен быть подключен к другим выводам, чтобы изменить коэффициент усиления.
Усиление | Подключение контакта GAIN |
---|---|
15 дБ | Подключен к GND через резистор 100 кОм |
12 дБ | Подключен к GND |
9 дБ | Без подключения (по умолчанию) |
6 дБ | При подключении к VDD / Vin |
3 дБ | Подключен к VDD / Vin через резистор 100 кОм |
Как записывать и визуализировать данные с помощью микрофона I2S
В первом примере мы начинаем записывать и визуализировать звуковые данные с микроконтроллера микрофона I2S SPH0645 от adafruit. В этом примере мы используем микроконтроллер ESP32 NodeMCU.
На следующем рисунке показана проводка между ESP32 NodeMCU и коммутационной платой SPH0645.
Важно подключать микроконтроллер I2S только к выводу 3,3 В. Следующий код Arduino визуализирует аналоговые звуковые данные в последовательном плоттере Arduino.
#include "driver/i2s.h" const i2s_port_t I2S_PORT = I2S_NUM_0; void setup() < Serial.begin(115200); esp_err_t err; // The I2S config as per the example const i2s_config_t i2s_config = < .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX), // Receive, not transfer .sample_rate = 16000, // 16KHz .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, // could only get it to work with 32bits .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, // use right channel .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // Interrupt level 1 .dma_buf_count = 4, // number of buffers .dma_buf_len = 8 // 8 samples per buffer (minimum) >; // The pin config as per the setup const i2s_pin_config_t pin_config = < .bck_io_num = 26, // Serial Clock (SCK) .ws_io_num = 25, // Word Select (WS) .data_out_num = I2S_PIN_NO_CHANGE, // not used (only for speakers) .data_in_num = 33 // Serial Data (SD) >; // Configuring the I2S driver and pins. // This function must be called before any I2S driver read/write operations. err = i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL); if (err != ESP_OK) < Serial.printf("Failed installing driver: %d\n", err); while (true); >err = i2s_set_pin(I2S_PORT, &pin_config); if (err != ESP_OK) < Serial.printf("Failed setting pin: %d\n", err); while (true); >Serial.println("I2S driver installed."); > void loop() < // Read a single sample and log it for the Serial Plotter. int32_t sample = 0; int bytes_read = i2s_pop_sample(I2S_PORT, (char *)&sample, portMAX_DELAY); // no timeout if (bytes_read >0) < Serial.println(sample); >>В первой строке мы включаем библиотеку I2S для ESP32 и определяем используемую структуру выводов I2S, потому что только GPIO25 и GPIO26 подключены к внутреннему 8-битному ЦАП, что также показано в распиновке ESP32.
В функции настройки мы устанавливаем скорость передачи 115200, которая должна соответствовать скорости передачи в последовательном плоттере Arduino IDE, где мы отображаем аналоговые звуковые данные.
Если мы получим какую-либо ошибку во время выполнения кода, мы можем получить доступ к ошибке с помощью переменной err.
Следующим шагом в коде Arduino является определение структуры связи I2S. Устанавливаем следующие настройки:
- установите режим I2S на RX для получения данных I2S
- используйте частоту дискретизации по умолчанию 16 кГц
- установите бит на выборку равным 32, а не 16
- мы используем только правый канал микрофона
- мы используем 4 буфера, каждый длиной 8
После того, как мы установили структуру связи I2S, мы определяем контакты, которые используются на ESP32 NodeMCU для связи. В моем случае я выбираю:
- Последовательные часы (SCK) = 26
- Выбор слова (WS) = 25
- Последовательные данные (SD) = 33
- В следующем разделе настраиваются драйвер и контакты I2S. Поскольку эта часть кода глубоко погружается во внутренние функции ESP32, мы пропускаем объяснение этого раздела.
В функции цикла мы читаем аналоговый вывод из ЦАП и сохраняем данные в переменной bytes_read. Если мы получаем данные, мы выводим аналоговый звуковой сигнал на последовательный выход, чтобы визуализировать звуковую частоту в последовательном плоттере.
На следующем рисунке показан аналоговый выход последовательного монитора, когда я проигрываю музыку со своего компьютера, и микрофон слушает.
Как воспроизводить музыку из внутренней памяти ESP32
Во втором примере мы хотим воспроизводить музыку через динамик. Звуковые данные хранятся в виде массива во внутренней RAM ESP32. Мы используем плату аудиоразъема MAX98357 I2S для преобразования цифрового сигнала в аналоговый. Поэтому мы используем протокол I2S для вывода цифровых звуковых данных без потери качества.
На следующем рисунке показана проводка между ESP32 NodeMCU, коммутационной платой MAX98357 I2S и динамиком.
Для кода Arduino мы используем библиотеку ESP8266Audio от Earle F. Philhower. Чтобы включить эту библиотеку в ваш Arduino, выполните 4 шага:
- Загрузите папку github в виде zip-файла
- разархивируйте загруженную папку
- переименуйте распакованную папку в ESP8266Audio
- скопируйте папку в путь к вашей библиотеке IDE Arduino (в моем случае: C:\Users\chris\Documents\Arduino\libraries)
Мы используем следующий код Arduino из примеров библиотеки для воспроизведения музыки из внутренней памяти.
#include "AudioGeneratorAAC.h" #include "AudioOutputI2S.h" #include "AudioFileSourcePROGMEM.h" #include "sampleaac.h" AudioFileSourcePROGMEM *in; AudioGeneratorAAC *aac; AudioOutputI2S *out; void setup() < Serial.begin(115200); in = new AudioFileSourcePROGMEM(sampleaac, sizeof(sampleaac)); aac = new AudioGeneratorAAC(); out = new AudioOutputI2S(); out ->SetGain(0.125); out -> SetPinout(26, 25, 22); aac->begin(in, out); > void loop() < if (aac->isRunning()) < aac->loop(); > else < aac ->stop(); Serial.printf("Sound Generator\n"); delay(1000); > >В первых строках мы добавляем следующие заголовочные файлы из библиотеки ESP8266Audio:
- AudioGeneratorAAC: генератор аудиовыхода с использованием декодера Helix AAC.
- AudioOutputI2S: базовый класс для интерфейсного порта I2S
- AudioFileSourcePROGMEM: сохранить «файл» как массив PROGMEM и использовать его как данные источника звука.
- sampleaac: заголовочный файл, в котором аудиофайл хранится в виде массива
Цифровые звуковые данные хранятся в заголовочном файле sampleaac. Чтобы загрузить код Arduino с файлом заголовка в EPS32, важно, чтобы Arduino (файл .ino) и заголовок (файл .h) находились в одной папке.
После того, как мы включили файлы заголовков библиотеки ESP8266Audio, мы даем для первых трех включенных файлов переменные, содержащие ссылки на классы этих файлов.
В функции настройки мы устанавливаем скорость передачи 115200 бод и инициализируем файлы заголовков. Для AudioFileSourcePROGMEM мы определяем, что образец аудиофайла находится в файле sampleaac с размером содержащего его массива.
Объект AudioOutputI2S имеет разные функции. Мы используем функцию SetGain, чтобы уменьшить громкость динамика, и определяем распиновку с помощью функции SetPinout. В моем случае я выбираю следующую распиновку по умолчанию:
- Последовательные часы (SCK) = 26
- Выбор слова (WS) = 25
- Последовательные данные (SD) = 22
Но не стесняйтесь выбирать другие цифровые выводы микроконтроллера EPS32.
Последним шагом функции настройки является подключение входных звуковых данных из внутренней памяти программы к аудиовыходу I2S с помощью AudioGeneratorAAC.
В функции цикла звуковой генератор продолжает работать до тех пор, пока весь звуковой массив не пройдет через генератор. Когда генератор завершит работу, он сообщит об этом на последовательный выход.
Как воспроизвести файл WAVE на ESP32 с внешней SD-карты
В нашем последнем проекте мы хотим воспроизвести WAVE-файл, который я упомянул в начале этого руководства, через ESP32 NodeMCU и динамик. Поскольку ESP32 должен читать файл WAVE и пересылать цифровой аудиосигнал на MAX98357A, мы должны использовать SD-карту с файлом WAVE на ней. Вы также можете использовать файл MP3 вместо файла WAVE.
На следующем рисунке показано подключение ESP32 NodeMCU к модулю карты (Micro) SD, MAX98357A и динамику. На картинке вы видите, что вам нужно изменить контакт DIN MAX98357A, по сравнению со вторым проектом.
Прежде чем мы погрузимся в код Arduino, мы должны подготовить (Micro) SD-карту. Файловая система должна быть FAT16 или FAT32. В зависимости от модуля SD-карты для SD-карты существует ограничение в 32 ГБ. Я использую карту micro SD объемом 32 ГБ, отформатированную как FAT32, и копирую файл WAVE без папки на SD-карту.
Для этого проекта мы используем библиотеку ESP32-audioI2S Arduino от schreibfaul1. Вы можете скачать библиотеку в виде zip-файла с её страницы на GitHub. Поскольку библиотека имеет имя audio, а в Arduino уже существует библиотека с таким же именем, мы включаем библиотеку через IDE Arduino:
- Откройте IDE Arduino.
- Перейдите к (см. Следующий рисунок): Скетч → Подключить библиотеку → Добавить .ZIP библиотеку.
- Выберите загруженную библиотеку
Скрипт Arduino основан на примере скрипта schreibfaul1, но я сократил скрипт оставив только части, необходимые для воспроизведения файла WAVE, и удалил все части для потоковой передачи WiFi.
#include "Audio.h" #include "SD.h" #include "FS.h" // Digital I/O used #define SD_CS 5 #define SPI_MOSI 23 #define SPI_MISO 19 #define SPI_SCK 18 #define I2S_DOUT 25 #define I2S_BCLK 27 #define I2S_LRC 26 Audio audio; void setup() < pinMode(SD_CS, OUTPUT); digitalWrite(SD_CS, HIGH); SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI); Serial.begin(115200); SD.begin(SD_CS); audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT); audio.setVolume(10); // 0. 21 audio.connecttoFS(SD, "Ensoniq-ZR-76-01-Dope-77.wav"); >void loop() < audio.loop(); >// optional void audio_info(const char *info) < Serial.print("info "); Serial.println(info); >void audio_id3data(const char *info) < //id3 metadata Serial.print("id3data "); Serial.println(info); >void audio_eof_mp3(const char *info) < //end of file Serial.print("eof_mp3 "); Serial.println(info); >void audio_showstation(const char *info) < Serial.print("station "); Serial.println(info); >void audio_showstreaminfo(const char *info) < Serial.print("streaminfo "); Serial.println(info); >void audio_showstreamtitle(const char *info) < Serial.print("streamtitle "); Serial.println(info); >void audio_bitrate(const char *info) < Serial.print("bitrate "); Serial.println(info); >void audio_commercial(const char *info) < //duration in sec Serial.print("commercial "); Serial.println(info); >void audio_icyurl(const char *info) < //homepage Serial.print("icyurl "); Serial.println(info); >void audio_lasthost(const char *info) < //stream URL played Serial.print("lasthost "); Serial.println(info); >void audio_eof_speech(const char *info)
В первой части сценария Arduino для ESP32 мы включаем все библиотеки и определяем контакты, которые используются для подключения ESP32 NodeMCU к MAX98357A и модулю SD-карты.
После инициализации объекта Audio с именем «audio» вызывается функция настройки. В функции настройки определяются контакты и SPI-соединение для связи с SD-картой. Скорость передачи установлена 115200, и объект SD-карты также инициализируется.
Для объекта audio устанавливаем распиновку, и уменьшаем громкость звука до 10. Вы можете регулировать громкость звука от 0 до 21. Последняя часть функции настройки - это подключение входов и выходов в этом примере. Поэтому мы связываем аудиообъект с объектом SD-карты и определяем путь к WAVE-файлу. Если вы помещаете звуковой файл в папку, вам необходимо скопировать весь путь к звуковому файлу с косой чертой («/»).
В функции цикла нам нужно только перебрать предварительно сконфигурированный аудио объект для воспроизведения музыки.
Последняя часть интересна, если вы хотите распечатать некоторые детали звукового файла на последовательном мониторе. На следующем рисунке показан последовательный вывод в моем примере. В первом разделе содержится информация о загрузке ESP32, которая отображается на последовательном мониторе, если скорость передачи установлена 115200.
В первой части этой статьи я вычислил частоту для тактовой частоты последовательного порта 44,1 кГц * 16 * 2 = 1,411 МГц. Теперь я хочу доказать, что частота I2S-соединения (последовательных часов SCK) между ESP32 и MAX98357A составляет 1,411 МГц. Поэтому я подключил линию CLK к своему USB-осциллографу и добавил измерение частоты.
На следующем рисунке видно, что мои расчеты верны и частота составляет 1,411 МГц.
Интернет радио на ESP32 и модуле MAX98357A
Обычное аналоговое радио, достигнув пика своего развития в конце XX века, в настоящее время стало постепенно сдавать свои позиции Интернет радио, которое доступно в любой точке земного шара, где есть Интернет-соединение.
Интернет радио (Internet Radio), также известное как стриминговое (streaming), web, IP или онлайн-радио обычно используется для трансляции сообщений, музыки, обсуждений и т.д. в форме аудио сигналов. По другому говоря, это цифровой аудио сервис, транслируемый через сеть Интернет.
Интернет радио можно создать с помощью устройства, подключенного к сети Интернет, или с помощью программного обеспечения, установленного на персональном компьютере (ноутбуке). В данной статье мы его создадим на основе модуля ESP32 и плате усиления MAX98357A, работающей по протоколу I2S.
Ранее на нашем сайте мы рассматривали проект интернет радио на основе платы Raspberry Pi. Если же вас интересует обычное FM радио, то его достаточно просто создать на основе платы Arduino и модуля RDA5807.
Необходимые компоненты
- Модуль ESP32 Devkit (купить на AliExpress).
- Плата усиления MAX98357A I2S (купить на AliExpress).
- 8-омный громкоговоритель (динамик).
- USB кабель.
- Адаптер 5V 1A.
- Активное Интернет-соединение
Интерфейс I2S в модуле ESP32
Как известно, ESP32 представляет собой дешевый модуль с низким энергопотреблением, но внушительным функционалом, включающим в себя поддержку технологий Wi-Fi и Bluetooth. Но, в отличие от других подобных модулей, ESP32 обладает еще и интерфейсом I2S. А во многих популярных сейчас микроконтроллерах такого интерфейса, к примеру, нет.
Почему поддержка интерфейса I2S так важна в современной электронике? Интерфейс I2S (Integrated Inter-IC Sound Bus) представляет собой последовательную шину для соединения цифровых аудиоустройств (плееров компакт-дисков, цифровых аудиопроцессоров и т. п.). Он разработан фирмой Philips Semiconductor. Данный интерфейс обычно используется компонентами АЦП и ЦАП. Более подробно про принципы работы протокола I2S вы можете прочитать в этой статье.
Поскольку в нашем интернет радио нам необходимо воспроизведение звука с помощью громкоговорителя (динамика), то нам нужен аналоговый выход, то есть необходим ЦАП (цифро-аналоговый преобразователь). И здесь мы видим самую интересную часть нашего проекта – это модуль MAX98357A, который представляет собой цифровой усилитель класса D, который использует интерфейс I2S для обмена данными с современными микроконтроллерами.
Достоинства модуля MAX98357A I2S:
- КПД 92%.
- Выходная мощность 3,2 Вт на 4-омном динамике при 5V.
- Уменьшение мощности шумов.
- Защита от короткого замыкания и перегрева.
- Поддержка левого, правого или Left/2 + Right/2 выхода.
- Работа от напряжения в диапазоне от 2.5V до 5.5V.
Внешний вид модуля MAX98357A I2S, использованного в нашем проекте, показан на следующем рисунке.
Схема проекта
Схема интернет радио на ESP32 и модуле MAX98357A I2S представлена на следующем рисунке.
Как видите, схема соединений достаточно проста. Поскольку контакт Gain модуля MAX98357A подключен к земле (GND), то коэффициент усиления модуля составляет 12dB.
Объяснение программы для модуля ESP32
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Для данного проекта нам понадобится библиотека ESP32 Audio I2S. Скачайте ее по приведенной ссылке с GitHub и добавьте ее в Arduino IDE.
Первым делом в программе мы подключим используемые библиотеки.
Протокол I2S в ESP32: принципы работы, основы программирования
I2S (Inter-IC Sound protocol) – последовательная шина для соединения цифровых аудиоустройств, используемая для передачи и приема аудио данных по синхронному последовательному порту между двумя устройствами. Находит достаточно широкое применение в современной электронике.
В настоящее время в мире существует много протоколов для передачи аудио данных, применяемых в аудио кодеках, ЦАП (для цифрового аудио выхода), АЦП (для цифрового аудио входа). Среди них одним из самых простых и прозрачных протоколов является протокол I2S.
Данный протокол был разработан компанией Philips Semiconductor (сейчас NXP Semiconductors) и он находит широкое применение в микроконтроллерах, кодеках, аудио модулях, микрофонах и т.п.
Ранее на нашем сайте мы уже рассматривали основы работы с протоколом I2S в статье про интернет радио на основе модуля ESP32, в этой же статье мы более глубоко рассмотрим принципы работы протокола I2S и программирование работы с ним в модуле ESP32.
Необходимые компоненты
- Модуль ESP32 Devkit (купить на AliExpress).
- Плата усиления MAX98357A I2S (купить на AliExpress).
- 8-омный громкоговоритель (динамик).
- USB кабель.
3-х проводное соединение в протоколе I2S
Протокол I2S использует 3 провода для соединения. Структура соединения между передающим и приемным устройствами в протоколе I2S показана на следующем рисунке.
Провод Word Select (WS) или Frame Select (FS)
Поскольку протокол I2S позволяет передавать звук в формате стерео, то левый или правый каналы в нем могут быть выбраны с помощью контакта WS или Word Select (выбор слова). Если контакт WP находится в состоянии Low, то выбран канал 1 (левый канал, left channel). Если контакт WP находится в состоянии High, то выбран канал 2 (правый канал, right channel).
То есть получаем:
If WS pin = 0 then Channel 1 or left channel is activated
If WS pin = 1 then Channel 2 or Right channel is activated
Независимо от этого контакта выбора канала, протокол I2S использует два дополнительных канала, которые применяются в большинстве последовательных интерфейсов.
Контакт Serial Data или SD
Контакт Serial Data (или SD) в протоколе I2S используется для передачи данных, которые передаются в два приема.
При передаче данных в протоколе I2S сначала передаются наиболее значимые биты (most significant bit, MSB). Для этого есть объективная причина – в протоколе I2S данные от передатчика к приемнику могут передаваться словами различной длины.
Таким образом, если сначала передаются наиболее значимые биты (MSB), для передатчика или приемника нет необходимости знать сколько бит передается или принимается. Но это порождает новую проблему – поскольку передатчик и приемник не знают длину слова, достаточно сложно определить были ли потеряны биты в процессе передачи в результате воздействия шумов или каких либо других факторов. Эта проблема решается с помощью контакта (линии) WS.
Если WS приемника больше чем WS передатчика, слово обрезается и наименее значимые данные устанавливаются в 0. Если WS приемника меньше чем WS передатчика, биты после наименее значимых битов (LSB) игнорируются.
Линия Bit clock или BCLK
Линия Bit clock (или BCLK, bit clock line) представляет собой линию, по которой передаются тактовые импульсы – это необходимо для процессов синхронизации. Линия синхронизации играет важную роль во всех последовательных протоколах передачи данных.
Она необходима чтобы все компоненты работали в одном и том же цикле. Частота линии BCLK зависит от частоты дискретизации (sample rate), количества бит на канал (Bits per channel) и числа используемых каналов (Number of channels).
Формула для ее расчета следующая:
Frequency = Sample Rate x Bits per channel x Number of channels.
Sample rate (частота дискретизации): 44.1 kHz
Bits per channel (бит на канал): 8
Number of channels (число каналов): 2 [Stereo]
В итоге получаем частоту линии BCLK равную 44.1 kHz * 8 * 2 = 705 kHz.
Временные диаграммы протокола I2S
Показаны на следующем рисунке.
На представленных диаграммах показаны три линии протокола I2S: BCLK, WS, SD. Линия BCLK обеспечивает требуемую частоту следования импульсов. Линия WS изменяет свое состояние от правого канала к левому.
Данные передаются каждый тактовый импульс. Контакт WS изменяет свое состояние с одного канала на другой перед тем как один тактовый импульс линии данных протокола I2S начинает передачу наиболее значимых битов (MSB). Это необходимо из-за того, что приемнику требуется время на то, чтобы сохранить предыдущее переданное слово и очистить регистр.
Работа с протоколом I2S в модуле ESP32
Основные принципы работы драйвера протокола I2S в модуле ESP32:
- Драйвер (контроллер) протокола I2S в модуле ESP32 может работать в режиме ведущего (master) или ведомого (slave).
- Он может работать как передатчик или приемник на шине I2S.
- Модуль ESP32 имеет выделенный DMA контроллер (контроллер прямого доступа к памяти), который может транслировать биты данных не используя ресурсы центрального процессора модуля.
- Периферийные устройства модуля ESP32, работающие по протоколу I2S, также поддерживают режим LCD. В этом режиме данные протокола I2S передаются по параллельной шине. Данный режим необходим для некоторых ЖК дисплеев (LCDs) и камер, подключаемых к модулю ESP32.
В режиме LCD контроллер I2S модуля ESP32 может работать в следующих режимах:
- Ведущий (master) в режиме передачи – для ЖК дисплея.
- Камера в режиме ведомого (slave).
- Режим ADC/DAC (АЦП/ЦАП).
Генератор тона NOKIA с использованием протокола I2S
Давайте подключим громкоговоритель (динамик) к модулю ESP32 по протоколу I2S и сгенерируем символическую мелодию тона NOKIA.
Поскольку громкоговоритель (динамик) является аналоговым устройством, то его невозможно напрямую подключить к модулю ESP32 – для этой цели мы будем использовать модуль усилителя MAX98357A, работающий по протоколу I2S. MAX98357A работает в режиме Mono.
Внешний вид модуля усилителя MAX98357A показан на следующем рисунке.
Самыми важными контактами модуля MAX98357A являются BCLK, DIN и LRC. DIN – это контакт передачи данных, фактически, это линия SD в протоколе I2S. LRC (Left-Right Channel) – это контакт выбора канала, аналог контакта WS в протоколе I2S.
Схема подключения модуля MAX98357A к ESP32 по интерфейсу I2S представлена на следующем рисунке.
В схеме имеем следующие соединения:
- BCLK pin of I2S = BCLK Pin of the Module = ESP32 Pin 27.
- Word Select pin of I2S = LRC Pin of the Module = ESP32 Pin 26.
- Serial Data pin of I2S = DIN Pin of the Module = ESP32 Pin 25.
Объяснение программы для модуля ESP32
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Чтобы код нашей программы работал, необходимо чтобы файл sampleaac.h содержал шестнадцатеричный код мелодии Nokia. О том, как это сделать, вы можете прочитать в статье про аудиоплеер на основе модуля ESP32.
Заголовочный файл должен быть примерно следующего формата: