AM Modulation¶
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 1, 1000)
fm = 2;
fc = 20;
message = 1 + 0.5*np.sin(2*np.pi*fm*t) # slow signal
carrier = np.sin(2*np.pi*fc*t) # fast signal
y = message * carrier
#noise = 0.2*np.random.randn(len(t));
#y = message * carrier + noise # uncomment to see response with noise
plt.plot(t, y)
plt.title("Measured Signal")
plt.show()
envelope = np.abs(y)
plt.plot(t, envelope)
[<matplotlib.lines.Line2D at 0x269e2970f50>]
window = 50
# We are averaging nearby points to remove fast changes
smoothed = np.convolve(np.abs(y), np.ones(window)/window, mode='same')
plt.plot(t, smoothed)
[<matplotlib.lines.Line2D at 0x269e2971710>]
from scipy.signal import butter, filtfilt
b, a = butter(3, 0.05)
filtered = filtfilt(b, a, np.abs(y))
plt.plot(t, filtered)
[<matplotlib.lines.Line2D at 0x269e4252a90>]
plt.plot(t, message, label="Original Message")
plt.plot(t, np.abs(y), label="Abs (raw envelope)", alpha=0.5)
plt.plot(t, smoothed, label="Moving Average")
plt.plot(t, filtered, label="Low-pass filter")
plt.legend()
plt.show()
FM Modulation¶
# FM Modulation
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 1, 2000)
# Message (slow signal)
message = np.sin(2*np.pi*2*t)
# Carrier base frequency
fc = 20
# Frequency deviation (how much it changes)
kf = 1000 # Change this to see what happens
# Instantaneous frequency
f_inst = fc + kf * message
# Build signal by integrating frequency → phase
phase = 2*np.pi * np.cumsum(f_inst) / len(t)
# FM signal
y_r = np.sin(phase)
#noise = 0.2*np.random.randn(len(y_r))
#y_r = y_r + noise
# Plot
plt.figure(figsize=(10,4))
plt.plot(t, y_r)
plt.title("FM Signal (Frequency Changes Over Time)")
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.show()
plt.plot(t[:300], y_r[:300])
plt.title("Zoomed FM Signal")
plt.show()
# easiest method to recover information
zero_crossings = np.where(np.diff(np.sign(y_r)))[0]
zc_times = t[zero_crossings]
# time differences between crossings
dt = np.diff(zc_times)
# frequency estimate (2 crossings per cycle)
freq_est = 1 / (2 * dt)
# time axis for estimated frequency
t_est = zc_times[:-1]
plt.plot(t_est, freq_est)
plt.title("Estimated Frequency")
plt.show()
window = 20
freq_smooth = np.convolve(freq_est, np.ones(window)/window, mode='same')
plt.figure(figsize=(10,4))
plt.plot(t, message, label="Original Message")
plt.plot(t_est, (freq_smooth - fc)/kf, label="Recovered (scaled)")
plt.legend()
plt.title("FM Recovery via Zero Crossings")
plt.show()
“We can detect how fast the signal is oscillating, but we don’t know whether the frequency increased or decreased.”
“We recovered part of the signal, but we lost information.”
To recover the full signal, you need:
- phase information
- or derivative with sign
- or quadrature (I/Q) signals
👉 That’s exactly what SDR will give us later
# Simple Trick (if you want it to look better visually)
recovered = (freq_smooth - fc)/kf
recovered = recovered - np.mean(recovered)
# --- Plot ---
plt.figure(figsize=(10,4))
plt.plot(t, message, label="Original Message")
plt.plot(t_est, (freq_smooth - fc)/kf, label="Recovered (scaled)")
plt.plot(t_est, recovered, label="Recovered (Centered)")
plt.legend()
plt.title("FM Recovery via Zero Crossings (Centered)")
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.show()
“FM is more robust to noise—but not always better in every situation.”
“The way you encode information determines how sensitive it is to noise.”
AM Advantages¶
🟢 1. Long-Distance Communication (Big One) AM signals can:
- travel hundreds to thousands of miles
- reflect off the ionosphere (especially at night) 👉 That’s why:
- AM radio stations can be heard across states or countries
🟢 2. Simpler Receivers (Low Complexity) AM is easy to decode:
- envelope detection (like your abs() demo!)
- minimal electronics needed 👉 historically:
- cheaper radios
- simpler systems
🟢 3. Lower Bandwidth Requirements AM uses:
- less bandwidth
- simpler signal structure 👉 good for:
- voice communication
- constrained systems
🟢 4. Better in Weak Signal Conditions When signal is very weak:
- FM → drops out suddenly (“cliff effect”)
- AM → degrades gradually (still intelligible)
🟢 5. Used in Critical Systems AM is still used in:
- aviation communication
- some emergency systems 👉 because:
- simple
- reliable
- predictable behavior
“Engineering is not about the ‘best’ solution—it’s about the right solution for the constraints.”