Articles

First order digital PLL for tracking constant phase offset

Considering a typical scenario where there might exist a small phase offset between local oscillator between the transmitter and receiver.

Figure 1 : Transmitter receiver with constant phase offset

In such cases, it might be desirable to estimate and track the phase offset such that the performance of the receiver does not degrade.

A simple first order digital phase locked loop for tracking the constat phase offset can be as

Assuming that the transmitter signal $x(n)$ gets rotated by a constant phase $\phi$, the received signal $y(n) = x(n)e^{j\phi}$. In a simple no-noise case, assuming that the phase offset is small (and the signal gets decoded correctly), the estimate of phase offset is,

$\theta(n) = \arg\left\{\hat{x}^\ast(n)y(n)\right\}$.

Typically, a first order phase locked loop which converges to $\phi$is used for facilitating synchronous demodulation.

Figure 2 :

First order digital phase locked loop (PLL)

(adapted from Fig 5.7 of [Mengali])

The estimate $\theta(n)$ from each sampling instant is accumulated to form the estimate $\hat{\phi}(n)$. This estimated phase is removed from the received samples$y(n) = x(n)e^{j\phi(n)}$ to generate $x(n)e^{j\phi(n) - j\hat{\phi}(n)}$. The parameter$\alpha$is a non-zero positive constant in the range $(0\ 1]$ controls the rate of convergence of the loop. Higher value of $\alpha$indicates faster convergence, but is more prone to noise effects. Lower value of $\alpha$is less noisy, but results in slower convergence.

Assuming $\alpha=1$, the phase estimate at the output of the filter is

$\hat{\phi}(n) = \hat{\phi}(n-1) + \theta(n-1)$.

Substituting, $\theta(n) = \phi(n) - \hat{\phi}(n)$, then

$\hat{\phi}(n) = \hat{\phi}(n-1) + \phi(n-1) - \hat{\phi}(n-1)=\phi(n-1)$.

A simple Matlab code to simulate this can be as follows:

% random +/-1 BPSK source
xn = 2*(rand(1,1000) >0.5) - 1;
% introducing a phase offset of 20 degrees
phiDeg = 20;
% first order pll
alpha = 0.01;
phiHat = 0;
for ii = 1:length(yn)
yn(ii) = yn(ii)*exp(-j*phiHat);
% demodulating circuit
xHat = 2*real(yn(ii)>0) -1 ;
phiHatT = angle(conj(xHat)*yn(ii));
% accumulation
phiHat = alpha*phiHatT + phiHat;
% dumping variables for plot
phiHatDump(ii) = phiHat;
end

plot(phiHatDump*180/pi,'r.-')

Figure 3: Convergence of $\hat{\phi}$for two $\alpha$values.

Reference:

14 thoughts on “First order digital PLL for tracking constant phase offset”

1. Ananias says:

i tried this an worked. however, i would appreciate help in understanding what happened here…

% demodulating circuit
xHat = 2*real(x_n(ii)>0) – 1 ;
phiHatT = angle(conj(xHat)*x_n(ii)) – angle(conj(xHat)*xn(ii));
if phiHatT pi
phiHatT = -2*pi + phiHatT
end

1. Ananias says:

% demodulating circuit
phiHatT = angle(x_n(ii)) – angle(xn(ii));
if phiHatT pi
phiHatT = -2*pi + phiHatT
end

works too…

2. Ananias says:

i got it to work, but i still dont understand quite well what i said before. are you projecting an X axis or something like that? i really want to know. thank you.

look:

clc
clear all;

% sine wave
Tp = 1/60;
T = Tp/128;
Fp = 1/Tp;
Fs = 1/T;
w = 2*pi*Fp;
t = [0:T:809*T];
xn = sin(w*t);
%al simular con e^jwt siempre quedara una parte representada en coord imaginarias, por lo k habria k hacer unas modificaciones para que se detecte cuando no sea error de fase y sea causa de la misma onda.
%sin(wt+phi) = (e^jwt-e^-jwt)*e^phi/(2j)

% introducing a phase offset
phiDeg = -100;
% se puede representar un desfase cualquiera como e^j(wt+phi) ?

% first order pll
alpha = 0.05;
phiHat = 0;
x_n = zeros(length(t));

for ii = 1:length(t)
x_n(ii) = yn(ii)*exp(-j*phiHat);

