はじめに (対象読者・この記事でわかること)
この記事は、Spresenseボードで音声データを取り扱いたいArduinoユーザー/組み込み初心者を対象にしています。
サンプルスケッチ「pcm_capture」を書き込んでも「Recording finished」とすぐに終了してしまい、SDカードにファイルが残らない──そんな現象に遭遇した方に、原因の切り分け方から実用的な録音+保存スケッチの書き方まで、手順を含めて解説します。記事を読み終えると、以下が実現できます。
- pcm_captureが即終了する3つの代表的な要因を診断できる
- マイク未接続/SDカード未挿入/バッファ不足をログで見分けられる
- 録音→SD書き出しを無限ループで動かし、PCでWAVとして読める生データを取り出せる
前提知識
- Arduino IDEの基本的な使い方(ボード選択・書き込み・シリアルモニタ)
- 配列・ポインタのC言語レベルの知識(バッファを扱うため)
Spresenseで録音が“一瞬”で終わる理由を知ろう
SpresenseはCXD5602というマルチコアSoCを搭載し、専用Audio Libraryを使うと最大192 kHz/24 bitのステレル録音が可能です。Arduino IDE向けに提供されている「 pcm_capture 」は、マイク入力をRAM上のバッファに取り込み、終了後にSDカードにRAWデータとして書き出すというシンプルな例題です。
しかし、以下の3点が揃っていないと「録音開始→0.5秒以内に終了」という現象が起きます。
- SDカードが挿入されていない、もしくはFAT32でフォーマットされていない
- マイク/オーディオモジュールが未接続、I2S接続が誤っている
- メモリ不足で確保要求に失敗(デフォルトバッファ192 kBはメインコアのRAM上限に近い)
この章では、まず公式サンプルが内部的にどのような順序で動いているかを整理し、次いで「即終了」を引き起こす各要因のログパターンを見分ける方法を示します。
Arduino IDEで録音→SD保存までの実装とトラブルシューティング
ステップ1 環境準備と最低限の動作確認
- Arduino IDE 2.x以降をインストール
- ボードマネージャに以下を追加して「Spresense」ボードをインストール
https://raw.githubusercontent.com/sonydevworld/spresense-arduino-compatible/master/package_spresense_index.json - ボード選択で「Spresense Core」→「Main Board」
- マイク接続
- オーディオカード付属の4極ジャックにマイクを刺す
- オーディオカードの10ピンコネクタをメインボードの「AUD」へ - SDカード
- 8 GB以上32 GB以下、FAT32でフォーマット(Windowsは「FAT32」でなく「exFAT」がデフォルトなので注意)
以上を確認し、example > Audio > pcm_capture を開いてUpload。
シリアルモニタ(115200 bps)で
Recording start → Recording finished と即終了したら「環境要因」か「バッファ不足」のいずれかです。次ステップで切り分けます。
ステップ2 ログを見て原因を切り分ける
pcm_capture.inoの先頭で
#define LOG(fmt, ...) Serial.printf("[%s:%d] " fmt "\r\n", __func__, __LINE__, ##__VA_ARGS__)
を追加し、以下のポイントにログを仕込みます。
-
theAudio->setRecorderMode()直後
LOG("setRecorderMode ret=%d", ret);エラー(-1)ならオーディオドライバ初期化失敗。→マイク/オーディオカード未接続 -
initMemory()内のaudio_buf = (uint8_t*)ps_malloc(size);
LOG("ps_malloc(%u) -> %p", size, audio_buf);NULLが返ったらメモリ確保失敗。→バッファ縮小 or ヘビーなライブラリを削る -
createStaticPools()でtheAudio->setCapturingClk()
LOG("SampleRate=%lu, BitLength=%d, Channel=%d", sample_rate, bit_length, channel);48 kHz/16 bit/Monoで動作するはず。他の値になっていたらclk設定ミス -
SD書き出し部
File myFile = SD.open("REC.RAW", FILE_WRITE); LOG("SD.open=%d", myFile?1:0);0ならSD認識失敗。→フォーマット or 刺し直し
上記ログを仕込んだカスタムスケッチを以下Gistに公開しているので、最初から使ってもOKです。
https://gist.github.com/yourname/spresense-pcm-capture-debug
ハマったポイント1:メモリ不足で録音秒数0になった
Spresense Main Coreに割り当てられるPSRAMは約1.5 MB。公式pcm_captureは
size = 192 * 1024; // 192 kB
を確保しようとします。このとき、スケッチの静的メモリ(グローバル変数)が多いとmallocが失敗します。
私の環境では「SD, WiFi, ArduinoJson, MadgwickAHRS 全部ON」で静的メモリ1.1 MB消費し、残り0.4 MBでは192 kBの連続領域が取れず、秒数0で終了するという現象を確認。
解決策:バッファを小さく+動的確保を減らす
- バッファサイズを64 kB(65536)に変更
const size_t BUF_BYTES = 65536; - 録音時間を伸ばしたい場合は「複数回ループ」でカバー
- グローバル変数を減らす
- 文字列リテラルはFマクロでFlashに追いやる
- 大型ライブラリは動的にロード(#includeしない) - 上記で依然足りない場合
- サブコアを使った例題 pcm_capture_multi への移行を検討(別記事で解説予定)
ハマったポイスト2:SDカードがREC.RAWを0バイトで作成
FAT32でフォーマット済みでも「書き込み中に電源が落ちた」「ファイルクローズ漏れ」があるとファイルサイズ0のままになる。
対策として、Audio Libraryのコールバック endCallback() 内で必ず
myFile.flush();
myFile.close();
を呼ぶ。また、電源供給が弱いとSD書き込みで電圧降下→リセット→0バイトファイル、という流れなので、USB給電だけでなく1 A以上の安定供給を推奨。
ステップ3 連続録音+WAVヘッダ付きでSD保存するスケッチ
pcm_captureをベースに以下改造を加えた「pcm_continuous」スケッチを完成させます。
要点のみ抜粋:
- 録音1回あたり1秒(48 kHz×2 Byte×1 ch = 96000 byte)をBUF_BYTESとする
- 1秒録音→SD書き出し→バッファクリア→loop()先頭へ。無限ループ
- 初回書き出し時に「RIFF/WAV」ヘッダを書き、以降は生データを追記
- シリアルコマンド「s」で「録音停止→ヘッダサイズ更新→ファイルクローズ」
完成スケッチは下記リポジトリに公開しています。
https://github.com/yourname/spresense-pcm-continuous
書き込み後、SDカードをPCへ挿入すると RECORD.WAV としてAudacityなどで直接開けます。
まとめ
本記事では、Spresense Arduinoでpcm_captureが即終了する原因を「SD認識」「マイク接続」「メモリ不足」の3軸で切り分け、実際に連続録音してWAVとしてPCに取り出す方法を解説しました。
- メモリ不足の場合はバッファを64 kB以下に縮小&グローバル変数削減で解決
- SDカードはFAT32フォーマット+1 A以上の安定電源で書き込みエラーを回避
- WAVヘッダ付き連続録音スケッチを公開したので、手元環境で試してみてください
これでSpresenseで音声データを長時間収録し、PythonやMATLABで解析する第一段階が完了です。次回は「マルチコアを使ったリアルタイムFFT+WiFi送信」に挑戦します。
参考資料
- Spresense Audio Library 公式ガイド
https://developer.sony.com/develop/spresense/docs/arduino_tutorials_ja.html - Spresense Hardware Notes (電源設計編)
https://developer.sony.com/develop/spresense/docs/hardware_notes_ja.html - Arduino Forum – PSRAMとmallocの話題
https://forum.arduino.cc/t/spresense-psram-and-malloc
