2016年 03月 09日

「コイルとコンデンサは電圧と電流の位相差を90度進めさせる/遅れさせる」とはどういう意味なのか

「コイルとコンデンサは電圧と電流の位相差を90度進めさせる/遅れさせる」という説明を良く見ますが、どうも直感的に理解できていませんでした。電圧と電流の位相差が±90度か0度しかとらないという話ではないだろうし、「途中の位相はないの?」と思ってしまうのです。この説明の意味がわからない、という意味です。

疑問の詳細

コイルとコンデンサの組合せで共振回路をつくった場合、電圧と電流の位相差はゼロになるはずです。ではすこしだけ共振していない場合はどうなるのでしょうか? 現実的には殆どの場合共振していないはずです。

「すこしだけ共振していない状態」であっても回路全体としてはインダクティブであるかキャパシティブであるかのどちらかであり、±90度の位相差は起こっているはずです。

でも現実問題としては回路全体で観測できる電圧と電流の位相差は必ずしも±90度ではありません。少しだけ共振していない場合は殆ど位相はずれていません。

途中の位相はどこいった?

式を使って「このように位相がずれます!!」というのは置いといて「途中の位相はどこいった?」という疑問だけ解決します。


純リアクタンス成分に関していえば、確かに±90度の位相差を常に起こしています。これはコイルとコンデンサだけで構成された回路なら回路全体に対してもあてはまります。「少しでも」コイルやコンデンサがあれば必ず±90度の位相差が起こっています。コイルとコンデンサの複合回路でも、共振していなければ必ず±90度の位相差が起きます。これはシミュレーションでも確認できます。

しかし実際の観測される位相は抵抗成分も含めて考える必要があります。これにより回路全体を見たときの位相差は任意の角度をとります。

全体として、抵抗成分が少なければ少ないほど-90度か+90度に近付き、リアクタンス成分が少なければ少ないほど、0度に近付いていきます。

複素平面上で見たときも、純リアクタンス成分は全体としても±90度にしかならないが、抵抗が加わった瞬間、合成された絶対値はいろんな別の角度をとりうることがわかります。

つまり

「コイルとコンデンサは電圧と電流の位相差を90度進めさせる/遅れさせる」というような説明は、純粋にそのコンポーネントの理想的な電圧の電流の関係をいっていて、抵抗成分を含めたことは言ってないわけでした。この説明、何度も何度も目にしてきたのに、何を言ってるのかわかりませんでしたが (途中の位相もあるよな?と思っていた)、ようやく意味がわかった気がします。

そして思いますが、この説明の仕方は筋が悪いと思います。現実のコイルやコンデンサには必ず無視できないほどの抵抗成分がありますから、これらのコンポーネントだけで回路を構成したとしても必ずしも位相差は±90度のどちらかになるというわけではないはずです。コイルやコンデンサと言うのではなくて「純リアクタンス成分は〜」とかで書いたほうが正確だと思いました。

2016年 03月 08日

自作SWR 計を一旦仕上げ

このへんのエントリの続きです

2014年に作ったSWR計でしたが、先月あたりセンサー部分の作りなおしをしてみて、前よりもよさそうだという感触を得られたので、一旦常用できるように仕上げることにしました。というのも、デスク上にバラックで積んであるブレッドボードと液晶がさすがに邪魔だからです……

PCB Milling で基板作成

今回 PCB-GCode という Eagle のプラグイン (ULP) を使ってみました。前に PCB Milling したときは謎の GCode 生成 ULP を使いましたが、こちらのほうが良くできていそうです。

こんな感じの基板を作って

PCB-GCode はこんな感じで

こんな感じの GCode をつくって

GrblServer で切削させて、実装しました。0.8T の基板なので配線が透けています。

片面切削だけにしたかったので、できるだけ Via をつかわず配線しています。そのため、DIP のピンとピンとの間を通すラインがあり、これがうまくいくか不安でしたが今回はうまくいきました。これぐらいなら 0.1mm 単位ぐらいの雑な調整でもなんとかなるようです。

CNC 切削で基板を作る場合、この程度の規模だと時間的にはユニバーサル基板で雑に実装するのとそれほど変わりません。しかし配線を Eagle 上でやって ERC にかけているのをそのまま切削しているので「配線ミス」というのが起きず、安心して実装できます。ユニバーサル基板での実装は結構気を使って疲れるので、ちょっと面倒でも切削でつくるのが気は楽です (ケースバイケースですが)。

インターフェイス

前に作ったものの中身をそっくり入れかえただけで、液晶も昔のものを再利用しています。バラック状態のときと違うタイプの液晶なので、ライブラリのAPIを適当にあわせたりして対応させました。

