- https://www.mathworks.com/help/comm/ref/convertsnr.html
- https://www.mathworks.com/help/comm/ref/biterr.html
Problem with OFDM transmit-receive code
3 views (last 30 days)
Show older comments
Hello, I have a problem with my code. It's a basic ofdm transmitter and receiver implementation making use of BPSK. But when I increase the bps to 4 (i.e 16 QAM) and above, I don't get the desired BER curve. I need help with this Please.
% Parameters
bps = 1; % Bits per symbol (1 for BPSK)
M = 2^bps; % Modulation order
totalBandwidth = 20e6; % Total bandwidth (Hz)
subcarrierSpacing = 15e3; % Subcarrier spacing (Hz)
nFFT = ceil(totalBandwidth / subcarrierSpacing); % Number of FFT bins
EbNoVec = 1:1:10; % Eb/No values (dB)
% Noise power values
noisePower_dBW = -120; % AWGN noise power in dBW
noisePower_W = 10^(noisePower_dBW / 10); % Convert noise power to watts
impulseNoisePower_dBW = -113; % Impulse noise power in dBW
impulseNoisePower_W = 10^(impulseNoisePower_dBW / 10); % Convert impulse noise power to watts
% Initialize BER vectors
berEstAWGN = zeros(size(EbNoVec)); % BER for AWGN only
berEstImp = zeros(size(EbNoVec)); % BER for AWGN + impulse noise
snr_dB = convertSNR(EbNoVec, "ebno", "snr", BitsPerSymbol=bps); % Convert Eb/No to SNR
% Loop over SNR values
for n = 1:length(EbNoVec)
%snr_dB = EbNoVec(n) + 10*log10(bps); % Convert Eb/No to SNR
% Initialize error and bit counters
numErrsAWGN = 0;
numErrsImp = 0;
numBits = 0;
while numErrsAWGN < 200 && numBits < 1e6
% Generate random symbols and bits
txSymbols = randi([0 M-1], nFFT, 1);
txBits = int2bit(txSymbols, bps);
% OFDM Modulation
txGrid = qammod(txSymbols, M, 'UnitAveragePower', true);
txOut = ifft(txGrid, nFFT);
% Calculate signal power
signalPower_dBW = snr_dB(n) + noisePower_dBW;
signalPower_W = 10^(signalPower_dBW / 10);
scalingFactor = sqrt(signalPower_W / mean(abs(txOut).^2));
txOutScaled = txOut * scalingFactor;
% AWGN
noiseSignal_notscaled = randn(size(txOutScaled)) + 1j * randn(size(txOutScaled));
noiseAWGN = sqrt(noisePower_W / 2) * noiseSignal_notscaled;
% Impulse noise (bursty)
impulseNoise = zeros(size(txOutScaled)); % Initialize as zeros
burstPositions = rand(size(txOutScaled)) < 1; % 5% of the time noise bursts occur
impulseNoise(burstPositions) = sqrt(impulseNoisePower_W / 2) * ...
(randn(sum(burstPositions), 1) + 1j * randn(sum(burstPositions), 1));
% Received signal with AWGN only
rxInAWGN = txOutScaled + noiseAWGN;
% Received signal with AWGN + Impulse noise
rxInImp = txOutScaled + noiseAWGN + impulseNoise;
% OFDM Demodulation
rxGridAWGN = fft(rxInAWGN, nFFT);
rxGridImp = fft(rxInImp, nFFT);
% Demodulate symbols
rxSymbolsAWGN = qamdemod(rxGridAWGN, M, 'UnitAveragePower', true);
rxSymbolsImp = qamdemod(rxGridImp, M, 'UnitAveragePower', true);
% Convert symbols to bits
rxBitsAWGN = int2bit(rxSymbolsAWGN, bps);
rxBitsImp = int2bit(rxSymbolsImp, bps);
% Count bit errors
[bitErrorsAWGN, ~] = biterr(txBits, rxBitsAWGN);
[bitErrorsImp, ~] = biterr(txBits, rxBitsImp);
% Update error counters and transmitted bits
numErrsAWGN = numErrsAWGN + bitErrorsAWGN;
numErrsImp = numErrsImp + bitErrorsImp;
numBits = numBits + nFFT * bps;
end
% Calculate BER
berEstAWGN(n) = numErrsAWGN / numBits;
berEstImp(n) = numErrsImp / numBits;
end
% Plot BER results
figure;
semilogy(EbNoVec, berEstAWGN, 'b-o', 'LineWidth', 2); % AWGN only
hold on;
semilogy(EbNoVec, berEstImp, 'r--o', 'LineWidth', 2); % AWGN + Impulse noise
grid on;
title('OFDM BER for BPSK with AWGN and Impulse Noise');
xlabel('Eb/No (dB)');
ylabel('Bit Error Rate (BER)');
legend('AWGN Only', 'AWGN + Impulse Noise');
hold off;
0 Comments
Answers (1)
Suraj Kumar
on 1 Oct 2024
Hi John,
Based on my understanding, you are working on transitioning your OFDM system from BPSK to 16-QAM modulation and are facing some challenges.
To resolve the issues, you can refer the following steps:
1. Ensure the modulation order M is calculated based on the bps, i.e. for 16-QAM, bps = 4 and hence M=16.
bps = 4; % Bits per symbol (4 for 16-QAM)
M = 2^bps; % Modulation order
2. Model the noise accurately implementing AWGN and impulse noise, ensuring the noise is bursty.
noiseAWGN = sqrt(noisePower_W / 2) * (randn(size(txOutScaled)) + 1j * randn(size(txOutScaled)));
impulseNoise = zeros(size(txOutScaled));
burstPositions = rand(size(txOutScaled)) < 0.05;
impulseNoise(burstPositions) = sqrt(impulseNoisePower_W / 2) * ...
(randn(sum(burstPositions), 1) + 1j * randn(sum(burstPositions), 1));
rxInAWGN = txOutScaled + noiseAWGN;
rxInImp = txOutScaled + noiseAWGN + impulseNoise;
3. Use the ‘biterr’ function in MATLAB to compute BER and plot the results.
[bitErrorsAWGN, ~] = biterr(txBits, rxBitsAWGN);
[bitErrorsImp, ~] = biterr(txBits, rxBitsImp);
numErrsAWGN = numErrsAWGN + bitErrorsAWGN;
numErrsImp = numErrsImp + bitErrorsImp;
You may refer to the output below for a clearer understanding:
To know more about the ‘convertSNR’ or ‘biterr’ function in MATLAB, kindly go through the following documentations:
Happy Coding!
See Also
Categories
Find more on QAM in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!