広帯域VCOの試作(1~2.2 GHz/1.6~2.7 GHz)

はじめに

今回は、マイクロストリップフィルタを用いた広帯域VCO(voltage controlled oscillator)を試作し、発振周波数・出力パワーを測定したので記録として残す。過去にも何度かVCOの試作にトライしてきたが、安定した発振を得るのが難しかった。今回の試作は結構上手くできたと思うので、これを基にしてPLLシンセサイザへと発展させたい。

原理

集中定数の発振回路では、コルピッツ発振回路やハートレー発振回路といった回路が有名だが、基本原理はどれも同じでフィードバックループの位相が360°(またはその整数倍)まわる周波数でゲインを持たせることで発振が得られる。よく例えられるのが、スピーカーとマイクのハウリングの原理。スピーカーで再生された音がマイクに拾われて、アンプで増幅されてスピーカーから再生される。これが繰り返され、ちょうど位相の揃う周波数が増強されて「キーーン」と鳴る。

Figure 1に今回試作した発振回路の構成を示す。位相をまわすフィードバック部分に分布常数回路を用いたバンドパスフィルタを採用した。バンドパスフィルタは、狭帯域であるほど通過帯域内で位相が急峻に回る。位相特性の傾きが急峻であるほど、スペクトラム線幅の細い、位相雑音の小さい発振器を作ることができる。

Figure 1 - Principle of VCO using a tunable filter

ざっくりとした理解だと、位相特性のグラフφ(f)とφ=360°との交点が発振周波数foscになる。Figure 2(a)のようにφ(f)の傾きがなだらかな場合、位相特性が少し変動するだけで交点の位置が大きくズレてしまうため、発振周波数が揺らぎ位相雑音としては大きくなる。一方、Figure 2(b)のようにφ(f)の傾きが急峻であれば、位相特性の変動に対して交点の位置はほとんど動かず、そのぶん位相雑音は小さくスペクトラム線幅も細くなると考えられる。

Figure 2 - Slopes of φ(f) and phase noises

過去に、チューナブルフィルタの実験をしたことがある。DUTはマイクロストリップの結合線路を用いたコムラインフィルタ。振幅・位相特性をNano VNAで測りながらバリキャップの電圧を調整して、特性が変化することを確認できた。通過帯域内で位相が急峻に回るようすがNano VNAの画面から読み取れる。

Figure 3 - Experiment of a tunable filter


下の論文が参考になった。
C. -H. Tseng and C. -L. Chang, "Design of Low Phase-Noise Microwave Oscillator and Wideband VCO Based on Microstrip Combline Bandpass Filters," in IEEE Transactions on Microwave Theory and Techniques, vol. 60, no. 10, pp. 3151-3160, Oct. 2012, doi: 10.1109/TMTT.2012.2210441.

回路図

Figure 4にVCOの回路図を示す。結合したマイクロストリップ両端のオープン容量をバリキャップにすることでチューナブルフィルタを構成する。R1~R3を介してバリキャップダイオード1SV280に逆バイアスを与える。マイクロストリップの中点がちょうど節(振幅が最小)となるため、R1~R3を中点に配置することで共振器の損失を抑える。フィルタ~FETは無駄な遅延を入れたくないので、とにかく最短距離で配置する。

Figure 4 - Schematic of the VCO prototype

FETはデプレッション型のNE76084を用いるが、ゲートはゼロバイアスで使うことにした。ドレイン電流はMax. 30 mAくらい流れる。ドレイン電圧VdはインダクタL1を介して供給する。Vdは低いとゲインが足りず、高いとバリキャップが飽和するためか発振が止まってしまい、最適値が存在することが実験から分かった。実験によりVd=1.5 Vが良さそうだった。C4はDCカット、R5は負荷インピーダンスを軽くするために入れている。出力パワーを取るためにR5は小さくしたいが、負荷が重すぎると発振しないのでトレードオフがある。

試作

フィルタ部のストリップ長L=6 mmと12 mmの2種類を試作した(Figure 5)。プリント基板はFusion PCBのFR4-TG130、1 mm厚、以前のブログ記事から比誘電率はεr=4.95と推定。

Figure 5 - Photographs of (a) VCO L=6 mm and (b) VCO L=12 mm

測定結果①(VCO L=6 mm)

測定環境は、2.1 GHz以下はSIGLENTスペアナで直接観測し、2.1 GHzより上はHMC213ミキサ+EVAL-ADF4351でダウンコンバートしてスペアナで観測した。EVAL-ADF4351ではHMC213の推奨LOレベルに満たないことと、HMC213の変換損を外挿して求めているので測定結果のPoutは正しくないが許してほしい。

VCO L=6 mmの発振周波数(fosc)と出力パワー(Pout)の特性をFigure 6に示す。Vctrl=2~13 Vの範囲で、発振周波数は1.6 GHz~2.7 GHzまで変化した。ただ、Vctrl=2 V以下では発振が弱く、1.6 Vを下回ると発振が止まってしまうことが分かった。Vctrlが低い領域では、バリキャップの直列抵抗成分によりQ値が劣化するためだと思う。Poutは、周波数が高いほど高出力となり、2 GHz以上では0 dBmを超えてくるので結構嬉しい。Vcrtlはバリキャップのブレークダウン電圧を超えないよう13 Vまでとした。

