マイクロコントローラによるRF信号処理の取り組みとして、AD9857を試していました。AD9857は、DDSとしてデジタル的にRF信号を一発で生成するだけに留まらず、その信号をIQ変調できてしまうという優れものです。数MspsのIQデジタル信号の生成が必要ですが、ここを王道のFPGAを使うこと無しに、マイクロコントローラでやろうとしています。数ヶ月前にちょっと実験して、実現可能であることは確認したのですが、手がまわらず放置していました。ようやく手が付けられる状態になったので、作業を再開です。
ピン数が多いマイコンボードとして、Nucleoを使っています。14bitのIQ信号をパラレル接続してDDSにデータを供給します。さらにI2SコーデックであるTLV320AIC3204を接続して、音声信号をデジタルで取り込みます。取り込んだ音声データに対して変調処理を実時間で実行し、最終的にAD9857に喰わせてやれば、いきなり数十MHzの変調信号が取り出せるわけです。ちなみに、DUCとはDigital Up Converterのことです。
マイクにはスマートフォン用のものを使っています。ヘッドフォン端子を iphoneと互換の4ピン接続にしていますので、ここにヘッドセットを接続すれば、音声の入力と出力を同時に行うことができます。別の端子に2chのライン入力も設けていますので、テスト信号はこちらから入力することができます。
以前の実験では、サンプリング周波数スキームを、48kHzから1.5MHzに持ち上げるために、FIRで25/4倍という非整数のインターポーレーションを行っていました。そこからCICで5倍し、1.5MHzでDDSに入力、あとはDDSの内部で、ハーフバンドフィルタで4倍、そしてCICで32倍し、最終的には192MHzで駆動しました。勘違いでCICの変換比が2のベキでなければならない気がしていたのと、1.5Mspsでインターフェースすることが目標だったので、これに囚われていたのですが、実際試したところまだ動作に余裕があることが判ったので、構成を考え直しました。
新しいアップサンプリングスキームは、48kHzからFIRで4倍、さらにCICで10倍することで1.92Mspsとします。これをAD9857に喰わせて、4倍、そしてCICで25倍することで192MHzに持ち上げます。192kHzを通るので、ハイレゾな実験も可能かもしれません。
FIRの係数はPythonで計算しました。48kHzの4倍、192kHzのサンプリングレートにおいてカットオフ周波数13kHzで、ちょっと肩の鈍った60タップのフィルタの係数列を計算し、それをポリフェーズフィルタ用に4分割して、15タップで計算します。実際の処理ではSIMD命令の都合上データは2サンプルづつ扱いますので、16タップの8分割で計算を行います。
CICは1段ですが変換比は10倍。すなわち一度、微分処理した後、積分処理を10回繰り返して、積分毎に結果のサンプル値を得ます。この処理により、サンプル数を10倍に増やすわけです。あとはバッファに蓄積し、DMAがIQ DDSへ送り込みます。
さて変調ですが、まずは、変調モードとしてSSBを試してみます。SSBを生成するためには、音声の実信号を、複素信号に変換します。このとき、正または負いずれか片側の周波数成分だけを取り出すようにします。この変換をするのがヒルベルト変換です。まずは普通にヒルベルト変換を実装してみました。素直に48kHzのサンプリングに対して、127タップのヒルベルト変換を行うようにしました。係数列は、Webサイトで提供されていた計算ツールを使ってみました[2]。ヒルベルト変換の計算はFIRと同様ですが、係数列は中心から前後で符号を反対にした対称な形をしています。また交互に0になっています。これらの性質を使って計算量を減らすようにします。実信号から、ヒルベルト変換でIQ信号になり、以後のFIRやCICはすべてIQ両方に適用します。
うまく動作するようになった結果です。オーディオ信号として、200,400,600,800Hz、そして1000Hzから16000Hzまで1000Hzステップの複数のトーンを重ねた信号を生成し、それを入力として変調動作を行わせてみました。そのスペクトラムが下です。アップサンプリングのFIRフィルタの形がそのまま綺麗に出ています。
USB(upper side band)の信号としておおむねいい感じでしょう。0Hz付近の振幅の飛び出しはRBWとの兼ね合いで生じています。気になるのは0Hz付近で反対側に若干はみ出ているようです。拡大してみます。
200Hzと400Hzのトーンが、反対側に漏れ出ているようです。
やってみて判ったのですが、ヒルベルト変換は、タップを途中で打ち切っている関係上、0Hzで完全にカットされるわけではなく、少々逆サイドへ信号がはみ出てしまうようです。これはタップ数の少ないFIRフィルタの肩が鈍っているのと同様です。
(追記)考えてみれば当然の話で、127タップで、サンプリングレートが48kHzであれば、48000/127でおよそ400Hzですから、それ以下はFIRで素通りになるのは当たり前の話でした。50Hzまで欲しければあと8倍タップを増やすか、レートを下げるかのいずれかです。(追記終)
これを完全なものに近づけるためには、タップ数を増やすのが一つの方法です。現在の処理能力ではまだ余裕があるので、タップ数を増やすのは可能です。ただ、一つ言えるのは、SSBの変調のためにヒルベルト変換を48kHzで行うのは、サンプリングレートが高過ぎということです。今回は16kHz程度まで出ていますが、無線用であれば3kHz程度で切るのが適切です。そうであれば、サンプリングレートは8kHzで十分です。サンプリングレートが低ければ、同じタップ数でも相対的に切れが良いフィルタになります。
もう一つの手段としては、複素化をヒルベルトフィルタを使わず、複素係数のBPFを使用して、下を0Hzではなく100Hzあたりでカットしてしまうことです。または、周波数シフトと実係数LPFを使用するかです。いずれの方法も、ヒルベルト変換の係数のように良い性質があるわけではないので、負荷が増えそうです。どうするのが最適かは、もうちょっと考えてみたいと思います。
ちなみにLSBはこんな感じです。虚実のいずれかの符号を変えるだけですから簡単です。
ちなみに、冒頭の写真にあるように、マイクを接続して信号を発生させて、電波は空中には出さずATT経由で直結したドングルで受信してみました。
マイクを接続するとノイズが入るのでノイズで通過域の形が見えます。発生した周波数は51.5MHzです。
マイクを抜くと通過域のノイズが下がります。キャリアリークがありますが、どこかにオフセットが残っているようです。
反対のLSBです。この白帯が標準的な通過帯域なので、無駄に広いですね。
以上、信号処理を見直し、ヒルベルト変換を動作させてみました。フィルタを修正すれば、いきなり電波にしても良さそうな信号が得られています。ただし、課題もあり、入力が過大になった時にスプラッターが出てしまいます。特に息がマイクに直接掛かったような時、盛大にスペクトラムが広がります。アップサンプリングの計算途中でオーバーフローが起きているようです。飽和演算をうまく使うなど対策が必要です。
AMやNB-FMの実験もしているのですが、まだ思うような綺麗な信号にはなっていません。おそらく、ステレオFMの変調も可能だと考えています。引き続き実験してみたいと思っています。
アップサンプリングスキームを見直したので、AD9857では1.92MHzの帯域を取り扱うことができています。この帯域を使えば何か面白いことができそうな気がしています。自明ではない使い方を工夫してみたいところです。
ご参考に回路図とNucleo用のコードを晒しておきます。
リファレンス
- 今回の実験のソース https://developer.mbed.org/users/edy555/code/Nucleo_IQDDS/
- ヒルベルト変換の係数計算Webフォーム https://hs-soft.exout.net/hilbert.php
- アナデバAD9857製品ページ https://www.analog.com/jp/rfif-components/direct-digital-synthesis-dds/ad9857/products/product.html
- STMicroelectronics Nucleo https://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847
- TI TLV320AIC3204 https://www.tij.co.jp/product/jp/tlv320aic3204
- 前回の記事 AD9857とNucleo F401REとI2S Codec TLV320AIC3204によるDDS IQ変調実験