One of the best-performing modulation techniques is QAM [↗]. Here, we modulate the symbols by varying the carrier signal's amplitude and phase in response to the variation in the message signal (or voltage variation). So, we may say that QAM is a combination of phase and amplitude modulation. Additionally, it performs better than ASK or PSK [↗]. In fact, any constellation for any type of modulation, signal set (or, symbols) is structured in a way that prevents them from interacting further by being distinct by phase, amplitude, or frequency.
MATLAB Script
% This is an example of 4-QAM. Here constellation size is 4
% or total number of symbols/signals is 4
% We need 2 bits once to represent four constellation points
% QAM modulation is the combination of Amplitude modulation plus
% Phase Modulation. We map the decimal value of the input symbols, i.e.,
% 00, 01, 10, 11 to 1 + 1i, -1 + 1i, 1 - 1i, and -1 - 1i, respectively.
clc;clear all;close all;
M = 4; % Number of levels after quantization / size of signal constellation
k = log2(M); % Number of bits per symbol
rng(10) %assaining the value of seed integer
N =10000; % Number of bits to process
InputBits = randi([0 1],1,N); % Generating randon bits
InputSymbol_matrix = reshape(InputBits,length(InputBits)/k,k); % Reshape data into binary k-tuples, k = log2(M)
InputSymbols_decimal = bi2de(InputSymbol_matrix); % Convert binary to decimal
for n= 1:N/k
if InputSymbols_decimal(n)==0
QAM(n)= complex(1,1);
elseif InputSymbols_decimal(n)==1
QAM(n)= complex(-1,1);
elseif InputSymbols_decimal(n)==2
QAM(n)= complex(1,-1);
else
QAM(n)= complex(-1,-1);
end
end
%Transmission of 4QAM data over AWGN channel
snrdB = 10;
Y=awgn(QAM,snrdB); %received signal
%Threshold Detection
for n= 1:N/k
if (real(Y(n))>0 && imag(Y(n))>0)
Z(n)=complex(1,1);
elseif (real(Y(n))>0 && imag(Y(n))<0)
Z(n)=complex(1,-1);
elseif (real(Y(n))<0 && imag(Y(n))>0)
Z(n)=complex(-1,1);
else
Z(n)=complex(-1,-1);
end
end
figure(1)
scatter(real(QAM), imag(QAM))
xlim([-3, 3]);
ylim([-3, 3]);
legend('Transmitted Symbols')
figure(2)
scatter(real(Y), imag(Y))
xlim([-3, 3]);
ylim([-3, 3]);
legend('Received Symbols')
Output
Another MATLAB Code
clc;
clear;
close all;
% Define parameters
M = 16; % Modulation order for 16-QAM
numSymbols = 10000; % Number of symbols to modulate
% Generate random data
data = randi([0 M-1], numSymbols, 1); % Ensure data is a column vector
% Modulate the data using 16-QAM
modData = qammod_custom(data, M);
snrdB = 15;
Y = awgn(modData,snrdB); %received signal
% Plot the constellation of the modulated signal
figure;
subplot(2,1,1);
scatter(real(modData), imag(modData), 'o');
grid on;
xlabel('In-phase');
ylabel('Quadrature');
title('Constellation Diagram of Modulated Signal (16-QAM)');
axis([-1.5 1.5 -1.5 1.5]); % Set axis limits for better visualization
subplot(2,1,2);
scatter(real(Y), imag(Y), 'o');
grid on;
xlabel('In-phase');
ylabel('Quadrature');
title('Constellation Diagram of Noisy Received Signal before demodulation');
axis([-1.5 1.5 -1.5 1.5]); % Set axis limits for better visualization
% Demodulate the received signal
receivedData = qamdemod_custom(modData, M);
% Ensure receivedData is a column vector for comparison
receivedData = receivedData(:);
% Custom 16-QAM Modulation Function
function modData = qammod_custom(data, M)
% QAMMOD_CUSTOM Modulate data using 16-QAM
% data - Column vector of integers (each element is between 0 and M-1)
% M - Modulation order (should be 16 for 16-QAM)
% Check if M is 16
if M ~= 16
error('This function is designed for 16-QAM modulation.');
end
% Define the 16-QAM constellation
constellation = [-3-3i, -3-1i, -1-3i, -1-1i, ...
-3+3i, -3+1i, -1+3i, -1+1i, ...
+3-3i, +3-1i, +1-3i, +1-1i, ...
+3+3i, +3+1i, +1+3i, +1+1i];
% Normalize constellation
constellation = constellation / sqrt(mean(abs(constellation).^2)); % Scale to unit average power
% Map data to constellation points
modData = constellation(data + 1);
end
% Custom 16-QAM Demodulation Function
function demodData = qamdemod_custom(modData, M)
% QAMDEMOD_CUSTOM Demodulate data using 16-QAM
% modData - Column vector of complex numbers (modulated symbols)
% M - Modulation order (should be 16 for 16-QAM)
% Check if M is 16
if M ~= 16
error('This function is designed for 16-QAM demodulation.');
end
% Define the 16-QAM constellation
constellation = [-3-3i, -3-1i, -1-3i, -1-1i, ...
-3+3i, -3+1i, -1+3i, -1+1i, ...
+3-3i, +3-1i, +1-3i, +1-1i, ...
+3+3i, +3+1i, +1+3i, +1+1i];
% Normalize constellation
constellation = constellation / sqrt(mean(abs(constellation).^2)); % Scale to unit average power
% Ensure modData is a column vector
modData = modData(:);
% Compute the distances from each modData point to all constellation points
numSymbols = length(modData);
numConstellations = length(constellation);
distances = zeros(numSymbols, numConstellations);
for k = 1:numConstellations
distances(:, k) = abs(modData - constellation(k)).^2;
end
% Find the closest constellation point for each modData point
[~, demodData] = min(distances, [], 2);
% Convert to zero-based index
demodData = demodData - 1;
end
Output
Copy the MATLAB Code above from here
MATLAB code for M-ary QAM (e.g., 4, 8, 16, 32, 64, 128, 256)
% M-ary QAM Modulation and Demodulation
clc;
clear;
close all;
% Parameters
M = 32; % Order of QAM (M-QAM)
N = 1000; % Number of symbols
SNR = 10; % Signal-to-Noise Ratio in dB
% Generate random data symbols
dataSymbols = randi([0 M-1], N, 1);
% Modulate using M-QAM
txSignal = qammod(dataSymbols, M);
% Add AWGN noise
rxSignal = awgn(txSignal, SNR, 'measured');
% Demodulate
demodulatedSymbols = qamdemod(rxSignal, M);
% Calculate symbol error rate
symbolErrors = sum(dataSymbols ~= demodulatedSymbols);
SER = symbolErrors / N;
% Display results
disp(['Symbol Error Rate (SER): ', num2str(SER)]);
% Plot constellation diagrams
figure;
subplot(2, 1, 1);
plot(real(txSignal), imag(txSignal), 'o');
grid on;
title('Transmitted Signal Constellation');
xlabel('In-Phase');
ylabel('Quadrature');
subplot(2, 1, 2);
plot(real(rxSignal), imag(rxSignal), 'o');
grid on;
title('Received Signal Constellation');
xlabel('In-Phase');
ylabel('Quadrature');