import numpy as np
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
import tabulate
from ipywidgets import HTML
plt.style.use('ggplot')
x_size = 4
fig, ax = plt.subplots(figsize=((x_size + 1) * 2, 4))
ax.set_title("SWR along a (lossless) line")
ax.text(x_size + .05, -37, "https://0x9900.com/", color='gray', rotation=90)
ax.set_xlim(0, x_size)
ax.set_ylim(-40, 40)
l1, = ax.plot([], [], lw=2, color='g')
l2, = ax.plot([], [], lw=2, color='r')
l3, = ax.plot([], [], linestyle='dashed', lw=1, color='b')
ax.hlines(20, 0, x_size, color='k', linestyle=":")
ax.hlines(10, 0, x_size, color='k', linestyle=":")
ax.hlines(0, 0, x_size, color='gray', linestyle=":")
ax.text(4.02, 21, 'V-fwd', style='italic')
ax.text(4.02, 11, 'V-rev', style='italic')
def init():
l1.set_data([], [])
l2.set_data([], [])
l3.set_data([], [])
return l1, l2, l3
def animate(i):
x = np.linspace(0, x_size, 200)
y = np.sin(1.5 * np.pi * (x - 0.02 * i)) * 20
z = np.sin(1.5 * np.pi * (x + 0.02 * i)) * 10
l1.set_data(x, y)
l2.set_data(x, z)
l3.set_data(x, y+z)
return l1, l2, l3
anim = FuncAnimation(fig, animate, init_func=init, frames=200, interval=40, blit=True)
file_name = 'vswr_wave_0.html'
with open(file_name, "w") as fdout:
print(anim.to_html5_video(), file=fdout)
SWR along the line animation: vswr_wave_0.html
Mathematically we calculate SWR by determining the reflection coeficient gamma ($\Gamma$) which is a function of the load impedance ($Z_L$) and the source impedance ($Z_0$). These 2 impedances are complex number.
$$ \Gamma = \frac{Z_L - Z_0}{Z_L + Z_0} $$or
$$ \Gamma = \frac{V_{rev}}{V_{fwd}} $$or
$$ \Gamma = \frac{VSWR+1}{VSWR-1} $$VSWR is them calculated using $\Gamma$ in the following equation:
$$ VSWR = \frac{1+|\Gamma|}{1-|\Gamma|} $$In our example above we have the forward voltage is 20V, and the reverse voltage is 15V:
$$ \begin{align} \Gamma &= \frac{10}{20} && = 0.5 \\ \nonumber VSWR &= \frac{1+0.5}{1-0.5} && = 3 \end{align} $$It is them possible to calculate the Return loss ($R_L$) using the equation: $$ R_L = 20 \log_{10}{\left(\frac{VSWR+1}{VSWR-1}\right)} $$
We can calculate the SWR from the Return Loss: $$ VSWR = \frac{10^{\frac{RL}{20}}+1}{10^{\frac{RL}{20}}-1} $$
The following equation is especially useful when using a directional power meter. It allows you to calculate the VSWR from the forward and reverse power.
$$ VSWR = \frac{1+\sqrt{\frac{P_{ref}}{P_{fwd}}}}{1-\sqrt{\frac{P_{ref}}{P_{fwd}}}} $$from itertools import chain
x = []
y = []
swr_values = chain(range(1, 10), range(10, 20, 2), range(20, 55, 5))
table = [('vswr', '% Reflected PWR')]
for vswr in swr_values:
rp = 100 * ((vswr-1)/(vswr+1))**2
table.append((vswr, rp))
x.append(rp)
y.append(vswr)
print("Reflected power doesn't necessarily mean the power lost")
print(tabulate.tabulate(table, headers='firstrow', numalign="decimal", tablefmt="github",
floatfmt=("2.1f", "6.2f")))
fig, ax = plt.subplots(figsize=(14, 6))
ax.set_title("VSWR and Reflected Power")
ax.text(max(*y) + .2, 3, "https://0x9900.com/", color='gray', rotation=90)
ax.set_xlabel("VSWR")
ax.set_ylabel("% Refected Power")
ax.set_ylim(0, 100)
ax.set_xlim(1, max(*y))
ax.plot(y, x)
plt.savefig('vswr.svg')
x = []
y = []
table = [('RL (dB)', "VSWR")]
rl_values = chain(range(1, 11, 1), range(11, 30, 3), range(30, 49, 6))
for rl in rl_values:
expo = 10**(rl/20)
vswr = (expo+1)/(expo-1)
table.append((rl, vswr))
x.append(rl)
y.append(vswr)
print(tabulate.tabulate(table, headers='firstrow', numalign="decimal", tablefmt="github",
floatfmt=("%d", "2.3f")))
fig, ax = plt.subplots(figsize=(14, 6))
ax.set_title("Return Loss / VSWR")
ax.text(10.1, 1, "https://0x9900.com/", color='gray', rotation=90)
ax.set_xlabel("VSWR")
ax.set_ylabel("Return Loss (dB)")
ax.set_ylim(0, 40)
ax.set_xlim(1, 10)
ax.plot(y, x)
plt.savefig('vswr.svg')
or
$$ \begin{align} Q &= \frac{2{\pi}fL}{R}\\ \nonumber &= \frac{2{\pi} \times 14.15 \times {10^6} \times 220 \times {10^{-9}}}{.05} \\ \nonumber &= 391 \end{align} $$To determine the target length of the antenna elements, the relationship in Eq. (4) was used: $$ L_{target} = L_{measured} \times \frac{f_{measured}}{f_{target}} $$
import math
imp = 50
results = [[' ', 'dBm', 'Watt', 'Volt (PP)', 'Volt (RMS)', 'Amp']]
for dbm in (float(d) for d in range(64, -21, -1)):
watt = 0.001 * 10**(dbm/10)
volt = math.sqrt(imp*(10**(dbm/10)/1000))
volt_pp = 2 * volt * math.sqrt(2)
current = volt / imp
marker = '->' if dbm % 10 == 0 else ' '
results.append((marker, dbm, watt, volt_pp, volt, current))
table = tabulate.tabulate(results, headers='firstrow', tablefmt="github",
floatfmt=("s", "3.0f", "3.3f", "3.3f", "3.3f", "3.4f"))
print(' ' + '-' * 23 + f' On a {imp}Ω load ' + '-' * 24)
print(table)