VNAにはスミスチャートは欠かせません。このあたりを実現したいと調べていたところ、素晴らしいツールに出会いました。matplotlibとSciKit-RFです。これらを使って、スミスチャートの描画と、キャリブレーションが一気に片付きそうです。まだ試行中ですが、現時点でできているところまでを整理のために書いておきます。
matplotlibは、pythonで実装された種々多様なグラフを作成できるツールキットです。その実力については公式サイトにある作例をご覧頂きたいと思いますが、驚くほど柔軟で、様々な種類のグラフを任意のフォーマットで出力できます。PDFやSVGの他、GUIツールキットに埋め込んで使うことも可能です。以前紹介したRTLSDR-Scannerもmatplotlibを使用していました。matplotlibは、そのときにhomebrewでインストール済でしたが、Mac OSXの場合、若干の修正が必要でした。これについてはその記事を参照してください。
さっそく、matplotlibを使ってVNAの測定結果の生数値をプロットしてみました。データの読み込みもとても簡単です。
極座標表示もちょっと変えるだけでできます。
3D表示も可能です。周波数対極座標表示を合わせて3Dにしてみました。
3Dのグラフはマウスで回転させることができますので、回路の挙動をカーブを回転させながら任意の方向から眺めることができます。
matplotlibには射影変換にも対応しており、スミスチャートのような直交射影のグラフも実装できそうです。
さて、グラフ化は方法が見えてきたので、続いてデータの入出力形式をちゃんとしたものにしておきたいと思います。この世界の標準としてtouchstoneフォーマットというものがあり、本物のVNAやシミュレータなどのツールはこの形式を読み書きできるようになっています。デバイス等の特性もこのフォーマットで提供されていることが多いです。これに合わせておけば、結果を確認したりするのにいろいろ便利です。
touchstone形式は、シンプルなテキストでそれほど難しいものではなく、今使っている適当な中間ファイルを若干修正すればOKそうです。とはいえ、ファイルフォーマット系の実装はいい加減に作ると、のちのち残念なことになりがちですので、先人の成果を利用させて頂くのが定石です。探してみると案の定pythonのライブラリがいくつか見つかりました。一つはnportというもので、touchstoneの読み書きができるようです。しかもスミスチャートの描画機能も持っているようですが、enthoughtという商用のディストリビューションの存在が前提となっているようです。
もう一つ見つけたのは、こちらもpythonのライブラリでSciKit-RF、通称skrfです。こちらはミリ波などを対象にして回路網をコードで記述してシミュレーションすることが主眼のツールキットのようです。Sパラメータを含むZ,Yなど任意のパラメータファイルの入出力機能や、スミスチャートの他mag, db, ang, re/imなど様々なグラフを生成できるようです。SciKit-RFのグラフ描画の中身には、matplotlibが使われています。
なんと驚いたことに、SciKit-RFにはキャリブレーションの機能もありました。たとえばSOL法で、short, open, loadの終端について、実機での計測結果と理想状態を組にしてCalibrationオブジェクトに与えると校正値を得ることができ、これをDUTの測定結果に適用すると校正された測定結果が得られるという仕組みです。サイトにはサンプルコードまで載っており、校正が殆ど手間いらずで実装できてしまいそうです。
手っ取り早くこれらの機能を利用してみるには、自作VNAの測定結果をtouchstone形式にしてしまえば、あとはそれを加工したり、校正したり、チャート描画することができそうです。さっそく試してみました。
まずはSciKit-RFをインストールしておきます。pipコマンドを使えばすぐにインストールすることができます。
$ pip install scikit-rf
前回gnuplotで描画するために、gnuradioにより計測値の取得、ならびにdBと位相角(ラジアン)への変換をして、テキストファイルに書き出していました。これをtouchstone形式にしたいわけです。そのため内部で一度skrfのNetworkオブジェクトを作ることにしました。skrfのAPIを確認すると、測定値を複素数で扱うのが最も簡単です。位相角と振幅から計算しても良いですが、gnuradioで直接、複素数値が得られるようにスクリプト(フローグラフ)を改造しました。各周波数で計測を行い、得られた複素数値と周波数をそれぞれ配列に入れてNetworkオブジェクトを作り、write_touchstone関数でファイルに書き出すだけです。コマンドのオプション引数で、ファイル名を指定できるようにしました。
こうして生の測定値をtouchstoneファイルで得ることができるようになりました。
続いて校正です。ポートをshort, open, loadの各状態で測定した結果を保存しておきます。各終端状態の実現ですが、load状態は50Ωのターミネータを使い、open状態は端子解放のままとします。short状態は、SMAプラグを加工してショートプラグを作っておきました(首が折れて破損したSMAコネクタを利用しました)。
測定は500MHzまでの範囲として、下記のようにコマンドで行います。
$ mkdir 500
$ ./vna\_probe.py -s 1e6 -e 500e6 -o 500/open
$ ./vna\_probe.py -s 1e6 -e 500e6 -o 500/short
$ ./vna\_probe.py -s 1e6 -e 500e6 -o 500/load
こうすると、500というディレクトリに、open.s1p, short.s1p, load.s1pファイルが得られます。これがこの周波数範囲用の校正データとなります。またそれぞれの状態における理想値もtouchstoneファイルに用意しておく必要があるので、ideal.pyスクリプトで作成しました。これらのデータを使って、何かDUTの測定を行い校正してみます。
まずシンプルな測定例として、DUTとして15cm程度の同軸ケーブルの先に100Ωの抵抗を付けたものをポートに接続してみました。
測定はコマンドで行います。校正作業をやった同じ周波数範囲で測定を行います。
$ ./vna\_probe.py -s 1e6 -e 500e6 -o measured
measured.s1pファイルに生の測定値が得られます。これをさきほどの校正値で校正します。コマンドラインは以下です。結果はcalibrated.s1pに得られます。
$ ./calibrate.py -c 500 measured.s1p calibrated.s1p
校正された結果をプロットしますが、これもSciKit-RFの機能を使います。Networkオブジェクトにはplot_s_smithという関数があり、一発でチャートを描くことができます。
$ ./plot.py calibrated.s1p
それらしいチャートが得られました。右の100Ωの点(2+0j)から開始し、周波数が上がると同軸の長さ分ぐるっと回転している様子がわかります。校正面はコネクタ部分ですので、同軸が測定対象に含まれています。はて、回転方向が逆な気もします。どこかで符号を間違っているようです。また回転につれて膨らんでいっています。まぁまずはご愛嬌ということで。
このウインドウは拡大等マウスで操作することも可能です。残念ながらスミスチャート上に周波数やマーカを表示することができないので、周波数がわかりません。実現したいところですが、もうすこし調べてみる必要があります。
次に、何かそれなりに面白いDUTとして、144MHzと430MHzデュアルバンドトランシーバ用のホイップアンテナを接続してみました。
同じように計測、校正、プロットを行います。
$ ./vna\_probe.py -s 1e6 -e 500e6 -o measured
$ ./calibrate.py -c 500 measured.s1p calibrated.s1p
$ ./plot.py calibrated.s1p
するとこのようなチャートになりました。
インピーダンスが中央に近づいて離れるのを2回転しているのがわかります。
plot_it_allという関数もあり、これを使うとこのように複数のチャートを並べて表示することができます。振幅、位相、スミスチャート、複素数値の4つのグラフが表示されます。まるでどこかのVNAで見るような画面です。
上の二つのグラフは横軸が周波数です。144MHz付近と450MHz付近で極があり、位相のほうはぐるっとまわっているのがわかります。たしかにデュアルバンド用のアンテナとして納得できる特性です。430MHz帯の中心がちょっと上(460MHz付近)にずれている様子もわかります。
上記の測定は500MHzまでとしましたが、これは上の周波数の挙動が暴れて、全く納得できるものにならなかったためです。これはもう少し実験してみたいと思います。
本当は、原典の論文でやっていたように、本物のVNAと比べてみたいところですが、残念ながら身近にそのような環境はありませんので、それらしい結果が得られたことで良しとしたいと思います。
今回感じたのは、pythonによる理工系のツールの豊富さです。touchstone形式の読み書きなども、複数の実装がすぐ見つかり、コマンド1行で即座にインストールが完了し即座に使えてしまいます。いつものようにOSXで試していますが、基本的にプラットフォームに依存しませんので、LinuxやWindowsでも動作するはずです。今更ながらこの強力さには驚きを隠せません。
SciKit-RFには他にバーチャルインスツルメントという機能もあるようです。これは本物のベクトルネットワークアナライザをGPIBで制御してパラメータの設定や自動測定を行い、測定結果を取り込んだうえで処理することができるようです。作っているVNAもこれと同じインターフェースで使えるようにできると面白いかもしれません。
今回は反射特性(s11)のみを対象としましたが、スルー(s21)のほうも引き続き試してみたいと思います。
リファレンス
- 原典 https://sdr-kits.net/DG8SAQ/VNWA/Baier_VNWA2_QEX.pdf
- matplotlib https://matplotlib.org/
- OSXへmatplotlibをhomebrewでインストールする
- touchstone形式の解説 https://ena.tm.agilent.com/e5071c/manuals/webhelp/jpn/index.htm#measurement/data_output/saving_trace_data_to_a_file.htm
- https://www.vhdl.org/pub/ibis/connector/touchstone_spec11.pdf
- nport https://github.com/bmachiel/python-nport
- SciKit-RF https://scikit-rf.org/
- 作者による校正操作@YouTube(旧mwavepy) https://www.youtube.com/watch?v=oeTsGYP91go
- pylab-plot.py https://gist.github.com/edy555/5274996
- pylab-polar.py https://gist.github.com/edy555/5275009
- pylab-plot3d.py https://gist.github.com/edy555/5275017
- vna_probe.py https://gist.github.com/edy555/5275763
- ideal.py https://gist.github.com/edy555/5275768
- calibrate.py https://gist.github.com/edy555/5275771
- plot.py https://gist.github.com/edy555/5275775