EXP NO - 10
PROGRAM :
WIRELESS CHANNEL SIMULATION INCLUDING FADING AND DOPPLER EFFECTS
% Define Parameters
sampleRate500kHz = 500e3; % Sample rate of 500 KHz
sampleRate20kHz = 20e3; % Sample rate of 20 KHz
maxDopplerShift = 200; % Max Doppler shift of diffuse components (Hz)
delayVector = (0:5:15) * 1e-6; % Discrete delays of 4-path channel (s)
gainVector = [0 -3 -6 -9]; % Average path gains (dB)
KFactor = 10; % Rician K-factor (linear ratio)
specDopplerShift = 100; % Doppler shift of specular component (Hz)
% Configure Rayleigh Channel
rayChan = comm.RayleighChannel( ...
'SampleRate', sampleRate500kHz, ...
'PathDelays', delayVector, ...
'AveragePathGains', gainVector, ...
'MaximumDopplerShift', maxDopplerShift, ...
'RandomStream', 'mt19937ar with seed', ...
'Seed', 10, ...
'PathGainsOutputPort', true);
% Configure Rician Channel
ricChan = comm.RicianChannel( ...
'SampleRate', sampleRate500kHz, ...
'PathDelays', delayVector, ...
'AveragePathGains', gainVector, ...
'KFactor', KFactor, ...
'DirectPathDopplerShift', specDopplerShift, ...
'MaximumDopplerShift', maxDopplerShift, ...
'RandomStream', 'mt19937ar with seed', ...
'Seed', 100, ...
'PathGainsOutputPort', true);
% QPSK Modulator
qpskMod = comm.QPSKModulator( ...
'BitInput', true, ...
'PhaseOffset', pi/4);
% Number of bits per frame
bitsPerFrame = 1000; % 500 symbols per frame for QPSK
msg = randi([0 1], bitsPerFrame, 1); % Generate random bits
% Modulate the message
modSignal = qpskMod(msg);
% Apply Rayleigh and Rician channels
rayChan(modSignal);
ricChan(modSignal);
% Release channels before changing non-tunable properties
release(rayChan);
release(ricChan);
% Enable Impulse and Frequency Response Visualization
rayChan.Visualization = 'Impulse and frequency responses';
rayChan.SamplesToDisplay = '100%';
% Transmit two frames and visualize channel response
numFrames = 2;
for i = 1:numFrames
msg = randi([0 1], bitsPerFrame, 1); % Generate random bits
modSignal = qpskMod(msg); % Modulate data
rayChan(modSignal); % Filter data through Rayleigh channel
end
% Switch to Doppler Spectrum Visualization
release(rayChan); % Release channel before changing properties
rayChan.Visualization = 'Doppler spectrum';
% Transmit 5000 frames to display Doppler spectrum
numFrames = 5000;
for i = 1:numFrames
msg = randi([0 1], bitsPerFrame, 1);
modSignal = qpskMod(msg);
rayChan(modSignal);
end
% Configure Narrowband (Frequency-Flat) Fading
release(rayChan); % Release channel before changing properties
rayChan.Visualization = 'Impulse and frequency responses';
rayChan.SampleRate = sampleRate20kHz;
rayChan.SamplesToDisplay = '25%'; % Display 1 of every 4 samples
% Transmit two frames with frequency-flat fading
for i = 1:numFrames
msg = randi([0 1], bitsPerFrame, 1);
modSignal = qpskMod(msg);
rayChan(modSignal);
end
% Configure Single-Path Fading (Zero Delay)
release(rayChan); % Release channel before changing properties
rayChan.PathDelays = 0;
rayChan.AveragePathGains = 0;
% Transmit two frames with single-path fading
for i = 1:numFrames
msg = randi([0 1], bitsPerFrame, 1);
modSignal = qpskMod(msg);
rayChan(modSignal);
end
% Disable Visualization
release(rayChan);
rayChan.Visualization = 'Off';
release(ricChan);
ricChan.Visualization = 'Off';
% Match Sample Rate and Delays between Rayleigh and Rician Channels
ricChan.SampleRate = rayChan.SampleRate;
ricChan.PathDelays = rayChan.PathDelays;
ricChan.AveragePathGains = rayChan.AveragePathGains;
% Configure Time Scope for Path Gain Visualization
gainScope = dsp.TimeScope( ...
'SampleRate', rayChan.SampleRate, ...
'TimeSpan', bitsPerFrame / (2 * rayChan.SampleRate), ...
'Name', 'Multipath Gain', ...
'ShowGrid', true, ...
'YLimits', [-40 10], ...
'YLabel', 'Gain (dB)');
% Compare Path Gains from Rayleigh and Rician Channels
msg = randi([0 1], bitsPerFrame, 1);
modSignal = qpskMod(msg);
[~, rayPathGain] = rayChan(modSignal);
[~, ricPathGain] = ricChan(modSignal);
% Display Path Gains on Time Scope
gainScope(10 * log10(abs([rayPathGain, ricPathGain]).^2));
EXP NO - 12
PROGRAM : PULSE SHAPING AND RADIOS (inu mudiyum)
M = 16; % Modulation order
k = log2(M); % Number of bits per symbol
numBits = 3e5; % Number of bits to process
sps = 4; % Number of samples per symbol (oversampling factor)
filtlen = 10; % Filter length in symbols
rolloff = 0.25; % Filter rolloff factor
rrcFilter = rcosdesign(rolloff, filtlen, sps);
fvtool(rrcFilter, 'Analysis', 'Impulse');
rng default; % Use default random number generator
dataIn = randi([0 1], numBits, 1); % Generate vector of binary data
dataInMatrix = reshape(dataIn, length(dataIn) / k, k); % Reshape data into binary 4-tuples
dataSymbolsIn = bi2de(dataInMatrix); % Convert to integers
dataMod = qammod(dataSymbolsIn, M);
txFiltSignal = upfirdn(dataMod, rrcFilter, sps, 1);
EbNo = 10;
snr = EbNo + 10 * log10(k) - 10 * log10(sps);
rxSignal = awgn(txFiltSignal, snr, 'measured');
rxFiltSignal = upfirdn(rxSignal, rrcFilter, 1, sps); % Downsample and filter
rxFiltSignal = rxFiltSignal(filtlen + 1:end - filtlen); % Account for delay
% Bit error rate calculation
dataSymbolsOut = qamdemod(rxFiltSignal, M);
dataOutMatrix = de2bi(dataSymbolsOut, k);
dataOut = dataOutMatrix(:); % Return data in column vector
[numErrors, ber] = biterr(dataIn, dataOut);
fprintf('\nFor an EbNo setting of %3.1f dB, the bit error rate is %5.2e, based on %d errors.\n', ...
EbNo, ber, numErrors);
% Visualize Filter Effects
EbNo = 20;
snr = EbNo + 10 * log10(k) - 10 * log10(sps);
rxSignal = awgn(txFiltSignal, snr, 'measured');
rxFiltSignal = upfirdn(rxSignal, rrcFilter, 1, sps); % Downsample and filter
rxFiltSignal = rxFiltSignal(filtlen + 1:end - filtlen); % Account for delay
eyediagram(txFiltSignal(1:2000), sps * 2);
eyediagram(rxSignal(1:2000), sps * 2);
eyediagram(rxFiltSignal(1:2000), 2);
scatplot = scatterplot(sqrt(sps) * rxSignal(1:sps * 5e3), sps, 0, 'g.');
hold on;
scatterplot(rxFiltSignal(1:5e3), 1, 0, 'kx', scatplot);
title('Received Signal, Before and After Filtering');
legend('Before Filtering', 'After Filtering');
axis([-5 5 -5 5]); % Set axis ranges
hold off;
EXP NO - 13
Program : OFDM SIGNAL TRANSMISSION AND RECEPTION USING SOFTWARE
DEFINED RADIO
%===================================================================
=====
% The mfile investigates the generation, transmission and reception of
% the OFDM signal without channel noise or HPA effect
%===================================================================
=====
clear all;
clc;
close all;
% A: Setting Parameters
M = 4; % QPSK signal constellation
no_of_data_points = 64; % Number of data points
block_size = 8; % Size of each OFDM block
cp_len = ceil(0.1 * block_size); % Length of cyclic prefix
no_of_ifft_points = block_size; % Points for the IFFT
no_of_fft_points = block_size; % Points for the FFT
% B: % +++++ TRANSMITTER +++++
% 1. Generate 1 x 64 vector of data points (phase representations)
data_source = randsrc(1, no_of_data_points, 0:M-1);
figure(1);
stem(data_source);
grid on;
xlabel('Data Points');
ylabel('Transmitted Data Phase Representation');
title('Transmitted Data "O"');
% 2. Perform QPSK modulation
qpsk_modulated_data = pskmod(data_source, M);
figure(2);
scatterplot(qpsk_modulated_data);
title('QPSK Modulated Transmitted Data');
% 3. Do IFFT on each block
% Reshape data into a matrix where each column represents a pre-OFDM block (without cyclic
prefixing)
num_cols = length(qpsk_modulated_data) / block_size;
data_matrix = reshape(qpsk_modulated_data, block_size, num_cols);
% Create empty matrix to store IFFT'd data
cp_start = block_size - cp_len;
cp_end = block_size;
% Operate columnwise & do CP
for i = 1:num_cols
ifft_data_matrix(:, i) = ifft(data_matrix(:, i), no_of_ifft_points);
% Compute and append Cyclic Prefix
for j = 1:cp_len
actual_cp(j, i) = ifft_data_matrix(j + cp_start, i);
end
% Append the CP to create the actual OFDM block
ifft_data(:, i) = vertcat(actual_cp(:, i), ifft_data_matrix(:, i));
end
% 4. Convert to serial stream for transmission
[rows_ifft_data, cols_ifft_data] = size(ifft_data);
len_ofdm_data = rows_ifft_data * cols_ifft_data;
% Actual OFDM signal to be transmitted
ofdm_signal = reshape(ifft_data, 1, len_ofdm_data);
figure(3);
plot(real(ofdm_signal));
xlabel('Time');
ylabel('Amplitude');
title('OFDM Signal');
grid on;
% E: % +++++ RECEIVER +++++
% 1. Pass the OFDM signal through the channel
recvd_signal = ofdm_signal; % Here you could implement a channel model
% 4. Convert Data back to "parallel" form to perform FFT
recvd_signal_matrix = reshape(recvd_signal, rows_ifft_data, cols_ifft_data);
% 5. Remove CP
recvd_signal_matrix(1:cp_len, :) = []; % Remove the cyclic prefix
% 6. Perform FFT
for i = 1:cols_ifft_data
fft_data_matrix(:, i) = fft(recvd_signal_matrix(:, i), no_of_fft_points);
end
% 7. Convert to serial stream
recvd_serial_data = reshape(fft_data_matrix, 1, (block_size * num_cols));
% 8. Demodulate the data
qpsk_demodulated_data = pskdemod(recvd_serial_data, M);
% Plotting the received data
figure(4);
scatterplot(qpsk_demodulated_data);
title('QPSK Modulated Received Data');
figure(5);
stem(qpsk_demodulated_data, 'rx');
grid on;
xlabel('Data Points');
ylabel('Received Data Phase Representation');
title('Received Data "X"');
EXP NO - 11
Program:
SIMULATION OF CHANNEL ESTIMATION, SYNCHRONIZATION AND EQUALIZATION
TECHNIQUES
% LTE Parameters
enb.NDLRB = 15; % Number of resource blocks
enb.CellRefP = 1; % One transmit antenna port
enb.NCellID = 10; % Cell ID
enb.CyclicPrefix = 'Normal'; % Normal cyclic prefix
enb.DuplexMode = 'FDD'; % FDD
SNRdB = 22; % Desired SNR in dB
SNR = 10^(SNRdB/20); % Linear SNR
rng('default'); % Configure random number generators
cfg.Seed = 1; % Channel seed
cfg.NRxAnts = 1; % 1 receive antenna
cfg.DelayProfile = 'EVA'; % EVA delay spread
cfg.DopplerFreq = 120; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.InitTime = 0; % Initialize at time zero
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
cfg.InitPhase = 'Random'; % Random initial phases
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
% Channel Estimation Configuration
cec.PilotAverage = 'UserDefined'; % Pilot averaging method
cec.FreqWindow = 9; % Frequency averaging window in REs
cec.TimeWindow = 9; % Time averaging window in REs
cec.InterpType = 'Cubic'; % Cubic interpolation
cec.InterpWinSize = 3; % Interpolate up to 3 subframes simultaneously
cec.InterpWindow = 'Centred'; % Interpolation windowing method
% Resource Grid Size
gridsize = lteDLResourceGridSize(enb);
K = gridsize(1); % Number of subcarriers
L = gridsize(2); % Number of OFDM symbols in one subframe
P = gridsize(3); % Number of transmit antenna ports
% Initialize Variables
txGrid = []; % Transmit Resource Grid
% Number of bits needed
numberOfBits = K * L * P * 2; % Number of bits (size of resource grid * bits per symbol)
% Create random bit stream
inputBits = randi([0 1], numberOfBits, 1);
% Modulate input bits
inputSym = lteSymbolModulate(inputBits, 'QPSK');
% Generate Subframes
for sf = 0:10
% Set subframe number
enb.NSubframe = mod(sf, 10);
% Generate empty subframe
subframe = lteDLResourceGrid(enb);
% Map input symbols to grid
subframe(:) = inputSym;
% Generate synchronizing signals
pssSym = ltePSS(enb);
sssSym = lteSSS(enb);
pssInd = ltePSSIndices(enb);
sssInd = lteSSSIndices(enb);
% Map synchronizing signals to the grid
subframe(pssInd) = pssSym;
subframe(sssInd) = sssSym;
% Generate cell specific reference signal symbols and indices
cellRsSym = lteCellRS(enb);
cellRsInd = lteCellRSIndices(enb);
% Map cell specific reference signal to grid
subframe(cellRsInd) = cellRsSym;
% Append subframe to grid to be transmitted
txGrid = [txGrid subframe]; %#ok
end
% OFDM Modulation
[txWaveform, info] = lteOFDMModulate(enb, txGrid);
txGrid = txGrid(:, 1:140);
cfg.SamplingRate = info.SamplingRate;
% Pass data through the fading channel model
rxWaveform = lteFadingChannel(cfg, txWaveform);
% Calculate noise gain
N0 = 1 / (sqrt(2.0 * enb.CellRefP * double(info.Nfft)) * SNR);
% Create additive white Gaussian noise
noise = N0 * complex(randn(size(rxWaveform)), randn(size(rxWaveform)));
% Add noise to the received time domain waveform
rxWaveform = rxWaveform + noise;
% Frame Offset Correction
offset = lteDLFrameOffset(enb, rxWaveform);
rxWaveform = rxWaveform(1 + offset:end, :);
rxGrid = lteOFDMDemodulate(enb, rxWaveform);
enb.NSubframe = 0;
% Channel Estimation
[estChannel, noiseEst] = lteDLChannelEstimate(enb, cec, rxGrid);
eqGrid = lteEqualizeMMSE(rxGrid, estChannel, noiseEst);
% Calculate error between transmitted and equalized grid
eqError = txGrid - eqGrid;
rxError = txGrid - rxGrid;
% Compute EVM across all input values
EVM = comm.EVM;
EVM.AveragingDimensions = [1 2];
preEqualisedEVM = EVM(txGrid, rxGrid);
fprintf('Percentage RMS EVM of Pre-Equalized signal: %0.3f%%\n', preEqualisedEVM);
% EVM of post-equalized receive signal
postEqualisedEVM = EVM(txGrid, eqGrid);
fprintf('Percentage RMS EVM of Post-Equalized signal: %0.3f%%\n', postEqualisedEVM);
% Plot the received and equalized resource grids
figure;
subplot(1, 2, 1);
imagesc(abs(rxGrid));
title('Received Grid');
xlabel('Subcarriers');
ylabel('OFDM Symbols');
colorbar;
subplot(1, 2, 2);
imagesc(abs(eqGrid));
title('Equalized Grid');
xlabel('Subcarriers');
ylabel('OFDM Symbols');
colorbar;