本当はせっかくなのでもっと格好いいケースに入れたいのですが、ひとまずこのような形におさめました。

ほかにも、高SWR時にブザーを鳴らす機能だとか、送信中にオンになるオープンドレイン出力だとか、シリアルに常時SWRを出力する機能なども実装してあるのですが、使ってません。

Dフリップフロップによる I/Q クロック生成

そういえば KX3 の源発振はDDSではなくて Si570 とかいうプログラマブルオシレータだよな、ということを思い出し、どうやって90度違いのI/Qを作ってるのが気になりました。

回路図を見ると以下らへんです。左側からきているのが Si570 からのクロックです。

NC7SB3257 はマルチプレクサ、74VHC4040 はカウンタで、ここはバイパス可能な1/8分周器なのでI/Qには関係ありません。

次に出てくる 74LVC74 は Dフリップフロップで、ここでI/Qのクロックを作っているようです。CLKc CLKs がそれぞれ In-phase と Quadrature のようです。

LTSpice でシミュレーションしてみる

LTSpice に入ってるデジタル素子でシミュレーションしてみました。この素子は理想素子なので、そのまま使うとシミュレーションできませんでした。適当に伝送路に遅延を入れるとなんかそれっぽい波形が出てきました。

4クロックで1つのI/Qクロックに変換される様子がわかります。

源発振の分周比を思い出す

KX3 で無線局免許を更新するとき、送信機系統図に源発振と出力周波数の関係を書いたことを思い出しました。これは電波法の規定で書かなければらないのですが、あまり深く考えていませんでした。以下の表です。

Dフリップフロップを使ったI/Qクロックは上記の通り4分周に相当するので、ここで書いてある表も殆どのケースで 1/4 の分周率になっているのでしょう。

1.8/1.9MHz だと4倍すると7.6MHzぐらいですが、Si570 が 10MHz〜 の発振器なのでさらに分周している、という話のようです。マルチプレクサとカウンタの分周は1.8/1.9MHz用というわけのようです。

DフリップフロップによるI/Qクロック生成のメリット/デメリット

メリット

  • 実質デジタル処理なので広い帯域で正確に90度位相差を得られる
  • クロック発信源が1つだけで良い

デメリット

  • 欲しい周波数の4倍の源発振器が必要
  • 矩形波出力 (デメリットかどうかは場合による)

200MHz ぐらいまでの発振器は安いのがいくらでもあるのですが、ここを超えると急に高価になる気がするので、50MHz で使うかどうか、DDS2台にするかどうか大きく判断が別れそうです。とはいえ、基本的にはDDS2台よりも安価で省電力そうです。

2016年 03月 07日

複素電圧・複素電流とはなんなのか

複素インピーダンスの場合、実数部は抵抗成分・虚数部はリアクタンス成分とわかれているので、イメージしやすいですが、電圧と電流の虚数部とは何なのでしょうか? と疑問に思ったので考えた結果をメモしておきます。

位相情報も含めた電圧・電流

実際のところ、位相も含めた電圧と電流は実数体で表現できます。つまり時間 、角周波数 、初期位相α、電圧振幅 E としたとき、時刻 t のときの電圧 v を表現するには

となります。この式は位相情報も完全に含んでいます。

ということで、位相を扱うには複素数が必須というわけではないわけで、なぜ複素数が必要なのかという気持ちになります。

しかし実数体で位相情報を含めて表現すると、上記のように三角関数を使うことになり、実際の計算はとても面倒になります。そこで、計算を便利にするために複素数の概念を入れます。

このとき使うのがオイラーの公式で、この場合、 三角関数が面倒なので指数関数にしてしまおう、そのためには電圧・電流表現を複素数体に拡大しよう、という感じのようです。

指数関数にするためにはこのような形式にする必要があるので、

と、電圧波形の式を複素形式にして (単に複素数部を付け加えているだけです。波形を表現するだけなら cos/sin はどっちがどっちでも良いので、オイラーの公式の形にあわせているだけです)

と指数関数に変換します。この形式で計算することで、オームの法則を使った普通の計算ができるようになって計算が楽になります。

例えばここでインピーダンスを考えると

e についている指数の割り算は指数同士の引き算になるので

指数の中を整理する

時間変数が消えてしまい、電圧と電流それぞれの初期位相 の位相差によって決まる定数がかかっている状態になります。この定数をまたオイラーの公式で戻してみると

この Z はインピーダンスなので、実数部は抵抗成分、虚数部はリアクタンス成分となっています。

