Note
Go to the end to download the full example code or to run this example in your browser via JupyterLite.
Lodge’s syntonic tuning: series resonance (1897)#
Early spark transmitters splattered energy over a wide band, so every
receiver heard every transmitter. Oliver Lodge’s 1897 patent on “syntonic”
telegraphy put an inductance in series with the antenna’s capacitance at
both ends, tuning transmitter and receiver to the same frequency
\(f_0 = 1/2\pi\sqrt{LC}\)
(resonance_frequency()). At
resonance the inductive and capacitive reactances cancel and the current
is limited only by the resistance; the sharpness of the peak is the quality
factor \(Q = \sqrt{L/C}/R\), and the half-power bandwidth is
\(f_0/Q\). Marconi bought the patent in 1912. This example measures the
bandwidth of a tuned circuit
(SeriesRLC) and shows how
much tuning rejects a neighbouring station.
import matplotlib.pyplot as plt
import numpy as np
from engineeringkit.electrical_engineering import SeriesRLC, resonance_frequency
A tuned receiver#
L, C = 250e-6, 1e-9
f0 = resonance_frequency(L, C)
print(f"f0 = {f0 / 1e3:.1f} kHz")
f = np.linspace(0.7 * f0, 1.3 * f0, 200_001)
fig, ax = plt.subplots()
for R in (5.0, 20.0, 50.0):
circuit = SeriesRLC(R, L, C)
gain = np.abs(1 / circuit.impedance(2 * np.pi * f)) * R # current relative to its peak
band = f[gain >= 1 / np.sqrt(2)]
width = band[-1] - band[0]
Q = circuit.quality_factor
print(f"R = {R:4.0f} ohm: Q = {Q:6.1f}, half-power bandwidth {width:7.0f} Hz, f0/Q = {f0 / Q:7.0f} Hz")
assert np.isclose(width, f0 / Q, rtol=1e-3)
ax.plot(f / 1e3, gain, label=f"Q = {Q:.0f}")

f0 = 318.3 kHz
R = 5 ohm: Q = 100.0, half-power bandwidth 3182 Hz, f0/Q = 3183 Hz
R = 20 ohm: Q = 25.0, half-power bandwidth 12732 Hz, f0/Q = 12732 Hz
R = 50 ohm: Q = 10.0, half-power bandwidth 31831 Hz, f0/Q = 31831 Hz
Rejecting a neighbour#
A second station 10% higher in frequency is attenuated by the high-\(Q\) circuit far more than by the low-\(Q\) one.
neighbour = 1.1 * f0
rejection = [abs(SeriesRLC(R, L, C).impedance(2 * np.pi * neighbour)) / R for R in (5.0, 50.0)]
print(f"neighbour 10% away is {rejection[0]:.1f}x weaker at Q=100, {rejection[1]:.2f}x at Q=10")
detuning = neighbour / f0 - f0 / neighbour
assert np.allclose(rejection, [np.sqrt(1 + (q * detuning) ** 2) for q in (100, 10)])
ax.axvline(neighbour / 1e3, color="gray", ls=":", label="neighbouring station")
ax.set(xlabel="frequency [kHz]", ylabel="relative current", title="Series resonance")
ax.legend()
plt.show()
neighbour 10% away is 19.1x weaker at Q=100, 2.16x at Q=10
Total running time of the script: (0 minutes 0.036 seconds)