以前の記事「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++側へ寄せている。
ハードウェア
使用したもの
- M5Stack AtomS3R
- AtomS3R内蔵のBMI270 (9軸センサー)
- AtomS3R内蔵のBMM150 (磁気センサー)
- AtomS3R用のPDMマイク基板 (以前の記事「M5Stack Atomic Proto Kit 用PCBの作成」 参照)
- SPH0641LU4H-1(PDMマイク)
- BME280 (温湿度センサー)
録音機能だけを確認する場合、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.yamlをsecrets.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ファイルをダウンロードできる。
録音開始要求を受けると、内部では次の順に処理する。
- リクエスト値を検証する
- 必要なPCMバッファをPSRAMに確保する
- ブラウザーへ録音開始の応答を返す
- Wi-Fiを一時停止する
- I2S PDM RXを開始してPCMを記録する
- 録音完了後にI2Sを停止する
- Wi-Fiを再開する
- 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の扱いやすさを残しつつ、録音のような独自処理を外部コンポーネントで
補う構成である。常時ストリーミングよりも、「小型センサーノードから必要な区間だけ
音を回収したい」という用途に向いている。



コメント