はすなわち位相差なので、電圧と電流の位相差の cos() と sin() が単純な E と I との比にかかって複素インピーダンスを構成していることになります。

で、複素電圧と複素電流の虚数部は何なの?

複素電圧と複素電流の虚数部は何なのかというと「なんでもない」が答えのようです (単体では初期位相と関係しますが)。というのも、電圧にしろ電流にしろ負荷との関係をもって「電圧と電流の位相差」が現われるので、負荷との関係を考えない状態での、単体の複素電圧・複素電流の虚数部は何の意味もないということです。

インピーダンスは定義からして「電圧と電流の比」という関係の表現ですから、この関係の中に位相差が表現されるのは自然なことです。

2016年 03月 06日

アンテナアナライザーの回路 ー まとめ

http://www.rigexpert.com/index?s=articles&f=aas で紹介されている回路を一通り自分の中で整理してまとめました。詳しい動作は今まで書いた各エントリにして、ここではそれぞれの特徴を書いてみます。

「アンテナアナライザー」と書いていますが、これをさらに発展させて入出力ポート両方で測定するようにすればネットワークアナライザになるはずです。

ダイオードディテクタ

  • ダイオードで検波するので、小電力時の非直線性が問題になり (誤差が多い) キャリブレーションが必要になる

抵抗1本タイプ

[tech] アンテナアナライザの回路 シリーズ抵抗1本型 | Tue, Mar 1. 2016 - 氾濫原

入力電圧・負荷電圧・負荷電流

  • 回路が簡単
  • 電流検出部で小さな電圧を測ることになる
  • リアクタンスの符号は不明

ブリッジタイプ

[tech] アンテナアナライザの回路 ブリッジ型 | Tue, Mar 1. 2016 - 氾濫原

入力電圧・負荷電圧・負荷電流・平衡電圧

  • 電圧反射係数を別途測っているので、SWR の精度があがる (特に1.0付近)
  • リアクタンスの符号は不明

ログアンプ検波

[tech] アンテナアナライザの回路 - ブリッジの三つの電位差を測るタイプ | Thu, Mar 3. 2016 - 氾濫原

AD8307 を使って検波するタイプ。

入力電圧・負荷電圧・平衡電圧

  • キャリブレーション不要
  • 差動接続のためブリッジの平衡部に直結できる
  • リアクタンスの符号は不明

ログアンプ+位相検出

[tech] アンテナアナライザの回路 ー 位相検出器を使ったタイプ | Fri, Mar 4. 2016 - 氾濫原

AD8302 (ログアンプ+位相差) を使って検波するタイプ

方向性結合器 複素電圧反射係数

  • キャリブレーション不要
  • 移相器を使うものは移相器の調整が必要だがリアクタンスの符号がわかる

複素入力電圧・複素負荷電圧

  • キャリブレーション不要
  • リアクタンスの符号がわかる
  • DDS が2台必要

ヘテロダイン系

[tech] アンテナアナライザの回路 ー ヘテロダインを使ったタイプ | Fri, Mar 4. 2016 - 氾濫原

  • より高い周波数を扱う場合に検討の余地あり
  • 回路はより複雑
  • DSPが必要

雑感

ダイオードディテクタを使う場合、現実的には後段にオペアンプによるバッファ回路を検出電圧分だけつける必要があり、部品数がかなり増加する。

AD8307 で検波する場合、ほかの部品は殆どいらずMCUなどのADCに接続できる。しかも精度が高い。アナログ部分が格段に少なくなるので設計しやすい。値段が高いのだけが問題。

AD8302 で検波する場合、リアクタンス符号がわかるのが嬉しい。しかし AD8302 はかなり高い。そしてDDSも2台必要。

作るなら

これまでを踏まえて、〜50MHz ぐらいまでを対象に、コスト的にそこそこで楽に作れてよさそうというのは AD8307 とブリッジを使うタイプだと思う。

コストをもう少しかけていいのなら、AD8302 + DDS2台 も十分に簡単な回路で作りやすそう。リアクタンスの符号まで知りたいならこれが一番簡単そうに思う。


リアクタンスの符号までわからなくても、現実的にはあまり問題にならないことのほうが多そう。アンテナの調整を目的とする場合リアクタンスは「同調しているかどうか」の判断に使うなら符号はいらないし、調整してリアクタンスが増えるか減るかでも符号を推測できる。

2016年 03月 04日

アンテナアナライザの回路 ー 位相検出器を使ったタイプ

AD8302 (ログアンプ+位相検出器) を使った系です。

方向性結合器の出力を AD8302 に直接入れるタイプ

http://www.rigexpert.com/index?s=articles&f=aas

