File: Patch_Antenna_Phased_Array.m

package info (click to toggle)
openems 0.0.35%2Bgit20190103.6a75e98%2Bdfsg.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 8,424 kB
  • sloc: cpp: 40,407; python: 2,028; yacc: 580; makefile: 458; lex: 350; sh: 176; ruby: 19
file content (166 lines) | stat: -rw-r--r-- 5,451 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
%
% Tutorials / Patch Antenna Phased Array
%
% Describtion at:
%
% Tested with
%  - Matlab 2011a
%  - Octave 4.0
%  - openEMS v0.0.33
%
% References:
% [1] Y. Yusuf and X. Gong, “A low-cost patch antenna phased array with
%   analog beam steering using mutual coupling and reactive loading,” IEEE
%   Antennas Wireless Propag. Lett., vol. 7, pp. 81–84, 2008.
% [2] S. Otto, S. Held, A. Rennings, and K. Solbach,
%   "Array and multiport antenna farfield simulation using
%   EMPIRE, MATLAB and ADS," 39th European Microwave Conf. (EuMC 2009),
%   Sept. 29 – Oct. 1, Rome, Italy, pp. 1547-1550, 2009.
% [3] K. Karlsson, J. Carlsson, I. Belov, G. Nilsson, and P.-S. Kildal,
%   “Optimization of antenna diversity gain by combining full-wave and
%   circuit simulations,” in Proc. Second European Conference on Antennas
%   and Propagation EuCAP 2007, 11–16 Nov. 2007, pp. 1–5.
%
% (C) 2013-2015 Thorsten Liebig <thorsten.liebig@gmx.de>


close all
clear
clc

% we need the "Cuircuit Toolbox"
addpath('C:\CTB');
% get the latest version from:
% using git: https://github.com/thliebig/CTB
% or zip: https://github.com/thliebig/CTB/archive/master.zip

% set this to 0 to NOT run a reference simulation with the given C2 and C3
% for comparison
do_reference_simulation = 1;

% set to 1 if you want to run AppCSXCAD to see the simulated structure
show_structure = 1;

% set this to 1, to force openEMS to run again even if the data already exist
force_rerun = 0;

% frequency range of interest
f = linspace( 1e9, 5e9, 1601 );

% resonant frequency for far-field calculations
f0 = 3e9;

% capacities for port 2 and 3 to shift the far-field pattern
C2 = 0.2e-12;
C3 = 0.2e-12;

Sim_Path_Root = ['tmp_' mfilename];

%% calculate the full S-parameter set for all 3 patch antennas running 3
% individual openEMS simulations in which one antenna is active and the
% other two a passive (50 Ohm load) respectively
xpos = [0 -41 41]; % x-center position of the 3 antennas
caps = [0 0 0];
resist = [50 50 50];

spara = [];
color_code = {'k-','r--','m-.'};

for n=1:3
    active = [0 0 0];
    active(n) = 1; % activate antenna n
    Sim_Path = [Sim_Path_Root '_' num2str(n)]; % create an individual path
    [port{n} nf2ff{n}] = Patch_Antenna_Array(Sim_Path, ((exist(Sim_Path,'dir')>0) && (force_rerun==0)), show_structure, xpos, caps, resist, active);
    port{n} = calcPort( port{n}, Sim_Path, f, 'RefImpedance', 50);
    nf2ff{n} = CalcNF2FF(nf2ff{n}, Sim_Path, f0, [-180:2:180]*pi/180, 0);

    figure
    hold on
    grid on
    for p=1:3
        I(p,n) = interp1(f, port{n}{p}.if.tot,f0);
        P_in(p) = 0.5*interp1(f, port{n}{n}.uf.inc,f0)*conj(interp1(f, port{n}{n}.if.inc,f0));
        spara(p,n,:) = port{n}{p}.uf.ref./ port{n}{n}.uf.inc;
        plot(f, squeeze(20*log10(abs(spara(p,n,:)))),color_code{p},'Linewidth',2);
    end
