M5Stack AtomS3RでPDMマイクの音をハードウェアでPDM-to-PCM 変換して録音

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

以前の記事「M5Stack Atomic Proto Kit 用PCBの作成」 で示したPCBに部品を実装し、接続した小型のESP32-S3デバイスで、センサー値をHome Assistantへ送りながら、必要なときだけ
マイクの音を録音したい。そんな用途に向けて、M5Stack AtomS3RとPDMマイク
SPH0641LU4H-1を使った録音機をESPHomeで作った。

録音した音声はAtomS3RのPSRAMに一時保存し、ブラウザーからWAV/BWFファイルとして
ダウンロードできる。温度・湿度・気圧と9軸センサーの値は本体のLCDにも表示する。
ESPHomeデバイスとして値をHome Assistantへ公開することもできる。

コード、ビルド手順、HTTP仕様などはリポジトリ https://github.com/kunsen-an/pdm_recorder_esp32s3_hardware-PDM-to-PCM に収録している。

開発には、OpenAI Codex (5.6 Sol)を利用しました。手動で作成したPDMマイクからの録音をするESPHome のコードを基に、Codexによって修正を行いました。この記事作成にもCodexを利用しています。

この構成は8 MB PSRAMを搭載した AtomS3R専用 である。外観のよく似た
AtomS3にはPSRAMがないため、そのままでは動かない。

作ったもの

主な仕様は次の通りである。

項目 内容
MCU ESP32-S3 (M5Stack AtomS3R)
マイク Knowles SPH0641LU4H-1
録音形式 mono、16 bit PCM、WAV/BWF
既定サンプルレート 16 kHz
録音データの保持先 AtomS3RのPSRAM
録音操作 Webブラウザー、HTTP port 8088
センサー BME280、BMI270、BMM150
連携 ESPHome API / Home Assistant
検証環境 ESPHome 2026.7.2 / ESP-IDF 5.5.5

録音の流れはシンプルである。

PDMマイク
  ↓
ESP32-S3のPDM-to-PCM変換
  ↓
PSRAMへPCMを一時保存
  ↓
WAV/BWFヘッダーを付加
  ↓
ブラウザーへHTTP送信

microSDカードを使わないので、構成を小さくできる。一方、録音可能時間はPSRAMの
空き容量に制約される。16 kHz・16 bit・monoでは、音声本体だけなら1秒あたり
32,000 byteである。

なぜESPHomeの外部コンポーネントにしたのか

ESPHomeはセンサーやネットワーク設定をYAMLで組み立てられるため、Home Assistantと
組み合わせる用途には便利である。しかし、今回必要だった「指定時間だけ録音し、
PSRAMへ保持し、WAVとしてHTTPで返す」という一連の処理は標準コンポーネントだけでは
完結しない。

そこで、録音部分をC++の外部コンポーネントとして実装した。役割はおおむね
次のように分けている。

  • ESP-IDFのI2S PDM RXドライバーを使う録音処理
  • PSRAM上の録音バッファと状態管理
  • 録音開始・完了・ダウンロードを扱うHTTPサーバー
  • WAV/BWFヘッダーの生成
  • YAML設定をC++へ渡すESPHome側のコード生成

ESPHomeにはWi-Fi、OTA、Home Assistant API、センサー、LCD表示を担当させ、
時間制約の厳しい録音処理はC++側へ寄せている。

ハードウェア

使用したもの

録音機能だけを確認する場合、BME280やBMM150は必須ではない。ただし公開版の
YAMLはセンサーとLCD表示を含む統合構成なので、省略する場合は該当ブロックを調整されたい。

PDMマイクの配線

公開版で使うPDM信号は次のCLKとDATAである。

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

マイク基板のL/R選択端子は、使うチャンネルに合わせて固定する。信号電圧や
端子配置は、必ず使用するマイク基板の回路図も確認されたい。

セットアップ

1. 設定ファイルを用意する

リポジトリを取得し、プロジェクトのディレクトリへ移動する。

secrets.example.yamlsecrets.yamlという名前でコピーし、次の値を自分の環境に
合わせて変更する。

  • Wi-FiのSSIDとパスワード
  • ESPHome APIの暗号鍵
  • OTAパスワード
  • Fallback APのパスワード

secrets.yamlには認証情報が入るため、Gitへコミットしてはならない。公開版の
.gitignoreでは除外済みである。

2. 設定を検証する

esphome config atoms3r_pdm_recorder.yaml

エラーがなければビルドする。

esphome compile atoms3r_pdm_recorder.yaml

3. AtomS3Rへ書き込み、実行

AtomS3RをUSBで接続し、次を実行する。

esphome run atoms3r_pdm_recorder.yaml

初回書き込み後は、設定したWi-Fiへ接続される。IPアドレスはLCD、ルーターの
DHCP一覧、またはESPHomeのログで確認できる。