方向性結合器から進行波と反射波をとりだし、それを直接AD8302に入れるタイプのものです。

AD8302 にはログアンプであるとともに、2信号間の0〜180度の位相差の測定もできます。

位相差も測っているからリアクタンスも符号もわかると言いたいところですが、AD8302 の位相差は基準に対し0〜180度なので、この構成だと符号の区別はつきません。

AD8302 は AD8307 よりもさらに高価 (AD8302 はログアンプが2個と位相検出器が入っているので当然ですが) なので、リアクタンスの符号がわからないのはかなり残念な構成だと思います。正直、AD8302 を使って実装する価値はなさそうです。

計算

測定値として電圧反射係数 Γ の絶対値と位相角度 α がわかります。ということで反射係数の実部と虚部は簡単に求められます。

Γと伝送路インピーダンス・負荷インピーダンスの関係は


分母を有理化しつつ R + j X の形になるように (rectform()) していきます

ということで の形になったので R と X はそれぞれ

となります。計算上 X の符号は失われていませんが、そもそも最初の位相が正しかとれていないので符号がわかりません。

方向性結合器の出力の進行波側の位相を90度シフトしてから AD8302 に入れるタイプ

http://www.rigexpert.com/index?s=articles&f=aas

基準となる進行波の位相をフェーズシフターで90度進めることで、AD8302 の位相検出範囲を -90〜+90度にし、リアクタンス符号を計れるようにしたタイプです。

負荷インピーダンス自体は直接入れるタイプと同じように計算できます。こちらは符号が有効に出てきます。

広い周波数で正確にフェーズシフターを動かすのが難しいところだと思います。

抵抗ブリッジのリファレンス電圧と負荷電圧を計るタイプ

http://www.rigexpert.com/index?s=articles&f=aas

ブリッジのリファレンス複素電圧と、負荷の複素電圧を計るタイプです。AD8302 の片方には90度位相シフトした元の波形を入力し、位相検出範囲を -90〜+90度 にしています。

位相シフトした基準信号はDDSで作ります。つまりブリッジ入力用の信号源と、基準信号用の信号源とで DDS が2台必要です。しかし DDS なので広い周波数で正確な90度信号を作りだせます。

調整がいらないのが最大のメリットだと思います。

反射係数を直接測っておらず、基準電圧と負荷電圧を測っています。

E_{LOAD} と E_{REF} の絶対値と角度がわかっているので

電圧反射係数 Γ は

あとは上記の複素電圧反射係数から R と X を求める形でいけそうです。

アンテナアナライザの回路 ー ヘテロダインを使ったタイプ

ヘテロダイン(周波数変換)を使ったタイプ

http://www.rigexpert.com/index?s=articles&f=aas

この方法の利点は信号を選択できることで、矩形波の高調波も信号源とできることだと思われます。つまり低い周波数しか発振できなくても、高調波を使うことで広い周波数を測定できます。

アンテナの入力に適当な信号を入力し、測定したい周波数 + f の周波数を出力に合成して、低い周波数 (中間周波数) f に測定したい周波数を変換します。この中間周波数にバンドパスフィルタをかければ目的信号を選択できます。

十分低い固定の周波数に変換されるので、実際の検波処理・位相差検出はADCとソフトウェア処理で行えます。

ダイレクトコンバージョンを使ったタイプ

http://www.rigexpert.com/index?s=articles&f=aas

ヘテロダインの一種ですが、目的周波数自体と、位相差90度の信号を出力に合成して、I/Q 信号として直接 0Hz にコンバートします。実際の検波処理・位相差検出はADCとソフトウェア処理で行います。

2016年 03月 03日

アンテナアナライザの回路 - ブリッジの三つの電位差を測るタイプ

http://www.rigexpert.com/index?s=articles&f=aas

ブリッジの50Ω/50Ωで分圧したほうの電位 、負荷側の電位 、ブリッジ間の電位差 を測っているタイプです。

完全差動ログアンプのAD8307で検波を行っているのでダイオード検波にあるような非直線性を回避しつつ、外部にSPDT RFスイッチを2つだけ配置して高価なログアンプを1台ですませていて、このページの中だと一番おもしろい感じがします。

このタイプはなかなか理解できませんでした。

計算

ダメパターン

入力電圧を 1 としたとき、 の電圧は50Ωの と、負荷インピーダンス で分圧した形になりますから、

にかかる電圧は入力電圧から をひいて

の抵抗値は分っているので、電流値 を求めてみると

から を求めてみると

(2) を変形して (1) に代入すれば一発ですが、一旦電流を経由しています。