Figure 6 - VCO L=6 mm, fosc and Pout vs. Vctrl

PLLシンセサイザに組み込む際には、VCOの伝達関数の比例定数Kvco [Hz/V]というパラメータを用いることになる。Figure 7にKvco vs. foscの結果を示す。

Figure 7 - VCO L=6 mm, Kvco vs. fosc

測定結果②(VCO L=12 mm)

Figure 8、9にそれぞれ、VCO L=12 mmのfosc/Pout vs. Vctrl特性、Kvco vs. fosc特性の測定結果を示す。VCO L=12 mmはVctrl=0 Vから安定した発振が得られた。発振周波数は1 GHz~2.2 GHzまで変化した(実際に使うときはちょっと余裕を持たせて1.1 GHz~2.1 GHzあたりで使うことになると思う)。出力Poutは低域側はやっぱり弱く-5 dBm程度で、高域にいくほど高出力となる。

Figure 8 - VCO L=12 mm, fosc and Pout vs. Vctrl

Figure 9 - VCO L=12 mm, Kvco vs. fosc

課題(自己共振の抑制)

部品を色々付け替えたりしている中で、ある条件で異常な発振スペクトラムとなる現象を発見した。Figure 10にその時のスペクトラムを示す。パスコンC3=1 nF、インダクタL1=100 nHを使用した場合に発生し、1.7 GHz~1.8 GHzに遷移する領域で、1本だったスペクトラムが分裂してコム状に変化した。C3を47 pFに変更したり、L1に100 Ω抵抗を並列したりするとこの現象が抑えられたことから、どうやらチップコンデンサ、チップインダクタの自己共振が原因ではないかと思う。1608サイズの積セラ1 nFは300 MHz付近に自己共振(直列共振)があり、それ以上の周波数ではインダクティブとなる。また、今回使用した巻き線チップインダクタ100 nHは1.8 GHzに自己共振(並列共振)がある。

つまり、コンデンサ、インダクタの自己共振によってループゲインの位相特性にうねりが生じ、不安定な発振条件となっているのかもしれない。周波数ジャンプ(発振周波数特性が不連続で、ある周波数から別の周波数に飛び移ること)の中間の状態でこのような現象が起こるみたいな話をどこかで聞いたことがある。

Figure 10 - Spectra during sweep from fosc=1.7 GHz to 1.8 GHz

対策として、インダクタに並列に抵抗を入れることで自己共振のQ値を下げる方法が思いつく。Figure 11に改善した回路を示す。インダクタL1にR6=33 Ωを並列に追加し、さらにハイインピーダンスを保つためのインダクタL2を直列に入れる。FETから見たインピーダンスがR6によりレジスティブになるので、自己共振の影響が小さくなるのではないかと考えた。実際にこの回路にしてみて、Figure 10のようなコム状のスペクトラムがなくなることを確認した。

Figure 11 - Circuit improvement to suppress paracitic resonances

BGA616というアンプ

はじめに

今回は、秋月電子で販売されているBGA616というInfineon製のDC~2.7GHz広帯域アンプを評価してみた。

akizukidenshi.com

データシートからFeatureの部分を引用↓

  • 3 dB-bandwidth: DC-2.7 GHz with 19.0 dB typical gain at 1.0 GHz
  • Compression point P1dB=18 dBm at 2.0 GHz
  • Noise figure=2.6 dB at 2.0 GHz
  • Absolute stable
  • 70 GHz fT - Silicon Germanium technology

上からひとつひとつ確認していくと、3 dB帯域幅がDC-2.7 GHzで、1 GHzのゲインが19 dB。P1dB(1-dB compression point)とは、入力電力を上げていくとアンプの出力がサチってきて、ゲインがちょうど1 dB低下する点のこと。P1dB=18 dBmと高出力で使いやすそう。Noise Figure(NF)は付加される雑音の指標。入力雑音レベルが-174 dBm/Hz(熱雑音レベル)のとき、出力雑音レベルは-174 dBm/Hz+18 dB (Gain@2 GHz)+2.6 dB (NF@2 GHz)=-153.4 dBm/Hzという計算になる。Absolute stableは絶対安定、つまりどんなインピーダンス負荷を繋いでも発振しませんよ、ということ。最後に、fT=70 GHzのSiGeプロセスを使っているらしい。

結構良さそうなアンプだと思い、評価してみることにした。

回路

データシートのTest Circuit(下)を参考に、出力ピンからBias Teeで電源を供給する。Bias Teeはインダクタとキャパシタで作る。手持ちに100 nHのチップインダクタ(LQW18ANR10G00D, 自己共振周波数:1.8 GHz)があったのでそれを使うことにした。

下にPCBのレイアウトを載せる。基板は1 mm厚のFR4でFusion PCBに作ってもらった。一晩で適当にレイアウトしたのでSMAコネクタのピッチとかミスったりしたけど、結果的になんとかなった。

測定

測定はスペアナのトラッキングジェネレータを使用した。nanoVNA-F V2も持ってるんだけど、SOLTでキャリブレーションとか面倒くさいのでスペアナにした。バイアス電流(Id)をテスタでモニタしながら、アンプがサチらない程度に入力パワーを-20 dBmに設定して小信号利得を測った。

