So I've been working on how to digitally implement a static reference frame PLL (SRF-PLL), which is a quite popular PLL used for extracting three-phase grid angle.

This PLL works by using the DQ0 transform as a phase detector. Using the estimated grid angle $\hat{\theta}(t)$ as the rotation angle $\theta_r(t)$ of the DQ0 transform, a signal $v_q(t)$ is obtained. This signal is proportional to the phase difference between $\hat{\theta}(t)$\ $\theta_r(t)$ and the true grid angle. A PI controller drives $v_q(t)$ to zero by adjusting $\Delta\omega(t)$, which is the difference between the expected grid frequency $\omega_g$ and the true grid frequency. This is then fed to a sawtooth generator/VCO (i.e. resettable integrator), which generates the estimated grid angle $\hat{\theta}(t)$.


Since the PLL I'm actually implementing is a little bit more complex, I basically need to discretize the individual blocks and not the whole thing in one go (is that even possible? Even if so, it wouldn't help my case - see additional info below).

Discretizing the PI and VCO is trivial enough, just use backwards euler or tustin/bilinear, easy - with the caveat that the integrator can't just be reset at any given timestep, it has to either "overflow" at $2\pi$ or have its output be the remainder of a division by $2\pi$ in order to avoid weird phase jumps.

That's all fine, the problem stems from the fact that a delay is obviously needed. My first approach was to place a unit delay between $\hat{\theta}(t)$ and $\theta_r(t)$, so my pseudo-code at each time-step would look like:

At each timestep compute:
    vq = DQ0(v_abc, theta_r)
    delta_omega = PI(vq)
    omega_i = omega_g + delta_omega
    theta_estimated = VCO(omega_i)
    //Prepare theta_r for next timestep
    theta_r = theta_estimated

Note that:

  • The DQ0 transform only outputs vq=0 if its input equals the grid angle $\theta[n]$.
  • Its input is theta_r, i.e. $\hat{\theta}[n-1]$.
  • The PI will drive vq to zero.

The only logical conclusion is that $\hat{\theta}[n-1]$ will equal $\theta[n]$. Thus it makes no sense to have $\hat{\theta}[n]$ be the actual output of the SRF-PLL, the output must be $\hat{\theta}[n-1]$ in order to achieve zero-error steady state.

But this is just weird. So if in a given timestep $n$ I find that my estimation was a little bit off, my PI corrects, a new angle is calculated... but I'll still be outputting $\hat{\theta}[n-1]$, which I know must be wrong because that's what I just used to compute the DQ0 transform!!

So yeah, basically I really don't know where to place the unit delay. I thought about it, like placing after the PI or after the DQ0 transform, but none really seem to make sense to me.

Where should I place the delay?

One super weird solution that I came up with (which would alter the system architecture) would be to add to theta_r what I "predict" $\theta[n]$ would be at the beginning of each timestep. Hence, the input to the DQ0 would be this "predicted" angle $\hat{\theta}[n-1] + \omega_i[n-1]\cdot sample\_rate$. I really don't like this solution because it is no longer a direct 1:1 discretization, but I'm curious to hear your opinions about it.

Additional info:

1) The DQ0 transform, whatever variant it might be (power invariant, amplitude invariant, A-aligned, 90deg before A, etc), is non-linear, involving different sine and cosine functions. Understanding how it works isn't really important to answer this question other than the fact that it provides a signal proportional to the phase difference between its rotation angle $\theta_r(t)$ and the grid angle of the three-phase voltages $v_a(t)$, $v_b(t)$ and $v_c(t)$.

2) Discretizing the whole thing in one go is not an option because my implementation requires other non-linear components. Hence, discretizing blocks one-by-one is my only choice.

EDIT: As was pointed out, placing a unit delay at any of the locations I mentioned makes no difference as LTI systems are commutative.

I guess the answer I'm searching for is more of a confirmation that yes - I just need to place a unit delay somewhere and live with the fact that the PLL takes 1 extra time-step to respond to disturbances - or that no - there is a way to make the PLL react to a disturbance in the same time-step where said disturbance appeared.

  • 1
    $\begingroup$ FIY : the first 3 solutions (delays in the forward path) will yield the same result. $\endgroup$
    – Ben
    May 31 '19 at 18:14
  • $\begingroup$ What is the transformation function in this case for the pll in order to design PI controller? $\endgroup$
    – ahmad
    Sep 3 '20 at 18:09

I faced the same problem in the past. Perhaps there is a way without adding a delay but I haven't found it.

You need to realize that your 3 first solutions (delay after vq, delay at the delta_freq and delay after the frequency) will yield the same result as omega_g is a constant and because your PI controller has fixed coefficients.

Anyway, place the delay where you want except in the feedback path. The phase estimate will barely be affected by the delay, which is what you want. You do not want to put the delay in the phase path, otherwise your phase would lag the phase of the input...

Another solution might be to use a discrete integrator (to compute the phase) with a forward euler method instead of tustin/backward euler method. This should also fix your algebraic loop.

  • $\begingroup$ Can you please elaborate a bit on how the forward method solves the need for a unit delay? I've never used it since I know it maps some stable continous time poles to unstable discrete poles, and have always kinda regarded it as this academic thing that no one really uses. $\endgroup$
    – Chi
    Jun 1 '19 at 0:45
  • 1
    $\begingroup$ The forward integration method uses the previous sample to compute the cumulative sum forward method : y[n] = y[n-1] + x[n-1] *Ts while the backward method uses the current sample. y[n] = y[n-1] + x[n]*Ts $\endgroup$
    – Ben
    Jun 1 '19 at 0:57
  • $\begingroup$ You just made me realize something. The PI computes some output x[n], and a backward diference integrator computes y[n-1] + x[n]*Ts, but if I place a unit delay then the integrator will instead compute y[n-1] + x[n-1]*Ts. Placing a delay = changing a backward difference into a forward difference, which leaves me with the same conundrum: the PLL takes 2 time-steps to react to a disturbance. $\endgroup$
    – Chi
    Jun 1 '19 at 1:16
  • 1
    $\begingroup$ Unless your sampling rate is really low, it is unlikely to be a problem. Your negative sequence signal will create more problems that the 2-step delay... $\endgroup$
    – Ben
    Jun 1 '19 at 2:10
  • 1
    $\begingroup$ Ah yes, the SOGI isn't represented in the figure. The QSG-SOGIs come after the ABC-Alpha Beta transform, and thus generate a filtered alpha (band-pass, no phase shift), a filtered and -90deg delayed alpha, a filtered beta, and a -90 filtered beta. Then, via some deductions you can find formulas that give you the alphas and betas that would result from only having those sequences. E.g. 0.5*(alpha_filtered - delayed_beta_filtered) = alpha_positive_sequence. By feeding the alpha and beta from the positive sequence to the SRF-PLL, you effectively eliminate the impact of the negative sequence. $\endgroup$
    – Chi
    Jun 13 '19 at 22:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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