しかし測定している が絶対値なので、リアクタンスがある場合、 これでは正確に を求めることはできなそうです。

似たような方法で測定していて、上記のように説明しているページが見つかりましたが純抵抗で校正検証してるようでよくわかりませんでした……

http://www.kn9b.us/cloud-concept

じゃあどうするか

このパターンだと、ブリッジ間の電位差も測っています。この電位差は じゃないの? という感じで一見無駄のように見えますが、リアクタンス成分がある場合、検波するまでは複素数なので、同じにはなりません。

イメージとしては、 を測っているときと、オフセットされた との差の関係を見るという感じでしょうか。

複素電圧の関係を図にすると以下にようになります。青のベクトルが 、赤のベクトルが 、緑のベクトルが を表しています。

半径の円の交点の座標がわかれば の複素電圧がわかることが見てとれます。

負荷電圧と反射係数だけから負荷の複素インピーダンスを求める

(複素インピーダンスといってもリアクタンスは例によって絶対値だけです)

図形的に複素電圧がわかりそう、ということは複素インピーダンスもわかりそうだ、ということで、数式をいじくって解いてみます。

まず とブリッジの入力電圧である の関係を確認しておきます


の絶対値を式にすると

の絶対値を式にすると

(1) と (2) の連立方程式から を求めます。あきらかに面倒なので maxima で解きました。

と、やたら複雑ですが解くことができました。もっと綺麗な式になるかもしれませんが……

余談ですが maxima に連立方程式を解かせる場合、sqrt() を分解してくれないことがあるので、そこだけ自力でやったりすると解けたりします。

シミュレーションで確かめる

LTSpice でブリッジと負荷を構成し、作った負荷と、実際にシミュレーションして得た電圧から上記で求めた複素インピーダンスを比較して確認します。

以下のような回路です。

.meas を使って各ポイントの電圧を求めています。RMSを検波出力としています。こんな感じでログに出ます。

ログの出力をいちいちコピペして計算するのもダルいので、このログの出力をパースして上記式で解いてみる Ruby スクリプトを書いてみました。

コードは末尾に置きますが、結果だけコピペすると以下の通りでした。(ltspice simulated voltages) から求めたのが calculated で、calculated error に計算されるべき値との差が入っています。だいたい計算はあってそうです。

ruby 2.0.0p645 (2015-04-13 revision 50299) [universal.x86_64-darwin15]
Condition:
	{:r=>25.0, :x=>1591.5494309189535, :z=>1591.74576834947}
complex v:
	{:v_r=>0.9985228396122859, :v_i=>0.031346316992564995}
(calculate with 0.5):
	{:e_ref=>0.5, :e_load=>0.9990147410405821, :e_diff=>0.49950737052029104}
(ltspice simulated volatages):
	{:e_ref=>0.350149, :e_load=>0.699604, :e_diff=>0.3498}
calculated:
	{:r=>25.2897097114912, :x=>1591.5067030422704, :z=>1591.7076224124105}
calculated error:
	{:r=>-0.2897097114911986, :x=>0.042727876683102295, :z=>0.038145937059425705}

Condition:
	{:r=>50.0, :x=>1591.5494309189535, :z=>1592.3346353886939}
complex v:
	{:v_r=>0.9980338412035863, :v_i=>0.03129238913528186}
(calculate with 0.5):
	{:e_ref=>0.5, :e_load=>0.9985242920457066, :e_diff=>0.49901595225182244}
(ltspice simulated volatages):
	{:e_ref=>0.35015, :e_load=>0.69926, :e_diff=>0.349455}
calculated:
	{:r=>50.32437181406401, :x=>1589.9247651730511, :z=>1590.7210004614456}
calculated error:
	{:r=>-0.3243718140640084, :x=>1.6246657459023481, :z=>1.613634927248313}

Condition:
	{:r=>75.0, :x=>1591.5494309189535, :z=>1593.3155968164137}
complex v:
	{:v_r=>0.9975477257601216, :v_i=>0.03122332536748392}
(calculate with 0.5):
	{:e_ref=>0.5, :e_load=>0.9980362524558889, :e_diff=>0.4985264641481664}
(ltspice simulated volatages):
	{:e_ref=>0.350146, :e_load=>0.69891, :e_diff=>0.349107}
calculated:
	{:r=>75.577314946581, :x=>1592.1658690154652, :z=>1593.9586208532223}
calculated error:
	{:r=>-0.5773149465809979, :x=>-0.6164380965117289, :z=>-0.6430240368085833}

Condition:
	{:r=>25.0, :x=>159.15494309189532, :z=>161.10647383201098}