測定のようす↓

ゲイン vs 周波数の測定結果(0.1~2.1 GHz, Id=0~60 mAで変化)↓。Id=60 mAのとき、ゲインは18.4 dB@1 GHzとなった。Id=10 mA~60 mAの範囲で利得が大きく変わるので、バリアブルゲインアンプとしても使えるかもしれない。

1 GHz, 2 GHzにおけるゲイン vs Idの測定結果↓。

~~~

お友達のJP7VTFさんに余った基板をあげたら、実装して測ってくれた。BGA616のチップも1個分けてもらった(ありがとう~~)。JP7VTFさんはADALM-Plutoというソフトウェアラジオを使って6 GHzまで測定できる環境を持っている。下にJP7VTFさんの測定結果を載せる(許可をいただきました)。2 GHzあたりからだらだらと利得が落ちているが、5.6 GHz帯らへんでも10 dB程度のゲインがあるので、無理をすればここら辺でも使えないこともないかも。

Fusion PCBのFR-4の誘電率を測ってみた

はじめに

Fusion PCBという$4.9〜でプリント基板を注文できるサービスがある。Fusion PCBの注文画面(下)では、材質をFR-4 TG130、アルミ基板、フレキシブル基板から選択できる。「TG130」はガラス転移温度130℃という意味で、耐熱性を示している。

Fusion PCBの注文画面

今回は、Fusion PCBのFR-4基板の誘電率を知りたいので、マイクロストリップのオープンスタブの共振周波数から求めてみようと思った。正しい誘電率を知ることで、結合線路を用いたバンドパスフィルタ等の設計ができたらいいなと思う。

試作したオープンスタ基板の写真を下に示す。基板厚は1 mm、スタブ長30mmとし、SMAコネクタをつけて2ポートで測れるようにした。

試作したオープンスタブ基板

原理:
高周波分からない人向けに簡単に原理を説明すると、マイクロストリップ線路のような伝送線路を高周波信号が伝搬するのに遅延が発生する。たとえば、1 GHzの信号が長さ1波長(λ)の伝送線路を伝搬するには、1 nsの遅延時間となる。また、FR-4等の誘電体を伝送線路に使う場合、その誘電率によって波長が短縮される(光と屈折率の関係と同じ)。オープン端ではほぼ全反射するので、λ/4のオープンスタブでは行って帰ってくるのに合わせてλ/2分位相が遅れる。入力した波と、反射して帰ってきた波とが打ち消しあうことで入力端での振幅がゼロ(ロスレスな場合)になる。この共振周波数において、2ポート間の通過特性(S21)が最小となるので、共振周波数を見つけることができれば波長短縮率が分かり、FR-4の誘電率も求めることができる。

測定結果

スペアナのトラッキングジェネレータを使って通過特性を測定した。トラッキングジェネレータとは、スペアナのスイープと同調した信号出力のこと。Thruで校正した後、DUTを挿入することでスカラーネットワークアナライザとして使うことができる。

測定のようす

測定結果を下に示す。スタブの共振周波数は1.27666 GHzとなった。1.5 GHz程度を予想していたので、低めになった印象。

通過特性の測定結果

誘電率をフィッティング

openEMS(FDTD方式の電磁界シミュレータ)を使ってFR-4の誘電率をフィッティングする。openEMSの使い方については他の記事で(拙いが)説明しているので、ぜひ参考にしてほしい。下にシミュレーションモデルを示す。ポートはLumpedPortを使用。SMAコネクタ等は複雑なのでモデルに含めていない。

openEMSのモデル

openEMSのスクリプトの一部を下に示す(ソース全体は一番下に載せる)。SetMaterialProperty()関数でFR-4の比誘電率 εr を設定する。残念ながらtanδ(誘電正接、タンデル)は設定できないようなので、代わりに電気伝導率 κ [S/m]を設定している。フィッティングした結果、εr=4.95, κ=0.004 という値となった。誘電率は思ったより高めになったが、調べてみるとFR-4の誘電率は4.3~5.0とあるのでメーカによっても結構ばらつくのかもしれない。

epsilon_r = 4.95;
kappa = 0.004;

% FR4
CSX = AddMaterial(CSX, 'FR4');
CSX = SetMaterialProperty(CSX, 'FR4', 'Epsilon', epsilon_r, 'Kappa', kappa);

結果の比較(下)。ぴったり一致はしていないが、コネクタやケーブルの特性が乗ってしまっているからだろうか。VNAを使ってDUTのポート端面でキャリブレーションやディエンベッドしたら一致するかも?

測定結果とシミュレーション(εr=4.95, κ=0.004)の比較

結論

オープンスタブの試作基板を測定し、openEMSでFR-4の誘電率をフィッティングしたところ、比誘電率 εr=4.95 という結果が得られた。

ソースコード

openEMSのソースコードMatlab/GNU Octave)を下に載せる。メッシュを作成するGradedMesh()関数については openEMSのメッシュを切る関数自作した - ペEの日記を参照。

close all
clear
clc

physical_constants;
unit = 1e-3;

% Design parameters
W0 = 1.9;  % Microstrip width
L0 = 31;   % Open stub length
L1 = 16.6; % Feeding line length

