Fractionally Spaced Equalizer with LMS algorithm

42 views Asked by At

I have created a FSE with LMS algorithm. The problem I am facing is related to the Symbol Error Rate (SER). I want it to be as small as possibile, the value that i have found is around 0.4, but i prefered to be close to 0.01.

I have tried different ways, but I falled in all of them.

I expected lower value for SER, but I have found a high value.

clear all
close all
clc

% Root of raised cosine filter parameters
alpha = 0.35;    % Rolloff factor
L     = 24;      % Truncated impulse length (-L/2:L/2)
Nc    = 12;      % Number of samples per symbol 

% Tx filter design
istrt = floor(L/2);
n     = -istrt:1/Nc:istrt;     %(-L/2:1/Nc:L/2)
pt    = truncRRC(n, alpha,0);

pt_delay=0.5*pt+0.2*truncRRC(n, alpha, 1)+0.2*truncRRC(n, alpha, 2)+0.1*truncRRC(n, alpha, -2);

figure
subplot(2,1,1)
stem((-L/2:1/Nc:L/2),pt);
xlim([-5 5]);
title('No ISI');

subplot(2,1,2)
stem((-L/2:1/Nc:L/2),pt_delay);
xlim([-5 5]);
title('ISI');

M = 2;
mb = log2(M);

nFrm     = 1;           % num di frames
nSym = 1000;        % length of the data sequence (num di simboli)
nSFrm    = nSym;
data_seq = sign(randn(1,nSym)); % Generate BPSK data

figure
scatter(real(data_seq), imag(data_seq),'red')
title('Ideal BPSK symbols');

pairs = [1 2; 3 4; 5 6; 7 8; 9 10; 11 12; 13 14;
         15 16; 17 18; 19 20; 21 22; 23 24; 25 26;
         27 28 ;29 30; 31 32; 33 34; 35 36; 37 38;
         39 40; 41 42; 43 44; 45 46; 47 48; 49 50;
         51 52; 53 54; 55 56; 57 58; 59 60; 61 62; 63 64];

% Generate Barker sequence
barker = ones(1, 16);
for i = 1:size(pairs, 1)
    barker(pairs(i, 1)) = -1;
    barker(pairs(i, 2)) = 1;
end
barker_len = size(barker);

trainSymtx_len = nSym; % sceglila tu!
trainSymtx = sign(randn(1, trainSymtx_len));

ReadySignal = [barker, trainSymtx, data_seq];

% Transmission filtering: upsample and filter
txSig_up = upsample(ReadySignal, Nc);
txSig    = filter(pt_delay, 1, txSig_up);

SampleRate = 1e6;                         % SampleRate ~ rate the device is configured to collect data
SamplesPerRXFrame = length(txSig);       % SamplesPerRXFrame ~ size of the buffer/ frame transfer from PlutoSDR to MATLAB                                      

FramesToCollect = 10;                     % Frame exchanged between Adalm Pluto and MATLAB
FrequencyOffset = 0;                      % Frequency Error (Hz)

rx = sdrrx('Pluto','SamplesPerFrame',SamplesPerRXFrame,...
           'BasebandSampleRate',SampleRate,'OutputDataType','double');
tx = sdrtx('Pluto','Gain',-20,...
           'BasebandSampleRate',SampleRate);

