Наконец то у меня добрались руки до сборки минимального аналога Espressif Systems плат на ESP32 микроконтроллере.
На плате расположен микрофон, усилитель для этого микрофона на одном транзисторе. Усилитель для динамика на трех транзисторах с выходным каскадом работающим в режиме AB. OLED дисплей 128x64 SSD1306
Espressif Audio Development Framework предоставляет богатую функциональную SDK которая работает все стабильнее с каждым релизом. Не без своих косяков конечно. Есть у нее и минусы. Например некоторые библиотеки предоставляются без исходных кодов. В линейке плат не было версии с использованием внутреннего ЦАП и АЦП для обработки звука. Конечно для чего-то серьезного такой подход не подойдет. И разрядность встроенного АЦП 12 бит и ЦАП 8 бит накладывает некоторые ограничения. Да и шумят эти встроенные модули не слабо. Но хотелось попробовать сделать если уж не VoIP телефон, то пример Google Translator и Text-To-Speech постараться запустить. Как это у меня получилось читайте под катом
Плата проектировалась и разводилась в Eagle Autodesk.
ESP32 Module Amplifiers
OLED Display
«Поднимать» плату будем традиционно с питания. Распаиваем разъем питания, стабилизатор напряжения питания и конденсатор на выходе это стабилизатора. Замеряем напряжение питания. На входе 5V после стабилизатора должно быть 3.3V
Плата задумывалась работать в переносном варианте с питанием от аккумулятора. Для этого предусмотрен чип IC2 отвечающий за заряд батареи TP4056 и схема барьера на полевом транзисторе Q3 и диоде Шоттки D3. Стабилизатор питания сделан на HT7833. Он обеспечивает малое падение напряжения и достаточный для питания схемы ток
Цепь зарядки нас пока не интересует, поэтому кинем перемычку с разъема питания прямо на вход HT7833. Померяем что на выходе и приступим к распайке самого модуля ESP32
Надо распаять цепь Reset и кнопку PROG которую надо удерживать для перевода контроллера в режим программирования. Пины для подключения UART адаптера RX-TX нужны для соединения платы с компьютером
Теперь можно подключать плату к компьютеру через USB-to-UART адаптер и запустить какой нибудь пример esp-idf. Например сканирования сети
Далее распаиваем усилитель для динамика и микрофона. Про использование усилителей для микрофона и динамика можно прочитать в статье Микрофонный усилитель и УНЧ для ЦАП и АЦП микроконтроллера
Настраиваем резистором R15 половину напряжения на эмиттерах T3 и T4 в схеме усилителя динамика. У меня подошел резистор 33К. R17 можно поставить поменьше 1K… 4.7K если усиления будет недостаточно. Он ограничивает усиление и выступает в качестве делителя напряжения
Для усилителя микрофона резистором R10 подбираем на коллекторе транзистора T2 напряжение в районе 0.6V...1.2V. Чем больше смещение при слабом сигнале, тем больше потери на разрядности АЦП. Так как у нас один каскад усилителя на одном транзисторе, амплитуда сигнала будет не большая. Я поставил 100К и получил 0.85V. Полная амплитуда сигнала full-scale voltage будет 1.7V что можно компенсировать аттенюатором на входе АЦП взяв например ADC_ATTEN_DB_2_5
Напомню про градации аттенюатора на входе АЦП ESP32
- 0 dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1 V
- 2.5 dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5 V
- 6 dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2 V
- 11 dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9 V
Теперь уже можно запустить что-то со звуком. Что касается примеров рассчитанных на внешний ЦАП тут все просто, в настройках конфигурации добавляем I2S_MODE_DAC_BUILT_IN
i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN,
...
Или при использовании esp-adf audio development framework
struct i2s_stream_cfg_t i2s_cfg = I2S_STREAM_INTERNAL_DAC_CFG_DEFAULT();
В частности это изменение для примера pipeline_bt_sink позволяет получить на этой плате BlueTooth динамик
Есть пример который выдает синусоидальный сигнал dac-cosine
Замена использования внешнего АЦП на внутренний так же возможна, но это будет несколько сложнее. Я это делаю примерно так
#define I2S_STREAM_CFG_1() {
.type = AUDIO_STREAM_WRITER,
.task_prio = I2S_STREAM_TASK_PRIO,
.task_core = I2S_STREAM_TASK_CORE,
.task_stack = I2S_STREAM_TASK_STACK,
.out_rb_size = I2S_STREAM_RINGBUFFER_SIZE,
.i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_ADC_BUILT_IN | I2S_MODE_DAC_BUILT_IN,
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE,
.channel_format = I2S_CHANNEL_FMT,
.communication_format = I2S_COMM_FORMAT_I2S_MSB,
.dma_buf_count = 4,
.dma_buf_len = 512,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
},
.i2s_port = I2S_NUM_0
}
И заменяю дефолтный конфиг esp-adf framework на свой
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_1();
i2s_cfg.type = AUDIO_STREAM_READER;
Продолжение сборки и запуск примеров в видео:
Используя эти подходы по замене внешнего ЦАП и АЦП на встроенный мне удалось запустить такие примеры как:
pipeline_http_mp3
pipeline_bt_sink
google_translate_device
И многие другие
На плате предусмотрена разводка под джойстик 4+1 кнопки, так что можно реализовать мини консоль Arduboy
Запустить VoIP пока не удалось. Но думаю у меня возникли проблема с настройками протокола. Так что пока в процессе. Но опять же, библиотека SIP в примере закрытая. Есть пример на Github sip_call с другой и открытой реализацией SIP библиотеки
В заключении хотел отметить, что я вывел на плате некоторые неиспользованные порты GPIO для подключения периферии. Возможность подключения внешнего ЦАП и АЦП все еще остается, что надо проверить
Автор: Andreev Dmitry