% Substrate dimensions
Ws_neg =  9.2; % Length in -x direction
Ws_pos = 34.8; % Length in +x direction
Ls     = 25.0; % Length in y direction
thickness = 1;

f0 = 1250e6; % Center frequency
fc = 250e6; % 20dB cutoff frequency

epsilon_r = 4.95;
kappa = 0.004;

% Setup FDTD
FDTD = InitFDTD('EndCriteria', 1e-6, 'NrTS', 1e5);
FDTD = SetGaussExcite(FDTD, f0, fc);
BC = { 'MUR' 'MUR' 'MUR' 'MUR' 'PEC' 'MUR' };
FDTD = SetBoundaryCond(FDTD, BC);

% Setup CSX
CSX = InitCSX();

% Materials
% FR4
CSX = AddMaterial(CSX, 'FR4');
CSX = SetMaterialProperty(CSX, 'FR4', 'Epsilon', epsilon_r, 'Kappa', kappa);
% Metal (PEC)
CSX = AddMetal(CSX, 'PEC');

% Substrate
start = [-Ws_neg -Ls/2 0];
stop  = [+Ws_pos +Ls/2 -thickness];
CSX = AddBox(CSX, 'FR4', 1, start, stop);

% Open stub
start = [ 0 -W0/2 0];
stop  = [L0 +W0/2 0];
CSX = AddBox(CSX, 'PEC', 10, start, stop);

% Feeding line
start = [-W0/2 -L1/2 0];
stop  = [+W0/2 +L1/2 0];
CSX = AddBox(CSX, 'PEC', 10, start, stop);

% Lumped ports
% Port 1
start = [-W0/2 -L1/2 0];
stop  = [+W0/2 -L1/2 -thickness];
[CSX port{1}] = AddLumpedPort(CSX, 999, 1, 50, start, stop, [0 0 1], true);

% Port 2
start = [-W0/2 +L1/2 0];
stop  = [+W0/2 +L1/2 -thickness];
[CSX port{2}] = AddLumpedPort(CSX, 999, 2, 50, start, stop, [0 0 1], false);

% Mesh
mesh.x = [];
mesh.y = [];
mesh.z = linspace(-thickness, 0, 5);
mesh.z = [mesh.z 5];

mesh = DetectEdges(CSX, mesh);
mesh = GradedMesh(mesh, 1);
CSX = DefineRectGrid(CSX, unit, mesh);

Sim_Path = 'tmp';
Sim_CSX = 'tmp.xml';

[status, message, messageid] = rmdir(Sim_Path,'s');
[status, message, messageid] = mkdir(Sim_Path);

WriteOpenEMS([Sim_Path '/' Sim_CSX], FDTD, CSX);
CSXGeomPlot([Sim_Path '/' Sim_CSX]);

% return
RunOpenEMS(Sim_Path, Sim_CSX, '');

% Post processing
f = linspace(f0-fc, f0+fc, 401);
port = calcPort(port, Sim_Path, f, 'RefImpedance', 50);

S11 = port{1}.uf.ref ./ port{1}.uf.inc;
S21 = port{2}.uf.ref ./ port{1}.uf.inc;

% Plot result
figure('Position', [100 100 500 300]);
plot(f/1e9, 20*log10(abs(S11)), 'r-', 'DisplayName', 'S_{11} (Sim.)');
hold on
plot(f/1e9, 20*log10(abs(S21)), 'b-', 'DisplayName', 'S_{21} (Sim.)');
grid on
legend('Location', 'southeast');
xlabel('Frequency (GHz)');
ylabel('S Parameters (dB)');
xlim([f0-fc f0+fc]/1e9);

% Measured data
data = importdata('data.csv');
f_Meas   = data(:, 1);
S21_Meas = data(:, 2);
plot(f_Meas/1e9, S21_Meas, 'k--', 'DisplayName', 'S_{21} (Meas.)');

3000円RFミキサを評価してみた

はじめに

アマゾンで3000円のRFミキサを購入してみた↓。HMC213というHittite製のGaAsダブルバランストミキサが使われているらしい。周波数範囲はRF:1.5~4.5 GHz、IF:DC~1.5 GHz。今持っているスペアナの帯域が2.1 GHzまでなので、それより上の周波数をこれで見れるようにしたくて買った。

動作確認

とりあえず中身を確認するためにケースを開けてみた。すごいシンプルな作りで、真ん中にチップがぽつんと乗っているだけだった。PCBは50 Ω線路の幅からして、おそらく0.8 mm厚のFR-4だと思う。なぜかネジは皿ネジが使われている。

動作確認をしたいけど、まともな信号源を持っていなかったので、RFにアンテナをつけてWifiの2.4 GHzを受信して、LOにADF4351(PLL IC)の評価ボードから2.0 GHzを入力して400 MHzにダウンコンバートしたIF信号をスペアナで表示してみることにした。評価ボードの出力パワーが+5 dBmで、HMC213のデータシートに書いてあるLOレベル13 dBm(Typ.)に足りていないが、まあいいでしょう。スペアナはSIGLENTのSSA3021X、Agilentを真似てるだけあってとても使いやすい。

アンテナの近くにスマホを置いて、Wifiで通信速度テストをスタート。通信帯域がモリモリしてちょっと楽しい。というわけで、ミキサがちゃんと動作していることが確認できた。結構使えそう。

