ESP-IDF のサンプルプログラム i2s_adc_dac を試す

ESP32でオーディオ関係のプログラムを作成するために、ESP-IDFのサンプルプログラム i2s_adc_dac を試してみた。

i2s_adc_dacは、リセットするとADCを利用してアナログの信号をサンプリングし、読み込んだデータをフラッシュメモリに書き込んで録音する。その後は、フラッシュメモリに書き込んだデータを再生し、その後に、あらかじめプログラムで用意されているデータを再生することを繰り返す。

ハードウェア

部品

ブレッドボード図

実際に組み立ててみた様子は次の通り。

回路図

Fritzingファイル

パーツのFritzingデータ

上記の回路図で利用したパーツは以下にあるものを利用した。

WeMos esp32 Lolin

小型シリコンマイクモジュール SPU0414HR5H-SB使用

テスト環境

  • Windows 10
  • PlatformIO IDE for VSCode 1.28.1
  • フレームワーク
    • Espressif 32 (Version 1.4.0)
      • Version 1.3.0 では ADCからデータが正常に読み込めなかった。常に0が読み込まれて無音状態であった。Version 1.4.0 にアップデートすることで読み込めるようになった。

ソフトウェア

以下にあるサンプルプログラムを利用した。

https://github.com/espressif/esp-idf/tree/master/examples/peripherals/i2s_adc_dac

当然ながらサンプルプログラムはそのままで機能するが、試した環境ではADCの入力の振幅が小さく、プログラムのままでは再生してもよくわからなかった(スピーカーが極めて貧弱であることも問題である)。ADCから読み取った値を調べてみたが、しゃべったことを録音するためには、マイクに口をかなり近づけないとほとんど変化が見られなかった。

とりあえず動作確認のために、ADCの出力の12bit の最上位8ビットを利用するのではなく、振幅を(2^scale_bit)倍にして(scale_bitビット左シフトすることで上位ビットを捨てて、その下の8ビットを使うようにして)試してみた(プログラム例ではプログラムの最初の方でマクロで指定している7ビットシフト)。具体的には、プログラムの example_i2s_adc_data_scale の次の部分を9行目のように変更して試した。

void example_i2s_adc_data_scale(uint8_t * d_buff, uint8_t* s_buff, uint32_t len, uint32_t scale_bit)
{
    uint32_t j = 0;
    uint32_t dac_value = 0;
#if (EXAMPLE_I2S_SAMPLE_BITS == 16)
    example_disp_buf((uint8_t*) s_buff, 32);
    for (int i = 0; i < len; i += 2) {
        dac_value = ((((uint16_t) (s_buff[i + 1] & 0xf) << 8) | ((s_buff[i + 0]))));
        dac_value = ((dac_value - ADC_OFFSET) << scale_bit) +  ADC_OFFSET;   // amplify 2^scale_bit  
        d_buff[j++] = dac_value & 0xff;
        d_buff[j++] = (dac_value >> 8 ) & 0xff;
    }
#else

はっきりしないところはあるが、マイクに口を近づけてしゃべってみて録音した音らしきものが再生されることは確認した。

プロジェクトファイル

使用したプロジェクトのファイルを次のGitHubに置いた。

https://github.com/kunsen-an/espidf_i2s_adc_dac