録音してみる

ブラウザーで次のURLを開く。

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

画面で録音時間とサンプルレートを指定して録音を開始する。録音完了後、
表示されたリンクからWAVファイルをダウンロードできる。

録音開始要求を受けると、内部では次の順に処理する。

  1. リクエスト値を検証する
  2. 必要なPCMバッファをPSRAMに確保する
  3. ブラウザーへ録音開始の応答を返す
  4. Wi-Fiを一時停止する
  5. I2S PDM RXを開始してPCMを記録する
  6. 録音完了後にI2Sを停止する
  7. Wi-Fiを再開する
  8. WAV/BWFヘッダーとPCM本体をHTTPで送る

録音中にWi-Fiを止めるのは、無線処理の割り込みや負荷がI2Sの連続読み込みへ
影響するのを避けるためである。そのため、録音開始直後はWeb画面へアクセスできなく
なるが、故障ではない。録音時間が終わりWi-Fiが再接続されるまで待つ。

WAVではなくBWFにも対応した理由

生成するファイルには通常のRIFF/WAVEチャンクに加え、BWFのbextチャンクを
含められる。BWF (Broadcast Wave Format) はWAVとの互換性を保ちながら、録音日時などのメタデータを
持たせられる形式である。

一般的な再生ソフトでは通常のWAVとして扱える。計測用途では、音声と同時刻の
温湿度、気圧、姿勢などを後から照合しやすくなる。

Home Assistantとの連携

録音用HTTPサーバーとは別に、ESPHome APIで次の情報をHome Assistantへ公開する。

  • 温度
  • 湿度
  • 気圧
  • 加速度
  • 角速度
  • 地磁気
  • IMU温度

LCDにも主要な測定値とネットワーク状態を表示する。これにより、通常時は
環境・姿勢センサーノードとして動かし、必要なタイミングでブラウザーから
録音する使い方ができる。

実機で確認したこと

公開版はAtomS3R実機で次の回帰試験を行った。

  • ESPHome 2026.7.2 / ESP-IDF 5.5.5での設定検証とビルド
  • AtomS3Rへの書き込みと起動
  • Wi-Fi接続、ESPHome API、OTA
  • BME280、BMI270、BMM150の読み取り
  • LCD表示
  • HTTPからの録音開始
  • 録音中のWi-Fi停止と録音後の再接続
  • WAVダウンロード
  • RIFFサイズ、サンプル数、録音時間の整合性
  • 複数回録音とHTTP接続切断後の回復

詳しい結果はリポジトリ内のdocs/TEST_RESULTS.mdにまとめている。

ハマりどころ

AtomS3とAtomS3Rを取り違えない

この実装は録音データをPSRAMに保持する。AtomS3Rは8 MB PSRAMを搭載しているが、
AtomS3は同じ条件では使えない。購入時とYAML選択時の両方で型番を確認されたい。

録音中はWeb画面が止まる

録音中はWi-Fiを一時停止する設計である。指定した録音時間に、再接続のための時間を
少し加えてからアクセスし直されたい。

HTTP画面に認証はない

録音用HTTPサーバーは認証を実装していない。同じネットワークの利用者は
録音の開始や直近データの取得を行える。インターネットへポートを公開せず、
信頼できるLAN内だけで使用されたい。

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

公開版では、実機で回帰試験できているst7789v設定を維持している。
ESPHome 2026.7.2では非推奨警告が出るが、現時点では警告だけを消すための
未検証移行は行っていない。mipi_spiへの移行は、表示を含む実機試験と
セットで行う予定である。

録音時間には上限がある

録音データ全体をPSRAMへ保持してから送信する方式である。長時間録音を行うと
メモリ確保に失敗する。必要量はおおよそ次の式で見積もれる。

PCMデータ量 [byte]
  = サンプルレート × 録音秒数 × チャンネル数 × 1サンプルのbyte数

たとえば16 kHz・mono・16 bitなら、60秒で約1.92 MBである。ただし実際には
ファームウェア、表示、センサー、通信処理もPSRAMを使うため、全容量を録音へ
割り当てることはできない。

まとめ

AtomS3RのPSRAMとESP32-S3のPDM RXを使い、ESPHomeへブラウザー録音機能を
追加できた。

  • PDMマイクのPCMデータをPSRAMへ保存
  • WAV/BWFとしてブラウザーから取得
  • 録音中だけWi-Fiを止めてI2Sを安定化
  • Home Assistantへ環境・9軸センサー値を公開
  • LCDで測定値と状態を確認

ESPHomeの扱いやすさを残しつつ、録音のような独自処理を外部コンポーネントで
補う構成である。常時ストリーミングよりも、「小型センサーノードから必要な区間だけ
音を回収したい」という用途に向いている。

コメント

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