complex v:
	{:v_r=>0.8788575625045866, :v_i=>0.25707223660794654}
(calculate with 0.5):
	{:e_ref=>0.5, :e_load=>0.9156837609164615, :e_diff=>0.45784188045823077}
(ltspice simulated volatages):
	{:e_ref=>0.350146, :e_load=>0.6411, :e_diff=>0.320345}
calculated:
	{:r=>25.333147144876502, :x=>159.41449698716028, :z=>161.4148388281985}
calculated error:
	{:r=>-0.3331471448765022, :x=>-0.25955389526495765, :z=>-0.308364996187521}

Condition:
	{:r=>50.0, :x=>159.15494309189532, :z=>166.8241466652368}
complex v:
	{:v_r=>0.858478400162449, :v_i=>0.22523862168419417}
(calculate with 0.5):
	{:e_ref=>0.5, :e_load=>0.8875345628445539, :e_diff=>0.4233665079824152}
(ltspice simulated volatages):
	{:e_ref=>0.350147, :e_load=>0.6215, :e_diff=>0.296282}
calculated:
	{:r=>50.449523403617995, :x=>159.4899517034167, :z=>167.27880650581648}
calculated error:
	{:r=>-0.44952340361799514, :x=>-0.3350086115213742, :z=>-0.4546598405796658}

Condition:
	{:r=>75.0, :x=>159.15494309189532, :z=>175.9411717324414}
complex v:
	{:v_r=>0.8473945832635346, :v_i=>0.19430325132965703}
(calculate with 0.5):
	{:e_ref=>0.5, :e_load=>0.8693856067486138, :e_diff=>0.39804114103710525}
(ltspice simulated volatages):
	{:e_ref=>0.350147, :e_load=>0.608911, :e_diff=>0.278669}
calculated:
	{:r=>75.55035761860219, :x=>159.54194370186138, :z=>176.52616898484652}
calculated error:
	{:r=>-0.5503576186021917, :x=>-0.38700060996606567, :z=>-0.5849972524051168}

Condition:
	{:r=>25.0, :x=>15.915494309189533, :z=>29.636176526432088}
complex v:
	{:v_r=>0.36206078079200993, :v_i=>0.1353749068388477}
(calculate with 0.5):
	{:e_ref=>0.5, :e_load=>0.38654155583759237, :e_diff=>0.19327077791879618}
(ltspice simulated volatages):
	{:e_ref=>0.350148, :e_load=>0.271725, :e_diff=>0.135173}
calculated:
	{:r=>25.089881853395678, :x=>16.0713690194714, :z=>29.7958230894429}
calculated error:
	{:r=>-0.08988185339567778, :x=>-0.15587471028186783, :z=>-0.15964656301081348}

Condition:
	{:r=>50.0, :x=>15.915494309189533, :z=>52.471925437378836}
complex v:
	{:v_r=>0.5123522615159288, :v_i=>0.0776115480673238}
(calculate with 0.5):
	{:e_ref=>0.5, :e_load=>0.5181972522832335, :e_diff=>0.07858836273879492}
(ltspice simulated volatages):
	{:e_ref=>0.350148, :e_load=>0.363498, :e_diff=>0.0557211}
calculated:
	{:r=>50.08913489974573, :x=>16.133109401993394, :z=>52.62317601572157}
calculated error:
	{:r=>-0.08913489974572997, :x=>-0.21761509280386093, :z=>-0.15125057834273292}

Condition:
	{:r=>75.0, :x=>15.915494309189533, :z=>76.67009168577957}
complex v:
	{:v_r=>0.6063811091086553, :v_i=>0.0501171137437655}
(calculate with 0.5):
	{:e_ref=>0.5, :e_load=>0.6084486622335925, :e_diff=>0.11759534627353731}
(ltspice simulated volatages):
	{:e_ref=>0.350148, :e_load=>0.426484, :e_diff=>0.0828987}
calculated:
	{:r=>75.08881154062821, :x=>16.196121314941593, :z=>76.8156492144165}
calculated error:
	{:r=>-0.08881154062821395, :x=>-0.28062700575205923, :z=>-0.14555752863692817}

検証コード

require 'pp'

result = <<-EOS
.step r=25 c=1e-11
.step r=50 c=1e-11
.step r=75 c=1e-11
.step r=25 c=1e-10
.step r=50 c=1e-10
.step r=75 c=1e-10
.step r=25 c=1e-09
.step r=50 c=1e-09
.step r=75 c=1e-09


