はじめに
Fusion PCBという$4.9〜でプリント基板を注文できるサービスがある。Fusion PCBの注文画面(下)では、材質をFR-4 TG130、アルミ基板、フレキシブル基板から選択できる。「TG130」はガラス転移温度130℃という意味で、耐熱性を示している。
今回は、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のスクリプトの一部を下に示す(ソース全体は一番下に載せる)。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のポート端面でキャリブレーションやディエンベッドしたら一致するかも?
結論
オープンスタブの試作基板を測定し、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.)');