Sipeed MAix Bit with MIC Maixduino(Arduino) で マイクのお試し #2 です。
前回の、Sipeed MAix Bit with MIC Maixduino(Arduino) で マイクのお試し
では、 Arduino の loop() 処理の中から I2S の取り込みや、PC への Serial 送信だったので、
もしかしたら、 I2S の取りこぼしが出ていないか、心配でした。
今回は、I2S の DMA転送完了のイベント駆動での、I2S フレームの受信と、
別タスクでの、PC への Serial 通信を試してみました。
I2S のイベント受信のサンプルは、
github.com/kendryte/kendryte-standalone-demo/blob/develop/i2s_dma/main.c
マルチタスクのプログラムは、Maixduino(Arduino) の中に、FreeRTOS が最初から入っているので、
それを利用します。
開発環境
OS: Windows10
Platform IO IDE(Visual Studio Code)
platforomio.ini
platform = kendryte210
board = sipeed-maix-bit-mic
framework = arduino
※ UART1 に、別途 USB-Serial (FT232RL) を付けます。
Maix-Bit silk | k210 IO | USB-Serial (FT232RL)
15 -- IO15 (tx) --> Rx
17 -- IO17 (rx) --> Tx
GND --> GND
注)上記以外は、オープン
USB-Serial VCC は結線しません。
1. Sipeed MAix Bit 側の Arduino プログラムです。
1) I2S でPC へ送るデータは、
Sampling Rate: 16000
Monoral 16bit
2) Serial1
Baud Rate : 921600 * 1.6
3) int i2s_on_irq(void *ctx) で、I2S の DMA 受信完了割り込みを受けます。
I2S の 1フレーム(TUNK) を受信したら、
xQueueSend(queue, (void *)&message, 0)
で、task0() へ知らせます。
4) void task0(void* arg) は、別タスクで、
xQueueReceive(queue, (void *)&message, 1000 / portTICK_PERIOD_MS)
でメッセージキューが来たら、I2S 1 TUNK データを、Serial1 で、PC へ送信します。
ここで、 I2S データの 32bit Stereo -> 16bit Monoral へ変換します。
PC へ送るデータは、
16000*2(バイナリデータ)+\r\n の固定長データ
5) i2s_setup() が10回コールされる毎に、LED_GREEN(pin12) をON/OFF させています。
もしブリンクが止まっていたら、ハングぞね!!
REV2 - Semaphore を使わない処理のアップデート版です。(2020.3.20)
2. PC 側の Python Script は、前回のと同じです。
3. 結果
どうやら、 I2S のフレーム(TUNK) の取りこぼしは、出ていないようです(たまに出るみたい)。
80cm 程離れて、普通に話してもマイクには拾えますが、
大きな声だと、ビリつきます。
「ハローハロー」と大きめに話しても、ビビリ音になります。
また、かなりエコーが掛かっているようです。
1.2 M位が良いのか?
感度が良すぎるのか、まだプログラムに不具合があるのか?
何か、改善策はあるのだろうか?
将来は、CNN での Sound Classify を Bit(k210) で走らせたいなと思っちょりますが、
これほど音が、ビリツクと、正しく判定出来ないのでは?
Bit に I2S DAC(Head phone) を繋げて、Sample Rate 44,100 の音を、ヘッドホーンで
確認してみる事も必要でしょうか。
4. Bit の方でまだ、ハングするみたいです。今、原因を調査中です。(2020.3.19)
5. 割り込みルーチン(i2s_on_irq()) の中で、xSemaphoreTake(),xSemaphoreGive() を使うのは拙いみたいです。
その代わり、xSemaphoreTakeFromISR(), xSemaphoreGiveFromISR() を使うとの事です。
これで、Bit 側のハングは解消できそうです。
早速、改修版を、アップデートしました。
ただ、もう少し様子みですが、xSemaphoreTake(), xSemaphoreGivee() 版の方が、動作が軽い(音が軽い)気がします。
xSemaphoreTakeFromISR(), xSemaphoreGiveFromISR() は、マクロ展開で、実際の中は、
xQueueReciveFromISR(),xQueueSendFromISR() みたいなので、
少しオーバーヘッドが出ているのかもしれません。
同じ割り込みルーチンの中で、2回の Queue 送信、1回の Queue 受信 するのは、いただけません。
ここは、改善の余地がありそうです。(202.3.20)
6. REV2 版 Semaphore を使わない処理に改めました。 (202.3.20)
音も元の様に軽くなったみたいです。
しかし、大きな音だと直ぐに、ビリつきます。これが限界か!!