動画もとってみた↓。

直流安定化電源を自作してみた

余談-----
最近Twitterがイ一口ンマスクのせいでつまらなくなってしまった。もうあのアイコンは見たくもない。旧Twitterをやめてマストドンに逃げたが、それまでフォローしていたオタクのツイートが見れなくなってしまって悲しい。マストドンは最初何も分からずmstdn.jpに垢を作ってみたが、あそこはLTLがかなり荒れていて居心地が悪かった。misskeyも試してみたが、リアクションがわちゃわちゃしすぎていて自分には合わなかった。今はVivaldi Social(通称、ビバ丼)に落ち着いた。ビバ丼はそこそこ居心地が良い。ハッシュタグ#ビバ丼で美味しいものを投稿する謎の文化はとても良いと思った。以上、生存報告。

はじめに

直流安定化電源をつくったのでブログに残しておこうと思う。今まではその都度ACアダプタや9V電池からレギュレータで電圧を落として電源をとってきていたが、さすがに面倒くさいので汎用的に使えるそこそこまともな電源がほしいなぁと前から思っていた。買ってもいいけど、自作する方が楽しいでしょう。

最近は高周波アナログ回路を扱うことが多いので、ノイズを出さないドロッパ方式の電源とした。負電圧が必要になることも稀にあるので、正電源と負電源(0 V~±15 V)を組み込むことにした。0 Vから調整可能にした点はちょっとしたこだわり(LM317等の可変レギュレータでは実現できない)。

それと、今回は見た目にもこだわってみた。やっぱり見た目が良い方が愛着も湧くし、大事に使おうという気持ちになる。アナログ電流計・電圧計のレトロな感じが個人的に好き。

構成

Fig. 1にブロック図を載せる。まず100 VACからトランスで15 VACに落とした後、整流回路~平滑回路を通して±20 VDCにする。ツェナーダイオードにより生成した±15 VDCの基準電圧を可変抵抗で分圧し、可変電圧レギュレータ回路(オペアンプ+MOSFETで構成)でブーストして出力する。正電源・負電源それぞれに電流計を入れて出力電流を表示する。電圧計はスイッチで切り替えるようにすることで、正電源・負電源で共通とした。

Fig. 1 ブロック図

回路図

Fig. 2に整流回路の回路図を載せる。まず100 VACからトランスで15 VACに落として、ブリッジダイオードで全波整流する。15 VACは実効値なのでピーク電圧は15 V×√2≒21 Vとなり、ダイオードの順方向電圧を引いて20 Vくらいになる(実際は無負荷のときトランス出力はもう少し高い)。平滑コンデンサ(C3, C4)には6800 μFと大きい容量を用いる。電源投入時、空っぽのコンデンサを急速に充電しようとして突入電流(~10 Aくらい?)が流れてしまうのを防止するための突入電流保護回路を入れることにした。電源投入後、最初は電流制限抵抗(R3, R4=50 Ω)を通してコンデンサが充電されるため、突入電流が抑制される。電源投入から0.5~1秒くらいすると電圧が±16~17 Vに達し、フォトカプラが作動してMOSFET(Q1, Q2)がオンになり、電流制限抵抗がショートされる。LED1をパイロットランプに利用することで、電源投入してから時間差で点灯し、スタンバイのインジケータとして機能させることができる。

Fig. 2 整流回路・突入電流保護回路

Fig. 3に可変電圧レギュレータの回路図を載せる。負電源は正電源の回路をそのままひっくり返した構成(ダイオードトランジスタのNPN/PNPが逆)なので説明は割愛する。まず、ツェナーダイオードで15 Vの基準電圧を生成し、ヘリカルポテンショメータで0 V~15 Vの範囲で電圧を調整する。これをオペアンプ(TL081CP)とMOSFETで構成したゲイン1倍の非反転増幅回路でブーストして出力する。0 Vから調整できることにこだわったので、オペアンプの電源電圧は-3 V~+20 Vとした。

Fig. 3 可変電圧レギュレータ回路

実験用電源なので、出力に容量性負荷が繋がっても発振しないように、フィードバックループの安定性に注意する必要がある。今回は、R8=1 kΩとC8=1 µFを用いてフィードバックのループ帯域を落とす手法を選択した。R8とC8のカットオフ周波数はfc=1/(2π×1 kΩ×1 μF)≒159 Hzとなり、これより高い周波数領域ではC8のループが支配的になり、オペアンプの安定性はボルテージフォロアと等価と言える(つまり安定)。ただし、この領域では回路の出力がフィードバックから切り離されるので、急激な負荷変動には鈍感となる。DC~カットオフ周波数の領域では、R8のループが支配的となるため(C8はオープンに近い)、DC電圧精度を維持することができる。ソースフォロア(ドレイン接地回路)の出力インピーダンスを約1 Ω(?)と見積もると、1000 μFの容量性負荷を繋いだときゼロとポールの周波数が重なり、それ以上の容量だと安定性が失われる可能性がある。