tx.CenterFrequency = tx.CenterFrequency + FrequencyOffset;          % Correction of the Rotation introduced by the Frequency Error
txSig = complex(txSig,0);
tx.transmitRepeat(txSig');

% Get data from radio --> Checking Overflow Conditions

sa=dsp.SpectrumAnalyzer();

saved = zeros(FramesToCollect*SamplesPerRXFrame,1);
ofe = 0;

for g = 1 : SamplesPerRXFrame : FramesToCollect * SamplesPerRXFrame
    [sig_rx, ~, of] = rx();
    saved(g : g+SamplesPerRXFrame - 1) = sig_rx;
    % Checking and counting overflows events
    if of                    
        ofe = ofe + 1;
    end
end

% Visualize
for g=1:SamplesPerRXFrame:FramesToCollect*SamplesPerRXFrame
    sa(saved(g:g+SamplesPerRXFrame-1));
end

clear rx tx;

%% Set up radio and capture some data

rx = sdrrx('Pluto','SamplesPerFrame',SamplesPerRXFrame,...
    'BasebandSampleRate',SampleRate);

tx = sdrtx('Pluto','Gain',-20,...
    'BasebandSampleRate',SampleRate);

tx.transmitRepeat(txSig');

% Get data from radio
sa = dsp.SpectrumAnalyzer();
sa(complex(zeros(SamplesPerRXFrame,1,'int16')));

ofe = 0;

for g=1:FramesToCollect
    [sig_rx,~,of] = rx();

    if of
        ofe = ofe + 1;
    end
    sa(sig_rx);
end

clear rx tx;

% Receiver filtering
rxSig = filter(pt, 1, txSig)./Nc; 
figure;
scatter(real(rxSig), imag(rxSig),'red')
title('seq rx con ISI Filtrata')
ylim([-0.5 0.5])

preamble_up = upsample(barker, Nc);
[r,lags]    = xcorr(rxSig,preamble_up);  

[~, idx]           = max(real(r));
start_preamble_idx = lags(idx);  

%% 1) Estrazione del Preambolo dal Frame
% PREAMBOLO inizia da start_preamble_idx+1 in avanti
preamble_syms = rxSig(start_preamble_idx+1:start_preamble_idx+length(preamble_up));
preamble_syms_ds = downsample(preamble_syms,Nc) 

preamble_syms_ds = 2*double(preamble_syms_ds>0)-1

okey_preambolo = 0;
for ii=1:length(barker)
    if preamble_syms_ds(ii) == barker(ii)
        okey_preambolo = okey_preambolo+1;
    end
end

if okey_preambolo == length(barker) % esce 38 = 39 ..
    disp('Il preambolo è stato stimato correttamente');
end

% 2) Estrazione della Training_Seq dal Frame
training_seq    = rxSig(start_preamble_idx+length(preamble_up)+1:start_preamble_idx+length(preamble_up)+Nc*trainSymtx_len);
training_seq_ds = downsample(training_seq,Nc)

% 3) Estrazione dei Dati (payload) dal Frame .. cioè separo _data(payload)_ da _training_ e da _preambolo_
data_seq_rx = rxSig(start_preamble_idx+length(preamble_up)+Nc*trainSymtx_len+1:end);
data_seq_rx_ds = downsample(data_seq_rx,Nc)


% FSE and LMS parameters
N        = 22;         
numTaps  = 2 * N + 1; 
stepSize = 0.01;
is_training = 1;

% Initialize tap weights
tapWeights = zeros(1, numTaps);

for k = 1:2*length(trainSymtx)

    for i = N+1:length(trainSymtx)-N

        % Current received symbol
        currSymbols = training_seq_ds(i-N:i+N);  

        % L'output dell'equalizzatore
        y(k) = tapWeights * currSymbols';

        if mod(k, 2) == 0

           a = k/2;

           % L'errore tra l'output e il simbolo di training
           error = y(k) - trainSymtx(a);

            % Update tap weights
           tapWeights = tapWeights - stepSize * error * conj(training_seq_ds(i-N:i+N));
        end
    end
end

tapWeights_tracking = tapWeights;

% Decision Device
estimated_symbols = zeros(size(data_seq_rx_ds));
dist_vec = zeros(size(data_seq_rx_ds));

for b = N+1:length(data_seq_rx_ds)-N

    % Current received symbol
    currSym = data_seq_rx_ds(b-N:b+N);

    % L'output dell'equalizzatore
    eq_out(b) = tapWeights_tracking * currSym';

 estimated_symbols = 2*double(eq_out>0)-1;

% Error between equalizer output and estimated symbol
    error = eq_out(b) - estimated_symbols(b);

    % Update tap weights
    tapWeights_tracking = tapWeights_tracking - stepSize * error * conj(currSym);
end

final_estSym = downsample(estimated_symbols, 2);
figure, scatter(real(final_estSym), imag(final_estSym), '*r'), title('Estimated symbols')
xlim([-1.1 1.1])
ylim([-0.4 0.4])

% Symbol Error Rate (SER)
num_errors_symbol = sum(final_estSym ~= data_seq(1:length(final_estSym)));
SER = num_errors_symbol / length(final_estSym);
fprintf('Symbol Error Rate (SER): %.4f\n', SER);

0

There are 0 answers