16-QAM over AWGN Channel

30 次查看(过去 30 天)
A. MAR.
A. MAR. 2020-8-4
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

回答(1 个)

Shashi Kiran
Shashi Kiran 2024-9-27
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.

类别

Help CenterFile Exchange 中查找有关 Modulation 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by