今回はPDM出力のデジタルマイクSPH0641LU4Hを
I2S接続で読み込んでみました。
最近のデジタルマイクはMEMSマイクのため、
一般的なマイクに比べ、
高感度かつ広帯域で感度も帯域に癖がなく、
非常にフラットな感度を持ちます。
特に今回紹介するMEMSマイクは
超音波帯域のマイクとしても使用でき、
80kHzまで拾うことができます。
一般的な超音波受信器は共振型のため、
36kHzと書いてあれば36kHz前後周辺の超音波しか拾うことができません。
一方、MEMSマイクは36kHz以外でも拾うことができるため、
例えば、amazonのDashButtonの初期設定のように
普通のマイクとしても、
超音波を使って自在にスマートフォンと機器の間で通信することもできます。
超音波に対応したMEMSマイクはKnowlesから
デジタル版MEMSマイクSPH0641LU4H以外に
アナログ版MEMSマイクSPU0410LR5Hも出ています。
ただ、アナログ版はご存じのようにオペアンプ増幅回路など
周辺回路が必要です。
一方、デジタル版はそのままマイコンに接続できるため、
周辺回路が不要です。
また、アナログ部がセンサ内部のみとなるため、
ノイズにも強い回路にできます。
一般的にはデジタルマイクはPDM出力となっており、
I2S接続でオーバーサンプリングで取得します。
環境は
・STM32F401RENUCLEO
+SW4STM32(System Workbench for STM32)
+STM32CubeMX(HAL ライブラリ、F4 ver. 1.15.0)
です。
CubeMXの設定は次の通り。
Data and Frame FormatとSelected Audio Frequency
は試しに設定した値です。
ポイントはHalf-Duplex Masterに設定し、
ModeをMaster Recieveに設定することです。
接続は
I2S2_CKをマイクCLK
I2S2_SDをマイクDATA
に接続します。
今回はモノラルで使用するため、
I2S_WSは未使用です。
コードは下記の通り
実際には音を安定して連続に取り込む必要があるため、
DMA転送等を利用すべきですが、
動作確認のため、必要なデータ数を読み込みました。
uint32_t I2S_RX_BUFFER[24];
while (1)
{
int8_t res=HAL_I2S_Receive( &hi2s2,
(uint16_t*)&I2S_RX_BUFFER,
24,1000);
HAL_Delay(200);
//printf("Res: %d ", res);
printf("Data: %" PRIu32", %"PRIu32", %"PRIu32" , %"PRIu32" \n",
I2S_RX_BUFFER[0],
HAL_Delay(200);
//printf("Res: %d ", res);
printf("Data: %" PRIu32", %"PRIu32", %"PRIu32" , %"PRIu32" \n",
I2S_RX_BUFFER[0],
I2S_RX_BUFFER[1],
I2S_RX_BUFFER[2],
I2S_RX_BUFFER[3]);
}
}
今回、テストで使用したKnowles社の
デジタルマイクSPH0641LU4Hは
入力するクロックによってモードが切り替わります。
Low-Power Mode :351 kHz ≤ fCLOCK ≤ 815 kHz
Standard Performance Mode :1.024 MHz ≤fCLOCK ≤ 2.475 MHz
Ultrasonic Mode :3.072 MHz ≤ fCLOCK ≤ 4.8 MHz
HALライブラリのI2Sの設定では
オーディオサンプリングの帯域設定しかありません。
実際に設定によってどのようにクロックが変化するか
確認してみました。
I2Sバスクロック96MHz設定の場合のI2Sクロック結果は下記の通り。
なお、クロック4.8MHz以上はデジタルマイクSPH0641LU4Hの動作保証外です。
一応、DATA出力としては6MHzまでは出ましたが...
実際にUART出力してみた例は下記の通り。
音によって値の桁が変化するため、
正常に読み込んでいると思われます。
今度は読み込んだ値をFFT化したりして、
意図した周波数の信号がとれるか確認してみたいと思います。なお、I2S_WSは16B幅の場合は
16bit毎にHIGH、LOWが入れ替わり、
それ以外では32bit毎にHIGH、LOWが入れ替わるようです。
96k,16B
96k,32B
96k,24B
96k,16BEX
1番目がCLK、2番目がDATA、3番目がWSです。
HALライブラリを利用したI2Sの場合、
HALの設定でオーディオサンプリング周波数に応じて
いい感じにクロックを出力してくれることが分かりました。
ただ、今回のセンサのようにクロックによって動作が変わる場合、
I2Sクロック周波数が直感的に分からないため、
オシロスコープ等で確認する必要がありそうです。