I am trying to write my first PLL in Python, and I've been making use of this excellent tutorial:


Reading through the math on pages 7 and 8 (very minimal- it's just a few lines), I have one point of confusion:

Let's assume, like they do in the tutorial, that the reference (power grid) voltage signal to be tracked is $V_{r}\sin(\omega_{r}t)$ and that our VCO voltage can be expressed with the two components $\sin(\omega_{v}t)$ and $\cos(\omega_{v}t)$. We integrate the incoming grid voltage to get a cosine term of $V_{r}\cos(\omega_{r}t)$, and then combine our four sinusoidal terms together in a way that reduces to $V_{r}\sin(\omega_{r}t-\omega_{v}t)$. According to the tutorial, we feed that function into the VCO, which then changes $\omega_{v}$ until the frequencies are equal and the term in the sine is zero for all $t$.

That all seems well and good when the initial phase of the incoming reference wave is 0. In that case, $V_{r}\sin(\omega_{r}t-\omega_{v}t)$ is positive when $\omega_{v}$ is less than $\omega_{r}$ and it is negative when $\omega_{r}$ is less than $\omega_{v}$. But what if the grid voltage is actually at some initial phase offset relative to the VCO? Let's say the true equation of our input to the VCO is, for example, $V_{r}\sin(\omega_{r}t-\omega_{v}t+\pi)$. Then $\omega_{v}$ could be less than $\omega_{r}$ and $V_{r}\sin(\omega_{r}t-\omega_{v}t+\pi)$ would still be negative. The VCO would falsely interpret this as a "you're ahead of the reference frequency, slow down" command, $\omega_{r}$ and $\omega_{v}$ would separate even further over the course of the wave's negative half-cycle, and I don't think a PI frequency controller would ever recover from that.

I'm not seeing a way around this problem. We don't have access to the actual frequency difference, only to the value of the combination sine function we've created. We also can't make any claims about the initial phase angle of the reference voltage, since we could have started our PLL at any point in its cycle and it could have any initial phase relationship to our VCO. If anyone could help me understand how we get past this issue, it would be a huge help. Thanks in advance!

EDIT: PLL block diagrams such as the one in the link below have a low-pass filter on the input to the VCO, but I don't believe that has anything to do with my question. Unless I'm mistaken, that LPF is just there to remove the high frequency component $\omega_{r}+\omega_{v}$ that results from the phase detector, i.e. the "combine VCO and reference signal" block. The LPF then leaves us with a pure (in the ideal case) sine wave $V_{r}\sin(\omega_{r}t-\omega_{v}t)$. If I'm wrong about that, though, please let me know!


EDIT 2: Had a helpful exchange with Dan, who gave me some pointers on more efficiently modeling a PLL. He also pointed out that it would be helpful clarify that my confusion is regarding how to implement a PLL. I am assuming that I don't know the phase or the frequency of the incoming reference signal ahead of time. In fact, that's why I'm building a PLL in the first place: I have a sinusoid of unknown phase and frequency, and I am trying to determine both of those quantities by locking a VCO to it and then just querying the VCO.

  • 1
    $\begingroup$ I just want to comment while this will simulate a PLL with actual sinusoidal waveforms which may be educational but it is not the typical (or recommended) approach to modeling PLL’s (in Python or other tools such as Matlab or Octave). Typically a system equation is done in units convenient to the various “test points” around the loop; such as radians at the VCO output for the case of a PLL such that the VCO is simply modeled as an integrating gain ($K_v/s$) or equivalent forms in terms of z for all-digital implementations. This is facilitated by the control toolbox (pip install control). $\endgroup$ Sep 25, 2018 at 17:29
  • $\begingroup$ Thanks very much for your comment - that's good to know, and I could certainly see it being a more efficient way to implement. In units of VCO output radians, though, what would the phase detector block look like? Since we don't have access to the phase of the incoming reference signal, how can we compare that and the VCO? $\endgroup$
    – kb4444
    Sep 25, 2018 at 17:44
  • $\begingroup$ Yes you absolutely have access to the phase of the incoming reference signal in a phase lock loop as that is what you are locking to. The phase detector would have two inputs in units of radians (phase) and an output in units of volts (or any other magnitude, such as "counts" in a digitized implementation). So the phase detector has a gain of $K_d$ with units of Volts/Radian (volts out, radians in). Again these are the units to use in the mathematical model and do not directly represent the physical system in terms of what you may see on an oscilloscope.... $\endgroup$ Sep 25, 2018 at 18:05
  • $\begingroup$ ...but you can always translate it to that. For example, a frequency offset when using radians would be a linear slope of phase increasing (or decreasing) with time. $\endgroup$ Sep 25, 2018 at 18:06
  • $\begingroup$ Sorry if I'm being slow here. I can certainly see how the system would work if you could define a phase detection block with some kind of relationship $V_{out}=K_{d}(\theta_{r}-\theta_{vco})$, but isn't getting the phase angle of the reference signal ($\theta_{r}$) nontrivial? You have an incoming signal that you know is a sinusoid, but initially has an unknown frequency/phase. Certainly after you've driven the phase error between ref and VCO (that's what's meant by "locking," right?) to zero then you have access to the phase angle (it's just equal to the VCO's), but before then you need... $\endgroup$
    – kb4444
    Sep 25, 2018 at 18:15

1 Answer 1


Here are some helpful tips to proceed with an all digital PLL implementation specific to your desire to determine the phase of your reference by observing the phase of your (cleaner) VCO.

First I would recommend using an NCO instead of a VCO. Here is a previous post where I provided hopefully helpful information on implementing an NCO.

Numerically Controlled Oscillator (NCO) for phasor implementation?

The advantage with this is that you can directly read the instantaneous phase from the phase accumulator (it also implies that you have some master reference of time since the phase accumulator will be continuously counting consistent with the output frequency as $d\phi/dt$.

Next assuming your "capture range" is narrow enough, you can use a simple multiplier as the phase detector, followed by a wide low pass filter for the purposes you describe; a real multiplier will create the sum and difference of the two signals; you would be multiplying the NCO digital output with a digitized representation of your reference signal resulting in a component at the multiplier output that is at twice the reference frequency (sum of reference and NCO specifically) that you want to filter out and the difference of the two which results in the phase error between the two. For more details on such phase detectors see the "Phase Detector" section of this post:

Phase synchronization in BPSK

Also at the bottom of the above link is an all digital carrier recovery loop that would be similar in structure to such a PLL implementation for your purpose. Specifically after the error signal shows the implementation diagram for the Proportional-Integral Loop filter that can be used after the wider filter mentioned above. The output of the Loop Filter is the control word as the input to the NCO (The NCO is also shown in this diagram as a complex implementation providing both sine and cosine outputs, to simplify your first approach you can simply use a real NCO and real phase detector which is a single multiplier).

Note depending on phase detector used, the loop will likely lock in quadrature to the input signal (if you use a real multiplier specifically this will happen as the phase detector output is 0 when the two inputs are in quadrature).

As far as "capture range" when using the simple multiplier as a phase detector; typically this is referred to the frequency range in which a PLL locks within a single beat-note between the frequencies compared, and the tuning range of the NCO should be limited to stay within this range. Here is a reference that develops the capture range for a simple XOR gate phase detector (note that an XOR gate is a hard-limited multiplier so has a similar operational range).


  • $\begingroup$ This is a terrific and thorough answer. It went a ways deeper into practical implementation than I had been considering and brought up a few questions that I didn't know I had. For anyone who might have a similar confusion to mine and wants a good place to start in addressing it, I would recommend Dan's citation about "phase detectors." After reading that, I realized that the trig identities mentioned in my original post do give you enough information to determine the phase difference of your signal, and that's all you need to feed to the NCO to get a working feedback loop. $\endgroup$
    – kb4444
    Sep 29, 2018 at 0:58
  • 1
    $\begingroup$ Thanks @kb4444 you can actually make it lock by feeding it directly to the NCO, but this would be only a "First Order Type 1" Loop, which means in short that the phase error once locked between the reference and feedback signal will be proportional to the frequency offset between them (makes sense as the NCO needs a constant value to lock to an arbitrary frequency, so if directly connected (with appropriate gain scaling) the Phase Detector will be at a proportionate value to that constant needed. This is the reason for the additional PI Loop Filter I described (to be 2nd order type 2). $\endgroup$ Sep 29, 2018 at 1:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.