In an attempt to get myself up to speed with PLLs I'm trying to implement Example 1 from this tutorial, in Python: https://wirelesspi.com/phase-locked-loop-pll-in-a-software-defined-radio-sdr/ (search for "Example 1")
I have output that is close to what the article shows, except that my cos_out[n]
seems to be "leaning" to the left:
My phase-difference signale_D[n]
is flipped vertically from what the tutorial shows:
I must be missing a -
sign or have a sin()
where I need cos()
but I've checked and triple checked my code.
My code:
import numpy as np
k = 1
N = 15
K_p = 0.2667
K_i = 0.0178
K_0 = 1
samples = np.linspace(0, 100, 100, endpoint=False)
input_signal = np.cos(2*np.pi*(k/N)*samples + np.pi)
integrator_out = 0
phase_estimate = []
e_D = [] #phase-error output
e_F = [] #loop filter output
sin_out = []
cos_out = []
for n, sample_in in enumerate(input_signal):
# phase detector
try:
e_D.append(sample_in * sin_out[n-1])
except IndexError:
e_D.append(0)
#loop filter
integrator_out += K_i * e_D[n]
e_F.append(K_p * e_D[n] + integrator_out)
#NCO
try:
phase_estimate.append(phase_estimate[n-1] + K_0 * e_F[n])
except IndexError:
phase_estimate.append(K_0 * e_F[n])
sin_out.append(-np.sin(2*np.pi*(k/N)*n + phase_estimate[n]))
cos_out.append(np.cos(2*np.pi*(k/N)*n + phase_estimate[n]))