また、誤って出力をショートしてしまったときにMOSFETを保護するため、Q4とR11=0.5 Ωで過電流保護回路を構成する。R11に1.3 A以上流れるとQ4のベース-エミッタ間電圧Vbe=0.65 Vに達してQ4がオンになり、MOSFETのゲート電圧を下げるように働くため、出力電流が抑制される。Q4がオンになると、定電流ダイオードCRD3を通って電流が供給される一方、ダイオードD4がオペアンプからの電流供給を阻止してくれるのでオペアンプも保護される。D2、D3はオペアンプの±入力端子間に過電圧が加わらないよう入れている。


全体の回路図はこちら

部品紹介

トロイダルトランス HDB-30(L) / 0-15V 1A / 0-15V 1A

トロイダルトランスはドーナツ状のコアに線を巻いた構造になっており、普通のEIコアのトランスと比べて漏れ磁束が極めて小さい。高級品で、特にトロイダルトランスである必要もなかったが、一度使ってみたかった。2次側は定格15 V, 1 Aの巻き線が2回路入っている。共立エレショップで購入。

アナログメータ(電流計・電圧計)MR-38

奥沢電気製作所のMR-38シリーズ。DC15 Vの電圧計×1個、DC1 Aの電流計×2個を使用。44 mm×44 mmの大きさがちょうど良い。共立エレショップで購入。

製作

基板作成

整流回路~平滑回路は自作のプリント基板に実装した。銅張基板の銅箔にカッターで筋を入れ、ピンセットでつまんでペリペリと剥がす方法でパターンを作成した(銅箔ペリペリ法)。銅箔厚18 µmの基板だと銅箔をピンセットで引っ張ったときに千切れてしまうが、35 µmならこの方法が使える。

銅箔ペリペリ法については下を参照。
https://x.com/neuroi_S2/status/1683079331697025024?s=20

可変電圧レギュレータ回路はユニバーサル基板に実装した。あらかじめMSペイントで配線図を描いてからはんだ付けしたのでミスなく配線することができた。

ケース加工

ケースはタカチのUC型ユニバーサルアルミサッシケース、UC26-7-20GG(260(W)×70(H)×200(D)mm)を使用した。ライトグレーの塗装仕上げとなっており高級感がある。上下カバーとフロント・リアパネルが分離できるので加工がしやすい。

Inkscapeで描いた図面を印刷した紙を貼った状態でシャーシ加工をしてみた。小さい穴はドリルであけ、大きい穴や四角い穴はリーマーやハンドニブラを使って0.5 mmくらい残して広げた後、棒やすりで整えた。

文字入れは、マットフォトペーパーという上質な紙にインクジェットプリンタで印刷し、切り抜いて糊付けしてみた。結構おしゃれな感じに仕上がったと思う。

組み立て

内部の配線。

写真左下、ケースの塗装を剥がしてアルミを露出させ、一点アースとしている。

完成

完成~~

フロントパネル↓。左から、パイロットランプ、電源スイッチ、電流計×2、電圧計、出力ON/OFFスイッチ、電圧計切替スイッチ、出力端子(-/GND/+)、電圧調整つまみ。出力のターミナル端子は29 mmピッチとすることで、BNC-バナナ変換アダプタが刺さる設計にしてある。

リアパネル↓。後ろにはACインレットとヒューズを取り付けた。また、なんとなく、整流回路後の+20 Vを取り出せるようにしておいた。

評価

だいたい問題なく動作することを確認した。下の写真は電圧調整つまみをMAXまで回して出力電圧をテスターで測ったところ。ちゃんと15 Vが出力できている。

負荷変動時のリップル測定みたいなことも試してみた。下の写真は、10 Ω, 10 W(実際には1 Ω, 1 W抵抗×10個直列)の負荷抵抗をパワーMOSFETでオンオフさせたときの5 V出力波形をオシロスコープで観測しているようす。(このためにハンドヘルドオシロスコープHDS272Sをポチってしまったが、買って良かったと思う。)

5 V出力波形↓。リップル電圧は0.5 Vpkくらいあり、2 ms程度で目標値に収束している感じ。前にも述べたが、急激な負荷変動に対してはループ帯域外なので、出力段MOSFETのソースフォロアの出力インピーダンスが見えているイメージで、まあそんなもんかなあという印象(ざっくり)。収束の早さに関しても、設計したループ帯域的に妥当な値だと思う。

次に、100 μFの電解コンデンサを並列に追加した場合の波形↓。パスコンを追加したことにより、リップル電圧が~0.35 Vpk程度まで緩和されることが確認できた。

NE76084(GaAs MESFET)の小信号モデルパラメータの抽出

はじめに

以前、秋月電子で200円で売られている高周波用のFET、NE76084(GaAs MESFET)をなんとなく40個購入した。18 GHzとかまでゲインが伸びていて、前からこれ使ってみたいなって思っていた。MESFET(metal-semiconductor field effect transistor)ってあまりなじみがないけど、ゲートをショットキー接合にしたFETで、動作的にはpn接合のJFETと同じなので使う分には難しくないと思う。データシートから、Sパラメータを取得できるので、今回は解析用に小信号モデルのパラメータ抽出をしてみた。

秋月電子のページ(NE76084)↓ akizukidenshi.com

チップの写真。マイクロXというパッケージで高周波用のトランジスタやアンプでたまに見かける。4本足だけど、そのうち2本はソース端子(写真では上下の2本)。

NE76084のチップ

小信号モデル

