OFDM Frequency Offset Estimation and Correction in MATLAB

This article provides MATLAB code for frequency offset estimation and correction in an OFDM receiver. This technique is commonly used in wireless technologies like WLAN, WiMAX, and LDACS.

Frequency Offset estimation Frequency Offset estimation

Frequency synchronization is crucial for receivers to compensate for frequency offsets caused by variations and drifts in transmitter and receiver clocks.

We’ll explore frequency offset estimation using reference data, specifically the preamble. The process involves these steps:

  • Extract the first symbol of the preamble from the received packet (excluding the cyclic prefix, CP).
  • Multiply the first 128 samples with the complex conjugate of the subsequent 128 samples of the first preamble symbol.
  • Calculate the angle of the resulting 128 multiplications.
  • Average the angle vector.
  • Divide the average value by 2π2\pi.
  • Multiply the result by 4, as frequency bins are spaced every fourth place.
  • This yields the frequency offset.
  • Note: Frequency offset estimation can also be performed using the second symbol. In this case, you would multiply the result by 2 because frequency bins are spaced every second place in the second preamble symbol.

Here’s the MATLAB code:

clc;
close all;
clear all;

CP=64;

load file_wimaxtxpkt;
load file_wimax_preamble;

Tx_Packet=awgn(Tx_Packet,40,'measured');

%%%%Introducing frequency offset%%%%%%%%%%%%
CFO = 40e3; % Hz    Here 40KHz frequency offset
CFO = (CFO)/20e6;
rx_data_fo = impairments(Tx_Packet,CFO);

%Frequency offset estimation using first symbol preamble in time domain
sh_dat = rx_data_fo((CP+1):256+CP);

for m=0:128
    theta(m+1) = angle(sh_dat(65+m:128+m)*sh_dat(1+m:64+m)')/(2*pi);
end

theta = mean(theta);
f_off1 = (theta*4)*20e6/256

%Frequency offset estimation using second symbol preamble in time domain
lo_dat = rx_data_fo((2*CP+256+1):256+2*CP+256);

theta = angle(lo_dat(129:256)*lo_dat(1:128)')/(2*pi);
f_off2 = (theta*2)*20e6/256

f_off=(f_off1+f_off2)/2  % average of both above symbol based estimation.

%%%%%%%%%Frequency offset correction%%%%%%%%
rx_data_corrected = rx_data_fo.*exp(-1i*2*pi*(f_off/20e6)*(0:length(rx_data_fo)-1));

Frequency Offset Correction

To correct for the frequency offset, use the estimated offset and multiply the received symbols by an exponential function:

y(n)=y(n)exp(i2παn/N)y(n)= y'(n) \cdot exp(-i2\pi \alpha n/N )

where:

  • n is the sample index
  • N is the number of samples in a symbol
  • y(n)y(n) are the received samples without frequency offset
  • y(n)y'(n) are the received samples with frequency offset
  • α\alpha is the estimated frequency offset (f_offf\_off, f_off1f\_off1, or f_off2f\_off2 from the code above)

Download MAT files containing the required data.