M5Stack AtomS3RでPDMマイクの音をソフトウェアでPDM-to-PCM変換して録音

この記事は約9分で読めます。

前回は、M5Stack AtomS3RのESP32-S3が持つハードウェアのPDM-to-PCM変換を利用して、PDMマイクの音を録音した( M5Stack AtomS3RでPDMマイクの音をハードウェアでPDM-to-PCM 変換して録音 )。

今回はその続きとして、I2Sからraw PDMデータを受け取り、ESP32-S3上のソフトウェアでPCMへ変換した。録音部分はESPHomeの外部コンポーネントとし、外付けBME280とAtomS3R内蔵のBMI270/BMM150の値をHome Assistantへ送り、LCDにも表示する。

ESP32-S3 の ハードウェアデシメーション(Hardware decimation) ではサンプリング周波数は実質的に48kHzまでしか対応できない。ソフトウェアデシメーション(Software decimation)を利用してサンプリング周波数192kHzで録音ができる。ソフトウェアデシメーションを用いることで超音波の録音が可能になる。ただし、192kHz録音ではデシメーション比が24であり、音響特性は応用によっては不十分と考えられる。

本記事で使用するのは、8 MB PSRAMを搭載したM5Stack AtomS3Rである。外観がよく似たAtomS3は対象ではない。

OpenAI Codex を使って、コードの修正およびこの記事の原稿作成を行った。

作ったもの

PDMマイクの信号を3.072 MHzで受信し、CICフィルターとFIRフィルターを使って48 kHz、16 bit、monoのPCMへ変換する。PCMはAtomS3RのPSRAMへ一時保存し、録音完了後にWAV/BWFファイルとしてブラウザーから取得する。

項目 内容
本体 M5Stack AtomS3R(ESP32-S3)
PDMマイク Knowles SPH0641LU4H-1
PDMクロック 3.072 MHz
PCM 48 kHz、mono、signed 16 bit
デシメーション CIC3 / 16、127-tap FIR / 4
録音バッファ AtomS3RのPSRAM
録音操作 HTTP port 8088
センサー BME280、BMI270、BMM150
連携 ESPHome API / Home Assistant
検証環境 ESPHome 2026.7.2 / ESP-IDF 5.5.5

raw PDMを受信し、CIC3とFIRで48 kHz PCMへ変換する流れ

ハードウェア変換版との違い

前回はESP32-S3のハードウェアPDM-to-PCM変換機能からPCMを受け取っていた。今回はI2S PDM RXをraw PDM形式に設定し、PDMの1 bitデータをソフトウェアの外部コンポーネント内でPCMへ変換する。

hardware decimation:
PDM microphone -> ESP32-S3 PDM-to-PCM -> PCM

software decimation:
PDM microphone -> raw PDM RX -> CIC3 -> FIR -> PCM

ソフトウェア版では変換処理を確認、変更しやすい反面、ESP32-S3のCPU時間を使う。このため、ESPHomeのコンパイル最適化は性能優先とした。

ハードウェア

使用したもの

  • M5Stack AtomS3R
  • SPH0641LU4H-1を搭載したPDMマイク基板
  • BME280温湿度・気圧センサー

PDMマイクの配線

SPH0641LU4H-1 AtomS3R
CLK GPIO5
DATA GPIO6
VDD 3.3 V
GND GND

BME280の配線

BME280 AtomS3R
VCC 3.3 V
GND GND
SDA GPIO38
SCL GPIO39

設定ファイルではBME280のI2Cアドレスを0x76としている。0x77になっている基板を使う場合はYAMLのaddressを変更する。

セットアップ

1. リポジトリ

リポジトリは、次の場所である。

GitHub - kunsen-an/pdm_recorder_esp32s3_software-PDM-to-PCM
Contribute to kunsen-an/pdm_recorder_esp32s3_software-PDM-to-PCM development by creating an account on GitHub.

secrets.example.yamlsecrets.yamlへコピーし、Wi-Fi、ESPHome API暗号鍵、OTAパスワード、Fallback APパスワードを変更する。

2. 設定を検証する

esphome config atoms3r_software_decimation_pdm_recorder.yaml

3. コンパイルしてAtomS3Rへ書き込む

esphome compile atoms3r_software_decimation_pdm_recorder.yaml
esphome run atoms3r_software_decimation_pdm_recorder.yaml

software decimationの設定

主な設定は次の部分である。

esp32:
  framework:
    type: esp-idf
    advanced:
      compiler_optimization: PERF

pdm_recorder:
  id: pdm_recorder_id
  pdm_clk_pin: GPIO5
  pdm_din_pin: GPIO6
  capture_mode: software_pcm
  pdm_clock: 3072000Hz
  raw_pdm_msb_first: true
  sample_rate: 48000Hz
  data_bit_width: 16bit
  saving_bits_per_frame: 16bit

capture_mode: software_pcmによってraw PDM受信とソフトウェア変換を選択する。PDMクロック3.072 MHzをPCMサンプルレート48 kHzで割ると、全体のデシメーション比は64となる。

最大192 kHzのソフトウェアデシメーション

公開YAMLの標準設定は48 kHzであるが、ソフトウェアデシメーション実装は最大192 kHzに対応する。PDMクロック4.608 MHz、デシメーション比24、signed 16 bit、monoの設定で192 kHz録音をAtomS3R実機で確認済みである。

