-
Notifications
You must be signed in to change notification settings - Fork 2
/
receiver.m
210 lines (170 loc) · 6.13 KB
/
receiver.m
1
%----------------------------------------------------%----------------- Demodulator ----------------------%----------------------------------------------------phase_rx = 0; Rx_I = Rx .* (sqrt(2)*cos(2*pi*Fc_tx*t+phase_rx));Rx_Q = Rx .* (-sqrt(2)*sin(2*pi*Fc_tx*t+phase_rx));%----------------------------------------------------%----------------- Low Pass FIR Filter --------------%----------------------------------------------------%% Low pass FIR filter can be easily implemented with a rectangular%% function in frequency domain to cut everuthing after the cutoff.%% Which in the time domain corresponds to a sinc function.%% Since it's a FIR filter, there is no feedback coefficient, so A = 1%% Multiplying in frequency corresponds to convolution in temporal%% So, we reverse the incremental in the for loop using d2%% And we make sure to not divide by 0 in case we have an odd order%% And then we got B and we can filter the demodulated signak%% Fcutoff is normalized, so divided by the Nyquist frequency, Fs/2%% The order of the FIR can be approximated with the formula%% Attenuation of the stopband%% FIRorder = ---------------------------------------%% 22 * (Fstopband - Fpassband) / FsamplingAtt = 20; %%in dBFpass = Rs/2; %% Passband frequencyFstop = 2*Fc_tx - Fpass; %% Stopband frequencyFIRorder = ceil(Att/ (22 * (Fstop - Fpass) / Fs)); Fcutoff = Fpass/(Fs/2); A_LPF = 1;B_LPF = 0;M = (FIRorder - 1)/2;for i = 0 : FIRorder-1 j = i - M; if (j == 0) B_LPF(i+1) = Fcutoff; else B_LPF(i+1) = sin(pi * Fcutoff * j) / (pi * j); endifendB_LPF = (1/sum(B_LPF)) * B_LPF; %%gain added to go back to the same range as the mapped symbolsRx_I_LPF = filter(B_LPF, A_LPF,Rx_I);Rx_Q_LPF = filter(B_LPF, A_LPF,Rx_Q);%----------------------------------------------------%----------------- Matched SRRC filter --------------%---------------------------------------------------- % Using the matched filter of the SRRC to get back the signalRx_I_BB = filter(B_SRRC, A_SRRC, Rx_I_LPF); Rx_Q_BB = filter(B_SRRC, A_SRRC, Rx_Q_LPF);%----------------------------------------------------%----------------- Downsampling ---------------------%----------------------------------------------------%% First downsampling is the simplest one, we take the sample%% at the k * Ns time%% Second downsampling is a bit more interesting, we use Gardner%% algorithm to calculate the error. However, there is no interpolator,%% so the technique only works well with a big samples_per_symbol number (Ns)%%%%%%%%%%%%%%%%%%%%%%%%%%%% Easy downsamplingsample_timing(1) = 2*Ns*G + 1;for i = 1 : numberOfSymbols receivedSymbols_I1(i) = Rx_I_BB(sample_timing(i)); receivedSymbols_Q1(i) = Rx_Q_BB(sample_timing(i)); if(i < numberOfSymbols) sample_timing(i+1) = sample_timing(i) + Ns; endif endreceivedSymbols1 = complex(receivedSymbols_I1, receivedSymbols_Q1);%%%%%%%%%%%%%%%%%%%%%%%%%%%% Gardner without interpolatorstep = 1;e = zeros(1, numberOfSymbols);k(1) = 2 * Ns * G + 1;for i = 1 : numberOfSymbols % Downsampling receivedSymbols_I2(i) = Rx_I_BB(k(i)); receivedSymbols_Q2(i) = Rx_Q_BB(k(i)); %% Gardner error if (i > 1) e(i) = (Rx_I_BB(k(i)) - Rx_I_BB (k(i-1))) * Rx_I_BB(k(i) - Ns/2); e(i) = e(i) + (Rx_Q_BB(k(i)) - Rx_Q_BB (k(i-1))) * Rx_Q_BB(k(i) - Ns/2); endif if mean(e) > 0 delta(i) = -step; elseif mean(e) < 0 delta(i) = step; else delta(i) = 0; endif %% Change of the sampling time if (i < numberOfSymbols) k(i+1) = k(i) + Ns + delta(i); k_plot(i+1) = mod(k(i+1) +Ns/2, Ns); %%for debugging endif endforreceivedSymbols2 = complex(receivedSymbols_I2, receivedSymbols_Q2);receivedSymbols = receivedSymbols1;%----------------------------------------------------%----------------- QAM Demapper ---------------------%----------------------------------------------------% Map symbols to bitsfor i = 1:length(receivedSymbols) [diff receivedSymbolsIndex(i)] = min( receivedSymbols(i) - mappingTable) ; endforreceivedSymbolsIndex = receivedSymbolsIndex - 1;for i = 1:length(receivedSymbols) dataOut(i*2 - 1) = rem(floor(receivedSymbolsIndex(i)/2), 2); dataOut(i*2) = rem(receivedSymbolsIndex(i), 2);endfor%----------------------------------------------------%----------------- Bit Error Rate -------------------%----------------------------------------------------BE = 0;for i = 1:length(dataIn) if dataIn(i) != dataOut(i) BE++; endifendforBER = BE/length(dataIn) * 100;%----------------------------------------------------%----------------- Figures --------------------------%----------------------------------------------------figure(11)scatter(real(receivedSymbols1), imag(receivedSymbols1) , "filled");axis([-2 2 -2 2])title("Received Symbols 1")##figure(12)##scatter(real(receivedSymbols2), imag(receivedSymbols2) , "filled");##axis([-2 2 -2 2])##title("Received Symbols 2")##figure(12)##stem(dataOut,"filled");##xlabel('Bit Index');##title('Data Out');##ylabel('Binary Value');##figure(13)##plot(Rx_I_LPF);##figure(15)##plot(real(mappedSymbols_upsampled));##figure(14)##plot(Rx_Q_LPF);##figure(16)##plot(imag(mappedSymbols_upsampled));##figure(17);##stem(real(mappedSymbols_upsampled));##figure(18);##plot(2*Ns*G +1 :length(Rx_I_BB), Rx_I_BB(2*Ns*G +1 : end));##hold on##stem(2*Ns*G +1 :length(Rx_I_BB), Rx_I_BB(2*Ns*G +1 : end));##hold on##stem(2*Ns*G +1: Ns :length(Rx_I_BB), Rx_I_BB(2*Ns*G +1 : Ns : end), 'filled');####figure(19);##plot(Rx_I_BB);##hold on##stem(Rx_I_BB);##figure(21);##stem(Rx_I_BB);##hold on##stem(k, Rx_I_BB(k), 'filled');##hold on##stem(sample_timing, Rx_I_BB(sample_timing), 'filled');##legend("Rx_I_BB", "k", "sample_timing");%----------------------------------------------------%----------------- Clear ----------------------------%----------------------------------------------------clear Rx Rx_I Rx_Q clear Rx_I_LPF Rx_Q_LPF %clear Rx_I_BB Rx_Q_BBclear i jclear Att Fpass Fstop Fcutoff A_LPF B_LPF FIRorderclear A_SRRC B_SRRCclear tclear receivedSymbolsIndex diff