Magnitude and Phase measurement, Part II
This is one of the first working plots of the magnitude and phase response
of a 2.5 to 4.2Mhz filter over a wide frequency range:
Red is the amplitude response, and green the phase response. +10 is "in phase"
or 0 degree, and -10 is π (180deg) out of phase. Since the phase
meter is measuring the cosine of an angle, the sign of the phase is ambiguous.
That is, cos(th) = cos(-th). To resolve this, we introduce a π/2 (90deg)
phase advance in the reference signal (equivilent to a π/2 delay in the
measured signal). If the sign is + and remains + after advancing the reference
signal, the difference phase angle is in the 1st (I) quadrant, or 0 to π/2.
This is equivilent to delaying the measured signal, or rotating it clockwise, by 90 deg.
If the sign is - and remains - it is in the 3rd (III) quadrant or -&pi/2 to -π.
If the sign is + and changes to - it is in the 4th (IV) quadrant, 0 to -π/2,
and if it is - and changes to + it is in the 2nd (II) quadrant, or π/2 to π.
In the plot above the phase starts out at 1.5Mhz with about 90 degrees out of
phase and shifts with rising frequency toward 0 degrees or in phase at about
2.7Mhz. At that point the sign of the shifted-reference phase measurement
(blue) changes so the phase has moved clockwise around from the 1st to the
4th quadrant, continuing on untill the phase is -180 degrees at about 4.2Mhz
and then on around clockwise into the 2nd quadrant trending back to 90 degrees.
This is the spice plot:
The real filter in the top plot has the passband about 300khz too low (due to
real component values I guess) but the important thing here is the relationship
of the phase to the amplitude response. And for some reason the spice plot
is just the opposite, with π phase shift at 3.2Mhz and 0 at 4.5Mhz.
Shortly I hope to have a test jig and software to measure both reflected
and transmitted response of two port networks, or just reflected resonse
of single port networks (like an antenna). Measuring reflected & transmitted
signal will require two basic input boards for 3 inputs including the reference
signal from the splitter.
This is the test jig:
The code so far:
f_sweep_2.py
(uses some custom blocks for measuring signal levels in python)
Nov 10, 2005: Fixed a bug where I had magnitude squared instead of magnitude:
io_ratio = 10 * math.sqrt((out_level / in_level)) # scaled to match phase plot
since the output of gr.signal_level_cc() is the square of the peak signal value.
The code uses a sampling rate of 1Mhz for the transmit and 2 receiver channels.
That limits the sweep width to a max of -500 to 500Khz, realistically -275 to
275Khz. I chose 11 samples 50Khz apart over a -275 to 275Khz range so that
they will straddle the 0Hz center, there will be a sample at -25Khz, then the
next at 25Khz, staying comfortably out of the range where the phase meter
cannot filter out the 2X frequency. After sweeping 550Khz like that, the code
must stop the timer, stop the signal generator graph and delete it, stop the
receiver graph, stop the DDC's, change the receiver DDC center
frequency, rebuild the generator at a new DUC freq, start the generator, start
the receiver, and restart the timer. There are a few time delays to allow for
settling. It gets 1 data point every 750mSec, with a longer delay when changing
DUC/DDC frequency.
This is a polar plot of the above data:
I have NO idea what, if anything, it means but thought it looked pretty
and serves as a test of getting data into normalized rectangular form
with a Smith Chart background. More about that coming soon.
The left, lower freq hump in the earlier plot corresponds to the right
lobe of this one. The pattern is the same - at low f the phase is near +90,
rotates around to 0 deg in phase near the top of the first hump, then
swings around down clockwise to near -90 in the middle between the humps
then around clockwise to near -180 after the higher freq hump and then
back towards +90 while decreasing in magnitude. That is, from low to
high freq the points go clockwise around the curve.
The Smith Chart for GNUPlot, modified thus:
set size square
set time
set clip
set xtics axis nomirror
set ytics axis nomirror
unset grid
unset polar
set title "Primitive Smith Chart"
unset key
set xlabel "Impedance or Admittance Coordinates"
set para
set rrange [-0 : 10]
set trange [-pi : pi]
set xrange [-1:1]
set yrange [-1:1]
tv(t,r) = sin(t)/(1+r)
tu(t,r) = (cos(t) +r)/(1+r)
cu(t,x) = 1 + cos(t)/x
cv(t,x) = (1+ sin(t))/x
plot cu(t,.1),cv(t,.1),cu(t,.1),-cv(t,.1),\
cu(t,1),cv(t,1),cu(t,1),-cv(t,1),\
cu(t,10),cv(t,10),cu(t,10),-cv(t,10),\
tu(t,.1),tv(t,.1),\
tu(t,.5),tv(t,.5),\
tu(t,1),tv(t,1),\
tu(t,5),tv(t,5),\
tu(t,10),tv(t,10),\
cu(t,.5),cv(t,.5),cu(t,.5),-cv(t,.5),\
tu(t,0),tv(t,0), "YOUR_DATA_HERE"
pause -1
where YOUR_DATA_HERE is a text file in your current directory with two
column XY data in the range -1 to 1.
Modification to the report writing code to make polar plots:
if self.rpt_open == True:
# self.rpt.write(str(freq)+" "+str(io_ratio)+" "+str(phase)+" "+str(sphase)+"\n")
# output for smith chart. Convert magnitude and angle into rect
# coords -1 to 1
if ((phase > 0) & (sphase > 0)) | ((phase < 0) & (sphase > 0)) : # 1st or 2nd quad
ang = math.acos(phase/10)
if ((phase > 0) & (sphase < 0)) | ((phase < 0) & (sphase < 0)) : # 4th or 3rd quad
ang = -math.acos(phase/10)
x_pos = math.cos(ang) * io_ratio/10
y_pos = math.sin(ang) * io_ratio/10
self.rpt.write(str(x_pos)+" "+str(y_pos)+"\n")