% demodulating circuit
xHat = 2*real(x_n(ii)>0) – 1 ;
phiHatT = angle(conj(xHat)*x_n(ii)) – angle(conj(xHat)*xn(ii));

% accumulation
phiHat = alpha*phiHatT + phiHat;
% dumping variables for plot
phiHatDump(ii) = phiHat;
end
%plot(t,xn);
%hold on;
%plot(t,yn);
plot(t,phiHatDump*180/pi,’r.-‘);

1. Ananias says:

it still wont work for angles above 90 degrees….

2. @Ananias: There are two assumptions
a) phase is constant
b) slicing of the received symbols is needed to remove the effect of modulation

3. Ananias says:

Im trying to use this for a sine wave in the input. problem is it only works for 90 and -90. what can i do about it? i dont quite understand how you get the angle with
% demodulating circuit
xHat = 2*real(yn(ii)>0) -1 ;
phiHatT = angle(conj(xHat)*yn(ii));

4. Dinu says:

Hi Krishna,

Can this code be used to recover the carrier ? Carrier signal is in 1GHz range.

Thank you

1. @Dinu: For recovering the carrier, we might need a second order loop. Will write about it soon.

1. Dinu says:

Hi,

Thanks fr the reply Krishna. In the previous comment by Venkat, he describes quite similar scenario to my program. How can I check the accurancy of the code?

I have another question, I am working on low SNR environment. Does these phase lock loop work on low snr region?

1. @Dinu: This piece of code does only phase tracking and not frequency tracking. I have not tried checking the performance in the low SNR region.

5. tien says:

thanks

6. venkat says:

Hello Krishna,
I have referred your example on first order PLL for constant phase tracking.It was very useful.
https://dsplog.com/2007/06/10/first-order-digital-pll-for-tracking-constant-phase-offset/
But in the example a complex carrier is being used at the transmitter and receiver.Practically , when I use a cosine carrier at Tx. and cosine,sine carriers at Rx.(as in costas loop) , can the same loop filter be used ?
I have tried to simulate the above situation in the following script but was unable to estimate the phase. Please help me……….

% MODULATION

clc;
clear all;
close all;

[b,a] = butter(1,0.0156,’low’); % low pass filter to remove
nterm_i = 0; % double frequency component
dterm_i = 0;
nterm_q = 0;
dterm_q = 0;

n_sym = 10; % number of symbols
fs = 12.8e6;
t = 0:1/fs:100e-6 – 1/fs;
fc = fs/8; % carrier freuency
theta = 70*pi/180; % phase offset
r = 0.1e6; % symbol rate
oversamp = fs/r;
sym = randint(n_sym,1)*2-1;
in = 0;
for ind=1:1:n_sym
tmp(1:oversamp) = sym(ind);
in = [in tmp];
end
tx = in(2:end);
tx_carrier = cos(2*pi*fc*t + theta);

tx_out = tx.*tx_carrier;

% first order pll
alpha = 0.05;
phiHat = 0;

for ii = 1:1:length(t)

% Remove carrier
rx_i(ii) = tx_out(ii)*cos(2*pi*fc*t(ii) + phiHat);
rx_q(ii) = tx_out(ii)*sin(2*pi*fc*t(ii) + phiHat);

% low-pass IIR filter for I-channel
iir_in_i(ii) = rx_i(ii);
iir_out_i(ii) = b(1)*iir_in_i(ii)+ nterm_i + dterm_i;
nterm_i = b(2)*iir_in_i(ii);
dterm_i = a(2)*iir_out_i(ii);

% low-pass IIR filter for Q-channel
iir_in_q(ii) = rx_q(ii);
iir_out_q(ii) = b(1)*iir_in_q(ii)+ nterm_q + dterm_q;
nterm_q = b(2)*iir_in_q(ii);
dterm_q = a(2)*iir_out_q(ii);

% demodulating circuit
xHat = 2*(iir_out_i(ii)>0) -1 ; % symbol estimate
phiHatT =angle(conj(xHat)*rx_i(ii)); % phase error estimate angle(iir_out_i(ii) + i*iir_out_q(ii));%

% accumulation
phiHat = alpha*phiHatT + phiHat; % phase accumulator output
% dumping variables for plot
phiHatDump(ii) = phiHat;
end

plot(phiHatDump*180/pi,’-‘);

1. @venkat: Does your transmit signal contain phase information? Did the code work in no noise case?