FETの小信号モデルは下のを使うことにした。名前が「L~」と「Cp~」のパラメータは、パッケージの寄生成分(ボンディングワイヤとかそういうやつ)。真ん中のSRC1は電圧依存の電流ソース(voltage-controlled current source)で、gmは相互コンダクタンス、tauは遅延時間。データシートのSパラはS2Pファイルに書き直して、Qucsに読み込ませた。6~18 GHzでは上手くフィッティングできなかったので、6 GHz以下でパラメータを合わせ込んだ。

FETの小信号モデル(P3:ゲート、P4:ドレイン、GND:ソース)

データシートのSパラ(P1:ゲート、P2:ドレイン、GND:ソース)

以下、シミュレーション結果とモデルパラメータ(一番下の表)を載せておく。結構あってると思う。

S11(左)とS22(右)スミスチャート(赤:小信号モデル、青:データシート)

S21(上)Mag/PhaseとS12(下)(赤:小信号モデル、青:データシート)

パラメータ 単位
Rg 2.06 Ω
Rd 33.0 Ω
Rs 4.08 Ω
Rgs 0.489 Ω
Rds 151 Ω
Rgd 829 Ω
Cgs 282 fF
Cgd 15.1 fF
Lg 183 pH
Ld 450 pH
Ls 77.9 pH
Cpg 143 fF
Cpd 263 fF
Cpgd 27.8 fF
Lpg 215 pH
Lpd 543 pH
gm 52.2 mS
tau 3.65 ps

openEMSのメッシュを切る関数自作した

はじめに

openEMSはフリーでオープンソースのFDTD(有限差分時間領域法)の電磁界解析ソフトで、僕は結構気に入って使っているのだが、日本ではあまり流行っていない。もっと広まってもいいと思うんだけどなあ。

openEMSは、MatlabまたはGNU Octaveで3Dモデルを作成する。他の有料の電磁界解析ソフト(HFSSとかCOMSOLとか)と違って、メッシュも自分で切らなければいけないところが難しい。一応、メッシュをいい感じに切ってくれるSmoothMesh関数などが用意されているが、これがなかなか使いにくい。処理が早く終わる時もあれば条件によっては延々と終わらない時もあって、結構癖のある関数だ。

そこで、簡単にopenEMSのメッシュを分割する関数を自作してみた。ソースコードは一番下に載せる。

メッシュ分割の考え方

おおざっぱなイメージを持ってもらうために下の例を見てほしい。

メッシュ分割の例

FR4の基板上にPEC(perfect electric conductor)で作ったマイクロストリップ線路と中央にDUTがあるモデル。メタルのエッジには電界が集中しやすいのでメッシュは細かく切りたい。一方で、オブジェクトから離れた電界が弱い部分はメッシュは粗くても問題ない。エッジ付近は細かくして、徐々に間隔を広げていくようなメッシュの切り方が望ましい。全部細かく分割してしまうのは、無駄に計算時間が長くなってしまい効率的でない。

上のようなメッシュ分割法をもう少し具体的に表すと、

  • オブジェクトのエッジ周辺は最小メッシュ分解能(min_res)で分割する
  • 一定の比率(ratio)で徐々にメッシュの間隔を大きくする
  • 最大メッシュ分解能(max_res)に達したら、等間隔に分割する

ここで、以下のパラメータを定義しておく。max_res:最大のメッシュ分解能。min_res:最小のメッシュ分解能。ratio:隣り合うメッシュの比の上限値。

目安として、max_resは波長λの1/30、min_resはmax_res/5、ratioは1.3くらいに設定するとよいと思う。


では、実際にx1からx2の区間(x2>x1)を上のルールに従って分割する方法を考えてみよう。ここでは、x=x1にオブジェクトのエッジがあると仮定して、x=x1近傍は細かく、x=x2に向かうほど間隔が広がっていくようにしたい。

といっても、僕は数学的な難しいことは苦手なので、小学生でも思いつきそうな方法でやってみる。まず、長さが (x2-x1) のテープを用意する。

テープの左端からmin_resの長さ分だけハサミで切り取る。

ratioの比率で徐々に切る長さを増やしていく。長さがmax_resに達したら、あとはmax_resで等間隔に切っていく。

最後に切れ端(あまり)が残る。切れ端の長さで場合分けする。

i) 切れ端の長さ ≥ min_res のとき
これは簡単。小さい順に並び替えるだけ(ソート)。並び替えた後の切れ端と隣接するメッシュとの比は必ずratio以下になるのでOK。

ii) 切れ端の長さ < min_res のとき
ii-a) 右二つの長さの合計 ≥ 2×min_res のとき
切れ端と右から2番目(つまり一番長いやつ)を一旦くっつけて、切れ端がmin_resになるように再分配する。あとはソートすればOK。

ii-b) 右二つの長さの合計 < 2×min_res のとき
この場合分けは、分割数が少ないときに発生する。この場合、切れ端をゴミ箱にぽいして、残りのテープの長さの合計が (x2-x1) になるようにスケーリングする。

以上のアルゴリズムでメッシュ分割できるようになった。あとは実装するだけ。

実装・関数の使い方

Matlab/GNU Octaveの関数として実装した。ソースコードは一番下に載せた。ここでは、関数の使い方を説明する。

GradedMeshLines()