pdm_recorder:
  id: pdm_recorder_id
  pdm_clk_pin: GPIO5
  pdm_din_pin: GPIO6
  capture_mode: software_pcm
  pdm_clock: 4608000Hz
  raw_pdm_msb_first: true
  sample_rate: 192000Hz

192 kHzでは、100 msで19,200フレーム、1秒で192,000フレーム、5秒で960,000フレームを取得した。5秒録音の実測時間は5,005 msであり、WAVヘッダーとデータ長は正常、I2S read errorおよびクリッピングは発生しなかった。96 kHzと192 kHzの両方で、HTTP録音要求、録音後のWi-Fi再接続、WAVダウンロードも確認している。

CICとFIRによる変換

最初に3段のCICフィルターで16分の1に間引く。CICは乗算を使わずに大きな間引きを行えるので、PDMのような高いサンプルレートの処理に向いている。

続いて127-tapの固定小数点FIRフィルターを通し、さらに4分の1に間引く。CICとFIRを合わせて64分の1となり、3.072 MHzのPDMから48 kHzのPCMを生成する。

ESP-IDFのraw PDM RXが返す16 bit wordについて、時間順にPDMビットを処理する必要がある。今回のマイクと設定ではraw_pdm_msb_first: trueを使用した。

録音してみる

AtomS3RのLCDまたはルーターでIPアドレスを確認し、同じLANのブラウザーから次を開く。

http://<AtomS3RのIPアドレス>:8088/

録音時間と48 kHzを指定して録音を開始する。録音中はI2S処理を優先するためWi-Fiを一時停止し、録音完了後に再接続する。完了するとWAV/BWFファイルをダウンロードできる。

センサー値とLCD表示

外付けBME280から温度、湿度、気圧を取得する。AtomS3R内部のBMI270/BMM150からは加速度、角速度、地磁気、IMU温度を取得する。

LCDにはIPアドレス、BME280の温湿度、加速度、地磁気を表示する。

Home Assistantとの連携

ESPHome APIを有効にしているので、Home Assistantへデバイスを追加すると、BME280、BMI270、BMM150の値をエンティティとして利用できる。API暗号鍵はsecrets.yamlで管理する。

実機で確認したこと

ESPHome 2026.7.2とESP-IDF 5.5.5でビルドし、AtomS3Rへ書き込んで確認した。

  • devcontainerを使わないクリーンビルドとUSB書き込み
  • BME280、BMI270、BMM150の全13センサー値を暗号化ESPHome APIで取得
  • LAN経由のOTA更新と、再起動後のAPI・HTTP録音の復帰
  • HTTP録音画面と、LAN内限定・未認証のNVS設定画面
  • 48 kHz、16 bit、monoで500 ms(24,000 frames)と5秒(240,000 frames)を録音
  • RIFF/WAVEヘッダー、sample width、sample rate、frame数の整合
  • 5秒録音でI2S read errorなし、clipped sample 0
  • 発展設定として96 kHzおよび192 kHzの実機録音、192 kHz・5秒で960,000 framesを確認

5秒録音はmin -1566、max 1544、RMS 369.86であった。ここでは録音経路の動作確認だけを目的とし、SNR、THD+N、周波数特性などの音響性能は評価していない。

LCDドライバーの初期化と表示更新経路にはエラーがなかった。画面にIPアドレスとセンサー値が正しく描画されることは、実機画面を見ながら最終確認する必要がある。

ハマりどころ

AtomS3とAtomS3Rを取り違えない

本構成は録音バッファとしてPSRAMを使う。対象は8 MB PSRAMを搭載したAtomS3Rであり、AtomS3では動作しない。

raw PDMには新しいESP-IDFが必要

software decimationでは、I2S PDM RXから変換前のraw PDMを取得する必要がある。今回の検証環境はESPHome 2026.7.2とESP-IDF 5.5.5である。古いESP-IDFのハードウェア変換済みPCMをraw PDMとして扱わないよう、外部コンポーネント側でもバージョンを確認する。

録音中はWeb画面が止まる

録音中はWi-Fiを一時停止するため、ブラウザーは応答待ちのように見える。録音終了後にWi-Fiへ再接続して応答を返す。

HTTP画面に認証はない

録音画面と/settingsには認証がない。信頼できるLAN内だけで使用し、ルーターでポート転送するなどしてインターネットへ直接公開しないようにする。

NVSの設定がYAMLより優先される場合がある

/settingsで保存したネットワーク設定はNVSに残る。YAMLを変更しても設定が変わらない場合は、NVS設定を確認または削除して再起動する。

LCDドライバーの非推奨警告

ESPHome 2026.7.2ではst7789vに非推奨警告が出る。今回は前回の実機確認済み設定との比較を優先し、そのまま使用している。

まとめ

ESP32-S3のI2Sからraw PDMを受け取り、CIC3とFIRを使って48 kHz PCMへ変換する構成をESPHomeの外部コンポーネントとしてまとめた。ハードウェア変換版と同様に、PSRAMへの録音、WAV/BWF取得、センサー表示、Home Assistant連携を一つのAtomS3Rで扱える。

関連記事・参考資料

コメント

タイトルとURLをコピーしました