不満な点を改善したいと思えてきました。
- 当初考えたよりもコストパフォーマンスが良くなかった
- スピーカドライバをもっと簡単にできないのか
- アナログB入力がポンコツ(ノイズまみれ)
目次
スピーカドライバの再考
スピーカドライバは、ゲートドライバ+パワーFETブリッジの構成にしています。これは、確実なスイッチングを実現するためですし、部品表で見ても大したコストでもなく、十分良い設計と考えています。
しかしながら、自作のしやすさを考えたら、もっと安く単純にしたいとも思っていました。考えていたのは以下のようなものです。
- 単純にHブリッジ直結はダメなのか
- 内蔵DACとD級アンプでスピーカ駆動
- I2Sでのスピーカ駆動
- 入手性の良いモータドライバを利用
Hブリッジ直結
出来るのなら、みんなやっている。FETはソース/ドレイン電流・電圧の大きさによって、ゲートの負荷も大きい。今回の、目的の音声出力1~3Wでは、マイクロコントローラーの出力能力では出来るかもしれないし、できないかもしれないという微妙なところ。それ以上もそれ以下でもない、ガチガチの仕様(FET品種打ち抜きでの設計)にするのであれば、十分可能。
これも面白いが、今回はそそらない。そこまでの最適化を考えていない。
内蔵DAC+D級アンプ
ESP32には8bitのDACが2チャネルあるので、直接ステレオのアナログ音を出力する事ができます。これを、省電力型のD級アンプICでスピーカを駆動すれば良いのです。解像度には若干不安はあります。
D級アンプのICは豊富に提供されており、かつ低価格なので、作りやすく一番コストダウンできる構成だと思われます。が、私的にはそそりません。途中にアナログが介在してしますためです。
I2S出力
I2S経由で直接スピーカをドライブするICがあり、かなりのコストダウンできる可能性がありました。
- たまたま低価格で入手できるデバイスがあった(出物的商品)
- 結局内部ではDAC+D級アンプだった
- 高価なモジュール、もしくはパッケージが手ハンダ困難
1品物の工作なら良いと思います。特定のデバイスに制約されてしまうのは嫌です。2番手の構成と考えます。
モータドライバ流用
スピーカのPWM駆動は、Hブリッジでスイッチングするだけなので、モータードライバも全く同じ回路構成です。そこに着目し、流用が可能と考えました。モータードライバは、たくさんの品種があり保護機能が充実、価格も安いものがあるので注目していました。
初代”BTSP01″で使いましたが、省電力で有利な3値制御では実用レベルの音質には、なりませんでした。論理上は問題ないはずなのですが、腑に落ちませんでした。今、原因を再考すると
- 制御信号の与え方が間違っている/制約がある
- スイッチングスピード
制御信号の使い方のミスがあるかどうかについては、中音量以上では割と良い音が出ていますので、間違っているという訳ではないと思います。
そもそも、モータドライバのデータシートにタイミングに関する事柄の記述が十分ではなく(用途外使用なので仕方無し)、44.1kHzのPWM駆動が完全に出来るのか確信が持てない部分がありました。具体的には、PWMピリオド周波数のMAXを超えない範囲にしていますが、あるデバイスでは最小パルス幅という項目があり、これが最小デューティー値で問題があるかもしれません。44.1kHzで10bitの場合1/(44100*1024)=22nsが最小パルス幅となります。
以下に、入手しやすいデバイスのPWM周りのタイミング仕様一覧です。
最小パルス幅が明確になっていないものは全て問題ありです。モータドライバ系は、概ねダメなようです。それどころか、直FET駆動でも気をつけないといけないレベルです。とは言え、データシート上明確になっている訳ではないので、もしかしたら使えるかもしれません。(まわりの数値から無理っぽいとは思いますが)という事で、2つのデバイスを実際テストしてみました。
- TB6612(100kHz)
- TC78H653(500kHz)
テスト環境は、デバイスは秋月電子のモジュール基板を利用し、ブレッドボードでESP32開発ボードとスピーカを配線します。BTSP03のソフトウェアをそのまま使い3値制御された44.1kHzのPWMを生成し、音源はBluetoothで440Hz正弦波を与えます。
TB6612はきたない「ポー」音でした。やはり、BD6211と同じような感じです。
TC78H653はきれいな「ポー」音でした。やはり、違いました。以下は、スピーカー出力のシグナルをオシロスコープで観察したものです。これを見る限り、きれいなスイッチング波形です。
予想通り良さそうなので、次に音楽などの音源を入れてみました。
- 小音量領域になるとざらつき感が出てます
- 音量が大きいと全く問題なく聞く事ができます
- Hi-Fiレベルとは言えません
ボリュームを絞ると顕著です。予想するに、小duty値でのスイッチングが不十分なのかもしれません。私の感想では、BGMなどの平均音圧の音楽を聴いたり、常に音圧のあるテレビ放送では、使えると感じました。
モータードライバでも、PWM周波数が大きい品種は省電力オーディオにも使える可能性を持っているようです。Hi-Fiには無理でしょうが、使える場面は多いと思います。結果としては、消費電力を気にするアプリケーションで、さほど音質にこだわらない場合は、安価にできるデバイスだと思われます。
ESP32のADC性能を再調査
ESP32のADC性能が良くないという判定になっていましたが、本当にこんな製品を世の中に出す訳はないはずだと思い、再再度の確認作業を実施することにしました。
調査項目
無音時のノイズが一番気になるので、この部分を中心に調べます。おまけに入力レンジについても確認していきたいと思います。
- 無音時のノイズ
- 入力レンジ(電圧幅)
テスト環境
ESP32-DevKitに、無音と正弦波の信号を与えて、ADCでの連続キャプチャを行わせます。実際のオーディオキャプチャの状況にしたいので、2CH×44100kHzでの条件にします。数値データだけでは、ノイズが減ったのか増えたのか判断しづらいので、スピーカに出力して実際耳で聞きます。
今回は、BTSP03のソフトウェアをそのまま使っていきます。PCMデータをダンプするデバッグ機能が埋め込まれていますので、キャプチャデータを記録できます。スピーカでの出力も確認出来ます。仮想アナロググラウンド用の固定電圧は可変抵抗器で作り、シグナルジェネレータはADALM2000を使います。
- 無音データとして、仮想グラウンドレベル電圧を与える
- レンジぎりぎりの正弦波シグナルを計測器で生成
- ステレオ44.1kHzでサンプリング
テスト項目
テスト数を最小に、漏れがないように、テスト項目を整理します。
確認したいことを要約すると以下の通りです。
- アナログ入力ピン(チャネル)毎の違い
- 変換ビット数の影響
- サンプリング回数(マルチサンプリング)との関係
- 内部アッテネータ適用でノイズが減るか
- 仮想アナロググラウンド(AGND)生成用分圧抵抗値の影響(バイアス電流の確認)
- 外部信号処理(パスコンの有効性、それ以上の外部回路が必要か)
テスト実施
「idf.py -p /dev/cu.??? monitor」で、波形データのダンプが出るまで2〜3秒待ちます。この表示されたダンプデータをコピペ、編集してcsvデータに変換(grep,awk,sedを駆使すれば1行コマンド!)します。それを表計算ソフトで読み込み、折れ線グラフにするのは数操作で済みます。
レンジ確認
計測を進めると以下の問題が発生しました。
- 入力レンジとADC出力値の相違
- チャネルが変わるとAGNDレベルが変わる
- オーバーシグナルで反転する
入力信号は、無音用に一定電圧のAGNDを用意します。アッテネータの設定によって、電圧レベルが異なりますが、データシート上の各アッテネータ設定時の電圧範囲のまん中では、ADCの出力は2048(12bitの中間)にはならず、かなりズレるようです。どう計算するのかドキュメントを洗いましたが判明しません。結局、レンジを調べる為のSIN波をダンプから折れ線グラフにしつつ、逆設定となりました。
ADC入力チャネル毎に平均値が変わってしまう事案が確認されました。AGNDは固定電圧との想定のもと、左チャネルの平均値を内部のAGND値としていました。(ADCの出力データの10秒間の平均値)色々なケースでデータを取ると、思惑通りのデータになっていない事に気づきました。そこで、チャネル毎にAGND値を取得するように、ソフトウェアを改善しました。
今回、限界シグナルレベルを確認する事を行いましたが、上限/下限をオーバすると、現状維持か、0値となるようです。マイナス側では結果的に大きな歪み感がないかもしれませんが、プラス側でいきなり0(=-max)になってしまうので、聞いていられない音になるでしょうでしょう。ドキュメントを精査すると、12bitの場合4096カウント全てを使うわけではなく、3000ぐらいで有効範囲があるようです。波形を見ながら、試行錯誤で一定値(4080)を超えるデータは信頼できないと判断するロジックをソフトウェアに組入れ、とんでもない波形にならないようにしました。この辺りは調整項目です。
詳しくは、添付の表計算ファイルのグラフを参照ください。
ノイズ確認
1テストは3回実施し平均値を取り、つまらない間違いで混乱しないようにします。
データは1000サンプリングを対象にしています。数値はADCの生データではなく、PCM16ビットに変換した後の値です。元のADCデータにするにはn/16+2048で計算できます。
test#10はマルチサンプリングの効果を確認するためのテスト項目ですが、平均値、中央値が異常となりました。調査した結果、プログラムバグ(オーバフローが発生していた)によるものでした。最小・最大・標準偏差については影響がなかったので、再テストはしていません。
ノイズが大きい/小さいの客観的な判断を行うためには、どのような見方をすれば良いか考えました。
- 平均値は基本的に0になるはず(バグ発見した)
- 最大から最小の差を見たが、実聴とは合わないような気がする
- 最大から最小差では全体の傾向を掴むのは不十分
- データの分布を調べれば、より正確に見られると思い、標準偏差で見てみた
- 実聴と合致している感じなので、これで判断
test#4,#5の変換ビット数の項目については、非常に良い数値が出ていますが、それぞれx2, x4で考えなければなりませんので、実質800ぐらいです。
以下、テスト項目と付き合わせた結果、有効な対策優先順位です。
順位 | 対策 | 標準偏差 |
1 | アッテネータ適用(-12dB) | 350 |
2 | パスコン適用(0.1uF) | 450 |
3 | マルチサンプリング(x3) | 600 |
4 | 特定のチャネルを使う(CH4+5) | 700 |
1〜2の効果があるのは、インターネット上の情報とメーカ提供の情報(ADC API説明の部分)に合致しています。3は一般則だと考えます。4に関してはSTM32で同様な現象を見てきましたので、ESP32でもあるのかという感じです。
次に行うべきは、組み合わせた場合どこまで改善できるかです。そもそもが、ひどい状態であったので、全部の条件を掛け合わせてみるのが筋だと考えました。
1〜4を全て適用した追加試験「test#99-4」をしたところ、標準偏差100まで減りました。グラフでも一目瞭然、スムーズな線です。実聴ではプチプチ音はありますが、ほぼノイズが聞こえない状態です。全ての対策を行う事で、実用レベルの性能があると判断できました。最初の開発では、どうやってもノイズを実用レベルまで削減する事はできなかったのか腑に落ちません。やはり、時間をかけなさすぎたのかもしれません。
音楽などを聞いてみる
その後、音楽プレーヤなどの外部の音源を入れられるように回路を追加し、実聴しました。やはり、プリアンプがない状態なので、テレビのイヤホン出力では音量100%でも音が小さかったです。iPod/iPhoneにすると、音量80〜90%まで上げると、普通に使えるレベルになってます。使える音源機器に制約が出てしまいますが、こんな簡単な回路でも実用できるかもしれません。
1〜2日実生活で使ってみたところ、「チ、チ、、プチ、、、プチ、、、」とい感じで、100ms~1sぐらいの周期でランダムなプチ音が入っている事が気になってきました。また、1時間以上の周期で「ブチッ」という大きなノイズも入ります。ダンプで波形を確認すると確かに入っています。ADCのRAWデータを確認するため、マルチサンプリングを止めてみました。そうするとプチプチ音が全く無くなるという偶然に当たりました。x2までは大丈夫なようです。原因は未確認です。タイミング的なものと想定しています。
実機のADC性能が悪いのはなぜ?
良好な結果を得られましたが、なぜ前の開発ではノイズが多かったのかが疑問です。テスト回路と実機との相違を見直してみると
- ADC入力にパスコンを入れていなから?
- ADCチャネルのCH0,3を使っているから?
- プリアンプ(オペアンプ)を入れているから?
- 回路の問題
- ゲイン設定抵抗の定数、大きすぎる?
- AGND供給分圧抵抗の定数、大きすぎる?
- 電源ノイズ(5V)が大きい?
- アクティブフィルタ構成の影響?
一番気になるところは、やはりプリアンプの適用です。ADCのアッテネータ機能を使用するのが一番効果の高い対策なので、使わざるを得ない回路です。そこで、
- 実験回路にプリアンプを追加し、再試験
- ノイズが増えるようだったら、プリアンプを付けない判断にする
- ノイズが増えないなら、別問題という事なので、次に定数を変更して再試験
- ノイズが増えたら、実機の定数を変更する対策を施す
- ノイズが増えないなら、少しずつ実機の回路に寄せて再試験を続け原因箇所を特定する
- 実機と同じオペアンプによるオフセット付きの反転増幅回路
- 定数は実機より低めに設定
- 最初はBPFは付加しない
結果は、どうやっても大きなノイズが出なくなってしまいました。オペアンプのプリアンプ回路のせいではないという結果です。プログラム修正の影響も考えられましたので、ソースを戻してみましたが状況は変わりませんでした。
そうなると、実機固有の問題しかないと考えざるを得ません。以下の対応を行いました。
- 実機のオペアンプの各端子の信号をチェック
- 入力をショートして無音状態を作る(アンプラグでグラウンドショートするプラグデバイスの機能)
- Opamp-側のノイズが大きい(600mVp-p)
- 予想以上に大きすぎる!
- 原因は想定できず
- Opamp+側のノイズが大きい(360mVp-p)
- AGND線、単純にパスコンを追加すれば改善できるはず
- 60mVp-pまで削減
- しかしOpamp出力のノイズは変わらない。なぜ??
- Opamp出力のノイズは700mVp-p
- 発振している?負荷が軽すぎる?
- 負荷抵抗1kΩを付ける事で、28mVp-p(激減)まで減った
- 出力がハイインピーダンス状態なので不安定だったのかもしれない
- LTspiceでシミュレーションでも再現できず
- とりあえず回避策は見つけた
- 上記の対応を行なっても、ADCの出力は相変わらずノイズまみれ
- 数値としては、STDEVP=1900
- オペアンプ回路に問題はあったが、他に原因がある
- 関係ないと思われる部品を切り離してみる
- LCDモジュールのコネクタを抜く → 変わらない
- STDEVP=1900
- 全く関係ないと判断
- 外部ADC(PCM1808)を抜く → ノイズが劇的に少なくなった!
- STDEVP=120まで減っている(激減)
- 配線ミス発見、Vdd3.3Vのパスコンが配線されていなかった
- 配線するとSTDEVP=400、実聴でも減っているのを確認
- 3.3Vは、ESP32ボードから供給されているので、電源経由でノイズがESP32に入り込んだと思われる
- 3.3V電源経由のノイズの影響が大きいようだ(あたりまえ)
- 他の配線を見直したら、ESP32ボードの5V,3.3Vの両方にもパスコンがない!
- 追加配線するとSTDEVP=140、激減!
- 十分がまん出来るノイズレベルになった
- 電源にパスコン盛ったり、配線ルートを見直したりすれば、もう少し下げられるかもしれない
- LCDモジュールのコネクタを抜く → 変わらない
結局、くだらない配線ミスだった。
調査結果の反映
モータドライバ
モータドライバをオーディオ用途で使うには、2値制御でしか使えないという認識になっていました。一般的に、2値制御は電力効率的には不利なので、回避したいと思ってきました。しかし、モータードライバの品種によっては、3値制御にも追従し、省電力にも対応出来る時代になっている事が分かりました。
使える選択肢が増えるのは、良い事です。こうゆう部品の進化は嬉しい事ですが、これに頼るのは本意ではありません。選択のバランスが大事なのかもしれません。
内蔵ADC
ESP32内蔵のADCで、音声ステレオキャプチャが、実用レベルに近い事が判りました。しかし、Hi-Fiレベルではありませんし、いくつかの条件を整えないといけない事も分かりました。逆にいうと、この条件を飲めば、実用品への適用範囲が広がります。
- アッテネータ適用(-12dB) → 当初より対応済み
- ADC入力端子にパスコン(0.1uF) → 回路変更、アクティブLPF型からRC型へ
- マルチサンプリング(x2) → x3を設定変更のみ
- 電源パスコン見直し → 試行錯誤 → 回路変更
- 特定チャネルを使う(CH4+5) → 回路変更
実機への反映しています。
その先の展開
極端な話、ESP32ボードとモータドライバICと少数の受動部品だけで、アナログ入力付きBluetoothスピーカが作れてしまいます。最初に考えていた構成が実現できるのです。
実際作ってみました。
<写真>
USBから電源を得て、Bluetooth音源をスピーカーで鳴らすものです。アナログ入力もあります。汎用のマイクロコントローラである「ESP32」でも、ここまでできるという一例となるかと思います。
Copyright©2024 Toyohiko TOGASHI
コメントを残す