GradedMeshLines()は1次元のメッシュ分割をする関数。

function lines = GradedMeshLines(lines, max_res, min_res, ratio)

引数に、もととなるグリッド(両端の座標、オブジェクトのエッジの座標の配列)と、max_res、min_res、ratioを渡す。min_resとratioはオプションでそれぞれmax_res/5、1.3をデフォルト値としている。

使い方の例↓(そのまま実行可能)

lines = [-10 0 10]; % もととなるグリッド
lines = GradedMeshLines(lines, 1); % メッシュ分割

% プロット
figure('Position', [100 100 600 100]);
for x = lines
    plot([x x], [0 1], 'k-');
    hold on;
end

これの実行結果が下。

GradedMeshLines()の使い方

多くの場合、シミュレーションモデルの両端は吸収境界に割り当てるので、両端はグレーディングせず、内側のラインをオブジェクトのエッジとみなしてメッシュ分割するようにしてある。

GradedMesh()

GradedMesh()は3次元のメッシュ分割をする関数。

function mesh = GradedMesh(mesh, max_res, min_res, ratio)

openEMSのMatlab/Octave関数の中にDetectEdges()という便利な関数があるので、最初にDetectEdges()でCSXのオブジェクトのエッジを検出してから、GradedMesh()を適用すれば簡単にメッシュが作成される。

使い方の例↓(openEMSのCSXオブジェクト作成後)

resolution = 1; % mm
mesh = DetectEdges(CSX); % CSXオブジェクトのエッジを検出
mesh = GradedMesh(mesh, resolution); % メッシュを分割
CSX = DefineRectGrid(CSX, unit, mesh); % 直交座標系のグリッドを設定

ソースコード

ファイル名:GradedMeshLines.m

function lines = GradedMeshLines(lines, max_res, min_res, ratio)
% function lines = GradedMeshLines(lines, max_res, min_res, ratio)
%
% input parameters:
%   lines                   lines to create a graded mesh in between.
%   max_res                 maximum resolution.
%   min_res (optional)      minimum resolution. default is max_res/5.
%   ratio (optional)        ratio of adjacent grids. default is 1.3.

    if ~exist('min_res', 'var')
        min_res = max_res/5;
    end
    if ~exist('ratio', 'var')
        ratio = 1.3;
    end

    lines = uniquetol(lines);

    if length(lines) < 3
        n = 1+floor(abs(lines(end)-lines(1)));
        lines = linspace(lines(1), lines(end), n);
    else
        lines_copy = lines;
        lines = [lines singleGradedMesh(lines_copy(2), lines_copy(1), max_res, min_res, ratio)];
        lines = [lines singleGradedMesh(lines_copy(end-1), lines_copy(end), max_res, min_res, ratio)];
        for n = 2:length(lines_copy)-2
            lines = [lines doubleGradedMesh(lines_copy(n), lines_copy(n+1), max_res, min_res, ratio)];
        end
        lines = sort(lines);
    end

end

function lines = singleGradedMesh(x1, x2, max_res, min_res, ratio)
    delta_total = abs(x1-x2);
    delta = [min_res];

    while sum(delta) < delta_total
        delta = [delta min(ratio*delta(end), max_res)];
    end
    delta(end) = delta_total-sum(delta(1:end-1));

    if delta(end) < min_res && length(delta) > 1
        if sum(delta(end-1:end)) > 2*min_res
            delta(end-1) = sum(delta(end-1:end))-min_res;
            delta(end) = min_res;
        else
            scaling = delta_total/sum(delta(1:end-1));
            delta = scaling*delta(1:end-1);
        end
    end

    delta = sort(delta);
    lines = [];
    for n = 1:length(delta)-1
        lines = [lines x1+sign(x2-x1)*sum(delta(1:n))];
    end
end

function lines = doubleGradedMesh(x1, x2, max_res, min_res, ratio)
    delta_total = abs(x1-x2);
    delta = [min_res];

    while sum(delta) < delta_total
        if mod(length(delta), 2) == 0
            delta = [delta min(ratio*delta(end), max_res)];
        else
            delta = [delta delta(end)];
        end
    end
    delta(end) = delta_total-sum(delta(1:end-1));
    
    if delta(end) < min_res && length(delta) > 1
        if sum(delta(end-1:end)) > 2*min_res
            delta(end-1) = sum(delta(end-1:end))-min_res;
            delta(end) = min_res;
        else
            scaling = delta_total/sum(delta(1:end-1));
            delta = scaling*delta(1:end-1);
        end
    end

    delta = sort(delta);
    delta = [delta(1:2:end) flip(delta(2:2:end))];

    lines = [];
    for n = 1:length(delta)-1
        lines = [lines x1+sign(x2-x1)*sum(delta(1:n))];
    end
end


ファイル名:GradedMesh.m

function mesh = GradedMesh(mesh, max_res, min_res, ratio)
    if ~exist('min_res', 'var')
        min_res = max_res/5;
    end
    if ~exist('ratio', 'var')
        ratio = 1.3;
    end
    
    mesh.x = GradedMeshLines(mesh.x, max_res, min_res, ratio);
    mesh.y = GradedMeshLines(mesh.y, max_res, min_res, ratio);
    mesh.z = GradedMeshLines(mesh.z, max_res, min_res, ratio);

end