2023年8月26日土曜日

ESP32でMAX98357Aを使ってみた

 I2S接続のモノラルなアンプ付きDACがAliexpressで155円だったのでポチってみた。送料は一応このDAC2個の他に3点入れても170円だった(トータル1000円かからないお買い物)

MAX98357A搭載のモジュールなんだけど、1チップでI2SのDACとD級アンプが内蔵されていてスピーカーと直結できる模様。モノラルなのでステレオで出したい場合は2個必要らしい。一応2個買ったけど。

MAX98357A
見た目はAdafruitのものとほぼ同じである。基板の色が違うぐらいしか…
デフォルトでは5Vで動作させるとモードがLRミックスでゲインが9dbに設定されているっぽい。

さっそくESP32に接続して使ってみた。

ライブラリは有名所っぽいのが2種類あったのでまずはESP32-audioI2Sを試してみた。
こちらのライブラリは簡単にMP3なネットラジオを再生できるようなサンプルがあったのでそのまま試してみた。
しかしビットレートが高くなったとき?にプツプツと切れるっぽい。ESP32でストリーミングデータを受信しながらMP3デコードはちょっと厳しいのかな?

ライブラリもデュアルコアのESP32にしか対応していないっぽいし…

念のため別な方のライブラリも試してみることに。
ESP8266AudioはESP-WROOM-02でも音声が再生できるようなライブラリ。内蔵DACにも対応している。
ESP32でこのライブラリを使う場合のデフォルトピン配置は
LRC→25
BCLK→26
DIN→22
になっていた。このモジュールはアンプ内臓なのでVinは5Vに接続した。

こちらにはWebRadioというサンプルがあったのでそのまま使ってみた。しかしブラウザからシリアルコンソールに出たIPにアクセスしてもブラウザに"ERR_EMPTY_RESPONSE"というエラーが出て設定画面が開けない…

色々探していると、サンプルのweb.cpp内の処理でflush()関数がESP32 Arduino Coreのバージョン1と2で動作が異なるのに起因しているっぽい。このサンプルは1.0.x向けに作られているのでここらへんを2.0.xで動くように作り変えないといけない。GitHubのフォーラムに修正方法が載っていた。
ということでweb.cpp内の
    client->flush();
ってなってるところ2箇所を
    while (client->available()) {
      client->read();
    }
のように変更した。
Coreのv1ではflush()関数がバッファクリアしていたのに対して、v2ではflush()関数が処理が終わるのを待つような仕様になったためらしい。なのでバッファが0になるまでreadでバッファをクリアしている。(Serialも同じような仕様変更あったな…)
この変更をしたらブラウザで設定画面が開けるようになった。

同じラジオ局で試してみたがこっちのほうが安定性がいいかも。
最初の方はプツプツ切れたりするんだけど安定するとちゃんと再生できてるっぽい?

ちなみにESP32のI2S機能はGPIO Matrixに対応しているっぽいのでピンは入力専用ピン以外だったらどこでも使えそう。ライブラリによって微妙にピン設定が違うのでちょっとハマったけど、好きなピンに設定してしまえば良さそう。wclkPinはモジュール上はLRCだったりとか呼び方も微妙に違ったり…

さすが外付けDAC。ジャンクノートPCのスピーカを繋いで使ってみたけど音質は結構クリア。簡易的なWebラジオとして使う分には十分なんじゃないかな。