Measurement: e_ref
  step	RMS(v(ref))	FROM	TO
     1	0.350149	0	3e-06
     2	0.35015	0	3e-06
     3	0.350146	0	3e-06
     4	0.350146	0	3e-06
     5	0.350147	0	3e-06
     6	0.350147	0	3e-06
     7	0.350148	0	3e-06
     8	0.350148	0	3e-06
     9	0.350148	0	3e-06

Measurement: e_load
  step	RMS(v(load))	FROM	TO
     1	0.699604	0	3e-06
     2	0.69926	0	3e-06
     3	0.69891	0	3e-06
     4	0.6411	0	3e-06
     5	0.6215	0	3e-06
     6	0.608911	0	3e-06
     7	0.271725	0	3e-06
     8	0.363498	0	3e-06
     9	0.426484	0	3e-06

Measurement: e_diff
  step	RMS(v(load)-v(ref))	FROM	TO
     1	0.3498	0	3e-06
     2	0.349455	0	3e-06
     3	0.349107	0	3e-06
     4	0.320345	0	3e-06
     5	0.296282	0	3e-06
     6	0.278669	0	3e-06
     7	0.135173	0	3e-06
     8	0.0557211	0	3e-06
     9	0.0828987	0	3e-06
EOS

steps = []
name = nil
result.split(/\n/).each do |line|
	case line
	when /^\.step r=(?<r>\d+) c=(?<c>.+)/
		r = Regexp.last_match[:r].to_f
		c = Regexp.last_match[:c].to_f
		steps << {
			r: r,
			c: c,
			data: {}
		}
	when /^Measurement: (?<name>.+)/
		name = Regexp.last_match[:name]
		steps.last[:data]
	when /^     (?<n>\d+)	(?<value>[\d.]+)	0	3e-06/
		n = Regexp.last_match[:n].to_i - 1
		value = Regexp.last_match[:value].to_f
		steps[n][:data][name] = value
	end
end

Z_0 = 50.0
freq = 10e6;

def Math.pow(a, b)
	a ** b
end

steps.each do |step|
	farad = step[:c]
	resitance = step[:r];
	reactance = 1 / (2 * Math::PI * freq * farad);
	z = Math.sqrt(reactance * reactance + resitance * resitance);
	expected = {r: resitance, x: reactance, z: z}
	puts "Condition:\n\t#{expected}"

	e_ref = 0.5
	e_load = Math.sqrt( (resitance * resitance + reactance * reactance) / (Math.pow(resitance + Z_0, 2) + reactance * reactance) ) * 2 * e_ref;
	e_diff = Math.sqrt(
		(Math.pow(resitance - Z_0, 2) + reactance * reactance) /
		(Math.pow(resitance + Z_0, 2) + reactance * reactance)
	) * e_ref;

	v_r = (Math.pow(e_ref, 2)+Math.pow(e_load, 2)-Math.pow(e_diff, 2))/(2*e_ref);
	v_i = Math.sqrt(-Math.pow(e_ref, 4)+2*Math.pow(e_load, 2)*Math.pow(e_ref, 2)+2*Math.pow(e_diff, 2)*Math.pow(e_ref, 2)-Math.pow(e_load, 4)+2*Math.pow(e_diff, 2)*Math.pow(e_load, 2)-Math.pow(e_diff, 4))/(2*e_ref);
	puts "complex v:\n\t#{{v_r: v_r, v_i: v_i}}"

	puts "(calculate with 0.5):\n\t#{{
		e_ref: e_ref,
		e_load: e_load,
		e_diff: e_diff,
	}}"

	e_ref = step[:data]["e_ref"]
	e_load = step[:data]["e_load"]
	e_diff = step[:data]["e_diff"]

	puts "(ltspice simulated volatages):\n\t#{{
		e_ref: e_ref,
		e_load: e_load,
		e_diff: e_diff,
	}}"

	r = ((Math.pow(e_ref, 2)-Math.pow(e_diff, 2))*Z_0) / (2*Math.pow(e_ref, 2)-Math.pow(e_load, 2)+2*Math.pow(e_diff, 2));
	x = Math.sqrt(-Math.pow(e_ref, 4)+2*Math.pow(e_load, 2)*Math.pow(e_ref, 2)+2*Math.pow(e_diff, 2)*Math.pow(e_ref, 2)-Math.pow(e_load, 4)+2*Math.pow(e_diff, 2)*Math.pow(e_load, 2)-Math.pow(e_diff, 4))*Z_0/(2*Math.pow(e_ref, 2)-Math.pow(e_load, 2)+2*Math.pow(e_diff, 2));
	z = Math.sqrt(r * r + x * x)
	puts "calculated:\n\t#{{r: r, x: x, z: z}}"
	puts "calculated error:\n\t#{{r: expected[:r] - r, x: expected[:x] - x, z: expected[:z] - z}}"

	puts