end

%% export sparameter to touchstone file
write_touchstone('s',f,spara,[Sim_Path_Root '.s3p']);

% instructions for Qucs:
% load the written touchstone file
% attach C2 and C3 to port 2 and 3
% attach a signal port to port 1
% probe the currents going into port 1 to 3

% example currents for ports 1 to 3 for C2 = 0.2pF and C3=0.2pF
I_qucs(1,1) = 0.00398-0.000465j;
I_qucs(2,1) = 2.92e-5-0.000914j;
I_qucs(3,1) = 2.92e-5-0.000914j;

disp(['I2/I1: Qucs: ' num2str(I_qucs(2)/I_qucs(1)) ' (defined manually)'])
disp(['I3/I1: Qucs: ' num2str(I_qucs(3)/I_qucs(1)) ' (defined manually)'])

%% Calculate the currents of port 1 to 3 using Matlab [1]
z = s2z(spara);

Z2 = 1/(1j*2*pi*f0*C2);
Z3 = 1/(1j*2*pi*f0*C3);

z23(1,1) = interp1(f,squeeze(z(2,2,:)),f0) + Z2;
z23(1,2) = interp1(f,squeeze(z(2,3,:)),f0);
z23(2,1) = interp1(f,squeeze(z(3,2,:)),f0);
z23(2,2) = interp1(f,squeeze(z(3,3,:)),f0) + Z3;

%set input/feeding current of port 1 to 1mA
I_out(1,1) = 1e-3;
% calc current for port 2 and 3
I_out([2 3],1) = z23\[-interp1(f,squeeze(z(2,1,:)),f0);-interp1(f,squeeze(z(3,1,:)),f0)]*I_out(1);

disp(['I2/I1: Matlab: ' num2str(I_out(2)/I_out(1))])
disp(['I3/I1: Matlab: ' num2str(I_out(3)/I_out(1))])


%% do a referenc simulation for the given C2/C3 values
if (do_reference_simulation)
    active = [1 0 0];
    caps = [0 C2 C3];
    resist = [50 inf inf];
    Sim_Path = [Sim_Path_Root '_C2=' num2str(C2*1e12) '_C3=' num2str(C3*1e12)];
    [port_ref nf2ff_ref] = Patch_Antenna_Array(Sim_Path, ((exist(Sim_Path,'dir')>0) && (force_rerun==0)), show_structure, xpos, caps, resist, active);
    port_ref = calcPort( port_ref, Sim_Path, f, 'RefImpedance', 50);
    nf2ff_ref = CalcNF2FF(nf2ff_ref, Sim_Path, f0, [-180:2:180]*pi/180, 0);

    % extract currents from referenc simulation
    for p=1:3
        I_ref(p,1) = interp1(f, port_ref{p}.if.tot,f0);
    end

    disp(['I2/I1: openEMS: ' num2str(I_ref(2)/I_ref(1))])
    disp(['I3/I1: openEMS: ' num2str(I_ref(3)/I_ref(1))])
end

%% calculate and apply weighting cooefficients [3]
% calculate
coeff = I\I_out;

% apply
E_ff_phi = 0*nf2ff{1}.E_phi{1};
E_ff_theta = 0*nf2ff{1}.E_phi{1};
for n=1:3
    E_ff_phi = E_ff_phi + coeff(n)*nf2ff{n}.E_phi{1};
    E_ff_theta = E_ff_theta + coeff(n)*nf2ff{n}.E_theta{1};
end

%% plot far-field patterns
figure
polar([-180:2:180]'*pi/180,abs(E_ff_phi(:))/max(abs(E_ff_phi(:))));
hold on
if (do_reference_simulation)
    polar([-180:2:180]'*pi/180,abs(nf2ff_ref.E_norm{1}(:,1))/max(abs(nf2ff_ref.E_norm{1}(:,1))),'r--');
end
title('normalized far-field pattern','Interpreter', 'none')
legend('calculated','reference')