16-QAM over AWGN Channel

34 views (last 30 days)
A. MAR.
A. MAR. on 4 Aug 2020
Answered: Shashi Kiran on 27 Sep 2024
Hello,
I want to simulate 16-QAM over AWGN Channel. The Emprical and Theoretical result are different.
Maybe I made a mistake in SNR and Eb/No.
How I can solve this problem?
clear all; close all; clc
% Variables
c = [-3-3i -3-1i -3+3i -3+1i -1-3i -1-1i -1+3i -1+1i 3-3i 3-1i 3+3i 3+1i 1-3i 1-1i 1+3i 1+1i];
M = length(c); % Size of modulation constellation
k = log2(M); % Number of bits per symbol
numBits = 10000; % Each trial uses 10000 bits.
SNR = 0:1:20; % Range of SNR values, in dB.
numSNR = length(SNR);
berVec = zeros(3, numSNR); % Preallocate a vector for BER results
%--------------------------------------------------------------------------
mod = comm.GeneralQAMModulator(c);
demod = comm.GeneralQAMDemodulator(c);
tx = randi([0 M-1],numBits,1);
modSignal = mod(tx);
% Add white Gaussian noise to the modulated signal by passing the signal through an AWGN channel.
awgnChan = comm.AWGNChannel('NoiseMethod', 'Signal to noise ratio (SNR)');
errorCalc = comm.ErrorRate;
for n = 1:numSNR
reset(errorCalc)
awgnChan.SNR = SNR(n);
noisySignal = awgnChan(modSignal); % Add Gaussian noise
rx = demod(noisySignal);
berVec(:,n) = errorCalc(tx,rx); % Compute error rate.
end
BER = berVec(1,:);
[BERtheory, SERtheory] = berawgn(SNR,'qam',M);
semilogy(SNR,BERtheory,'b-',SNR,BER,'r*');
legend('Theoretical BER','Empirical BER');
xlabel('SNR (dB)'); ylabel('BER');
title('16-QAM over AWGN Channel');
Code Result

Answers (1)

Shashi Kiran
Shashi Kiran on 27 Sep 2024
I understand that you are trying to simulate 16-QAM over an AWGN channel and are having trouble aligning the theoretical and empirical curves.
Here are some suggestions and improvements after reviewing your code:
  • Normalization of the constellation c: The constellation c is normalized to have an average power of 1, ensuring consistent power assumptions for both theoretical and empirical BER calculations.
clear ; close all; clc
c = [-3-3i -3-1i -3+3i -3+1i -1-3i -1-1i -1+3i -1+1i 3-3i 3-1i 3+3i 3+1i 1-3i 1-1i 1+3i 1+1i];
c = c / sqrt(mean(abs(c).^2));
  • Bit Generation and Symbol Mapping: The code generates symbols directly, causing inconsistencies in bit-level BER calculations. We can update this by generating random bits and mapping them to symbols, ensuring accurate bit-level processing and BER computation.
M = length(c); % Size of modulation constellation
k = log2(M); % Number of bits per symbol
numBits = 10000; % Each trial uses 10000 bits.
numSymbols = numBits / k; % Number of symbols
SNR = 0:1:20; % Range of SNR values, in dB.
numSNR = length(SNR);
berVec = zeros(3, numSNR); % Preallocate a vector for BER results
mod = comm.GeneralQAMModulator(c);
demod = comm.GeneralQAMDemodulator(c);
txBits = randi([0 1], numBits, 1); % Random bit sequence
txSymbols = bi2de(reshape(txBits, k, numSymbols).', 'left-msb'); % Map bits to symbols
modSignal = mod(txSymbols); % Modulate symbols
  • SNR Adjustment: The SNR is set per symbol, causing a mismatch with the bit-based SNR expected by `berawgn`, leading to incorrect BER comparisons. By adjusting the SNR with , the SNR is converted to per bit, aligning empirical BER with theoretical calculations.
  • Demodulation and Bit Recovery: Symbol error rate (SER) can be misleading for bit-level performance analysis. To improve accuracy, it's better to compute bit error rate (BER) by converting received symbols back into bits, providing a more precise and detailed measure, especially for multi-level modulation schemes like 16-QAM.
% Add white Gaussian noise to the modulated signal by passing the signal through an AWGN channel.
awgnChan = comm.AWGNChannel('NoiseMethod', 'Signal to noise ratio (SNR)');
errorCalc = comm.ErrorRate;
for n = 1:numSNR
reset(errorCalc)
awgnChan.SNR = SNR(n) + 10*log10(k); % Adjust SNR for bits per symbol
noisySignal = awgnChan(modSignal); % Add Gaussian noise
rxSymbols = demod(noisySignal); % Demodulate noisy signal
rxBits = de2bi(rxSymbols, k, 'left-msb'); % Convert received symbols to bits
rxBits = rxBits.'; % Reshape for error rate calculation
rxBits = rxBits(:);
berVec(:,n) = errorCalc(txBits, rxBits); % Compute BER
end
BER = berVec(1,:);
[BERtheory, ~] = berawgn(SNR,'qam',M);
semilogy(SNR, BERtheory, 'b-', SNR, BER, 'r*');
legend('Theoretical BER', 'Empirical BER');
xlabel('SNR (dB)'); ylabel('BER');
title('16-QAM over AWGN Channel');
grid on;
Additionally,
Instead of using 'comm.GeneralQAMModulator` and `comm.GeneralQAMDemodulator`, you can update the code by using `qammod` and `qamdemod`.
Please refer to the following documentations for more details about the functions:
Hope this helps resolve your query.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!