end
2016年 03月 01日

アンテナアナライザの回路 シリーズ抵抗1本型

http://www.rigexpert.com/index?s=articles&f=aas

このページが面白いので、1つ1つ見ていきたいという気持ちがあります。まずは一番上の Analyzers based on diode detectors のうち、抵抗1本を検出に使うものです。

やってることは負荷インピーダンスを電流と負荷電圧から求め、さらに入力電圧との関係からリアクタンスの絶対値まで求めるものです。

計算

1 を 、2 を 、3 を という名前にします。

負荷 に対し、それぞれの電圧を としとき、負荷 にかかっている電圧 の絶対値(検波値) は

回路全体にかかる電圧

(1) の式を について解いて

(3) を (2) に代入する。

これを について解く

(3) の式のルートをとって を求めると

また、回路全体の電流

負荷 はそれぞれ

となり、抵抗成分とリアクタンス成分の絶対値が求まる (容量性か誘導性かはわからない)

アンテナアナライザの回路 ブリッジ型

http://www.rigexpert.com/index?s=articles&f=aas

ブリッジタイプ (図の右側。2番)

これはリターンロスブリッジを使う形のものです。

  • 1を
  • 2を
  • 3を
  • 4を

とすると

から電圧反射係数が求められます。 で入力電圧を求め、 で得た電圧反射係数を正規化するイメージ)

から負荷インピーダンスの絶対値がわかります。

ブリッジのイメージをつかむ

一番問題なのはブリッジに接続されている がどのようになるかです。負荷側の電位は50Ωと負荷インピーダンスとの分圧、もう片方は50Ωと50Ωの分圧で固定になっています (すなわち入力電圧の0.5倍が基準点)。

ここでもし負荷インピーダンスが50Ωであれば、負荷側の分圧も入力電圧の0.5倍になり、ブリッジ部分の電位差はゼロになります。ブリッジの平衡状態です。

負荷インピーダンスが25Ωになると、25/(25+50)=0.333... で電位差が -0.1666...、100Ωになると 100/(100+50)=0.666... で電位差が 0.1666... になります。つまりここの電位差は基準インピーダンス50Ωに対しての比になります。

もし入力電圧が1Vだとしたら、この電位差の2倍がすなわち電圧反射係数になります。(反射係数には複素数の場合、角度が出てくるが、位相は計っていないのでこれはわからず、この反射係数は絶対値です)

ブリッジ電位差が反射係数になっていることを確かめる

ブリッジ中の負荷インピーダンスを とし、それ以外のインピーダンス値を とすると、入力電圧が1Vのときのブリッジの電位差 E は以下のようになります。ここで、 をブリッジの50Ω/50Ωで分圧された側の電位、 を負荷側の電位としています。

電圧反射係数は

なので、1Vのとき、ブリッジの電位差は反射係数の半分になっています。また、 は入力の半分の電圧になりますから、ブリッジ電位差 で正規化することで反射係数そのものを求められます。

反射係数の大きさと、負荷インピーダンスがわかると、負荷の成分がわかる

反射係数の大きさと、負荷インピーダンスがわかると、まず負荷の抵抗成分を求められます。

反射係数の大きさ 、伝送路インピーダンス 、負荷インピーダンス の関係は以下の通りです。

は 50Ω なので 50 で置き換え、Z は R + jX に置き換えます。

絶対値同士の比なので分子分母とも絶対値にします

負荷インピーダンスの絶対値が既知ですから

(2) を (1) に代入します

難しいので maxima で解かせて

R が求められれば 、Z との関係から X の絶対値も求められます。

あれ? VSWR って簡単な比で求められなかったけ?

VSWR は以下のような式で求められますが、これは負荷インピーダンスが純抵抗な場合 (jX = 0) だけで、純抵抗でなければ反射係数を一旦求める必要があります。

この式を前提にインピーダンス比がSWRになる(インピーダンスがSWRに直接関連づく)と覚えていると、SWRと負荷インピーダンスの値から R が求められる理屈がわからなくなります。

インピーダンス比からSWRを求めた場合、純抵抗を想定してSWR値を求めたわけですから、このSWRと負荷インピーダンスからRを逆算すると、必ず jX の項は0になります。

別の説明をすると、たとえ同じ絶対値の負荷インピーダンスでも、リアクタンス成分でSWRは上がります。Z = 50 であっても、50 + 0j の場合と 0 + 50j の場合では違うよということで、前者のSWRは1ですが後者は無限です。