#概要
トランジスタ技術(2017年11月号)の記事を見てh_nariさんの「ESP32でI2S+DACを使う」を知りました。
ちょうど、ヘッドフォンアンプを作成中だったので音源として使わせて頂いていましたが、CDくらいの音質が欲しかったため外付けDAC(PCM5102A)から音声を出力できるようにしました。
#サンプル・プログラム
ESP-IDFの開発環境でgitが使えたので初めてGithubでプログラムを公開しました。
・プログラム・ソース (GitHub)
https://github.com/od1969/ESP32_bt_I2S/
#変更点
以下の2つの関数内を変更しました。
参考にしたのはESP-IDF Programming Guide I2Sのページの記述です。
void i2sdac_init()
{
i2s_config_t i2s_config;
static const i2s_pin_config_t pin_config = {
.bck_io_num = 26,
.ws_io_num = 25,
.data_out_num = 27,
.data_in_num = I2S_PIN_NO_CHANGE
};
i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER|I2S_MODE_TX);
i2s_config.sample_rate = SAMPLE_RATE ;
i2s_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT;
i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT;
i2s_config.communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB;
i2s_config.dma_buf_count = DMA_BUF_COUNT;
i2s_config.dma_buf_len = DMA_BUF_LEN;
i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1;
i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM, &pin_config);
}
void i2sdac_write(const uint8_t *data, uint32_t len)
{
TickType_t delay = 50 / portTICK_PERIOD_MS;
if(len % 8){
ESP_LOGE(TAG,"unexpected data len:%u",len);
return;
}
for(int i=0; i<len; i+= 4){
uint16_t d[2];
d[0] = data[i+0]|(data[i+1] << 8);
d[1] = data[i+2]|(data[i+3] << 8);
int n = i2s_push_sample(I2S_NUM, (const char *)d, delay);
if(n < 0)
ESP_LOGE(TAG, "i2s_write_bytes error:%d",n);
}
}
#回路図
ESP32-DevKitCとRaspberry Pi用のPHAT DACをジャンパーワイヤーで接続しています。
ESP32-DevKitC → PHAT DAC
5V → 5V
GND → GND
IO26 → BITCLOCK(GPIO18)
IO25 → LRCLOCL(GPIO19)
IO27 → DATAIN(GPIO20)
ESP32側はソフトウェアで変更可能です。
#開発環境
トランジスタ技術(2017年11月号)の記事及び以下のQiitaの記事を参考に開発環境を構築しました。
ESP32(ESP-WROOM-32)でLチカ (WindowsでESP-IDF使用)
ESP-IDF の環境をWindows10につくる
#注意点(2017/10/24時点)
最新のEspressif toolchain及びESP-IDFを使うと動かないみたいです。(延々ノイズが出る等。
Espressif toolchain(20170330版),ESP-IDF Release v2.1を使用した所うまく動きました。