DIGITAL
COMMUNICATION
LAB 5
Section : EE-20B
NAME ROLL NO
M. Talha Zulfiqar 210401005
Raees Abdullah 210401019
LAB TASKS:
QPSK Modulation
1. Initialize variables
2. Generate binary message and select even and odd bits for I and Q channels
3. Generate QPSK modulated signal and plot the time domain QPSK
4. Plot In-phase, Q-phase and QPSK signal
QPSK Demodulation
1. Add AWGN to the QPSK signal
2. Multiply the QPSK signal with the two basis functions to receive I and Q channels
3. Apply correlation receiver to each of the I and Q channels using the corresponding basis function
(ideal template signal, as done for BPSK).
4. Make a decision by comparing it with a threshold for each of the I and Q channels. This will give a
pair of bits.
5. Create a constellation diagram for 5dB SNR.
6. Compare the received binary message with the original message and compute probability of bit error
(PB).
7. Plot the SNR vs PB curve for several values of SNR, from 10dB to -15dB with a step of 5dB (-15 : 5 :
10).
8. Repeat the modulation process using Gray codes, perform demodulation. Compute SNR vs PB
curve (as in step 7).
9. Compare the curves computed in step 7 and 8 and comment on the difference.
CODE:
N = 50; % Number of bits
fs = 100; % Sampling frequency
fc = 10; % Carrier frequency
t = (0:N-1)/fs; % Time vector
data = randi([0 1], 1, N); % Random binary data
I_bits = data(1:2:end); % In-phase channel (even bits)
Q_bits = data(2:2:end); % Quadrature channel (odd bits)
I = 2*I_bits - 1; % Map to +1 or -1
Q = 2*Q_bits - 1;
% Generate time vector per symbol
ts = 1/fs;
n = 0:ts:1-ts;
I_signal = kron(I, cos(2*pi*fc*n));
Q_signal = kron(Q, sin(2*pi*fc*n));
qpsk_signal = I_signal + Q_signal;
figure
subplot(3,1,1);
plot(I_signal);
title('In-phase Signal');
subplot(3,1,2);
plot(Q_signal);
title('Quadrature Signal');
subplot(3,1,3);
plot(qpsk_signal);
title('QPSK Signal');
snr_db = 5;
qpsk_noisy = awgn(qpsk_signal, snr_db, 'measured');
% 2. Multiply with Basis Functions
phi_I = sqrt(2/ts)*cos(2*pi*fc*n);
phi_Q = sqrt(2/ts)*sin(2*pi*fc*n);
I_rec = qpsk_noisy .* kron(ones(1, length(I)), phi_I);
Q_rec = qpsk_noisy .* kron(ones(1, length(Q)), phi_Q);
% 3. Correlation Receiver
I_reshaped = reshape(I_rec, length(n), []);
Q_reshaped = reshape(Q_rec, length(n), []);
I_integrated = sum(I_reshaped); % Match filter output per symbol
Q_integrated = sum(Q_reshaped);
% 4. Threshold Decision
I_detected = I_integrated > 0;
Q_detected = Q_integrated > 0;
received_bits = zeros(1, N);
received_bits(1:2:end) = I_detected;
received_bits(2:2:end) = Q_detected;
% 5. Constellation Diagram
figure;
scatter(I_integrated, Q_integrated, 'filled');
title('Constellation at 5 dB SNR');
xlabel('In-phase'); ylabel('Quadrature'); grid on;
% 6. Compute Bit Error Probability
errors = sum(data ~= received_bits);
Pb = errors / N;
% 7. Plot Time-Domain Signals
figure;
subplot(4,1,1);
plot(qpsk_signal);
title('Original QPSK Signal'); xlabel('Sample'); ylabel('Amplitude');
subplot(4,1,2);
plot(qpsk_noisy);
title('QPSK Signal with Noise (5 dB)'); xlabel('Sample'); ylabel('Amplitude');
subplot(4,1,3);
stairs(data, 'LineWidth', 1.5); ylim([-0.5 1.5]);
title('Original Bitstream'); xlabel('Bit Index'); ylabel('Bit');
subplot(4,1,4);
stairs(received_bits, 'r', 'LineWidth', 1.5); ylim([-0.5 1.5]);
title('Demodulated Bitstream'); xlabel('Bit Index'); ylabel('Bit');
snr_range = -15:5:10;
Pb_vals = zeros(size(snr_range));
for i = 1:length(snr_range)
% 1. Add AWGN
qpsk_noisy = awgn(qpsk_signal, snr_range(i), 'measured');
% 2. Multiply with Basis Functions
I_rec = qpsk_noisy .* kron(ones(1, length(I)), cos(2*pi*fc*n));
Q_rec = qpsk_noisy .* kron(ones(1, length(Q)), sin(2*pi*fc*n));
% 3. Reshape for correlation receiver
I_reshaped = reshape(I_rec, length(n), []);
Q_reshaped = reshape(Q_rec, length(n), []);
% 4. Integrate over symbol period (Matched filter output)
I_integrated = sum(I_reshaped);
Q_integrated = sum(Q_reshaped);
% 5. Threshold Detection
I_detected = I_integrated > 0;
Q_detected = Q_integrated > 0;
% 6. Reconstruct Received Bitstream
received_bits = zeros(1, N);
received_bits(1:2:end) = I_detected;
received_bits(2:2:end) = Q_detected;
% 7. Compute BER
Pb_vals(i) = sum(data ~= received_bits) / N;
end
% Plot BER vs SNR
figure;
semilogy(snr_range, Pb_vals, '-o', 'LineWidth', 2);
xlabel('SNR (dB)');
ylabel('Bit Error Probability (Pb)');
title('QPSK BER vs SNR (Standard Mapping)');
grid on;
HOME TASK:
clc; clear; close all;
% Parameters
N = 10000; % Number of bits
fs = 100; % Sampling frequency
fc = 10; % Carrier frequency
ts = 1/fs; % Sampling interval
t = (0:N-1)/fs; % Time vector
n = 0:ts:1-ts; % Symbol time vector
snr_range = -15:5:10; % SNR values
Pb_vals_std = zeros(size(snr_range));
Pb_vals_gray = zeros(size(snr_range));
% Generate random data
data = randi([0 1], 1, N);
%% ---- STANDARD QPSK ---- %%
I_bits = data(1:2:end);
Q_bits = data(2:2:end);
I_std = 2*I_bits - 1;
Q_std = 2*Q_bits - 1;
I_signal_std = kron(I_std, cos(2*pi*fc*n));
Q_signal_std = kron(Q_std, sin(2*pi*fc*n));
qpsk_signal_std = I_signal_std + Q_signal_std;
% BER vs SNR for Standard QPSK
for i = 1:length(snr_range)
qpsk_noisy = awgn(qpsk_signal_std, snr_range(i), 'measured');
I_rec = qpsk_noisy .* kron(ones(1,length(I_std)), cos(2*pi*fc*n));
Q_rec = qpsk_noisy .* kron(ones(1,length(Q_std)), sin(2*pi*fc*n));
I_reshaped = reshape(I_rec, length(n), []);
Q_reshaped = reshape(Q_rec, length(n), []);
I_integrated = sum(I_reshaped);
Q_integrated = sum(Q_reshaped);
I_detected = I_integrated > 0;
Q_detected = Q_integrated > 0;
received_bits = zeros(1, N);
received_bits(1:2:end) = I_detected;
received_bits(2:2:end) = Q_detected;
Pb_vals_std(i) = sum(data ~= received_bits) / N;
end
%% ---- GRAY-CODED QPSK ---- %%
I_bits = data(1:2:end);
Q_bits = data(2:2:end);
I_gray = zeros(1, length(I_bits));
Q_gray = zeros(1, length(Q_bits));
% Apply Gray code mapping
for k = 1:length(I_bits)
b1 = I_bits(k); b2 = Q_bits(k);
if b1==0 && b2==0
I_gray(k)=1; Q_gray(k)=1;
elseif b1==0 && b2==1
I_gray(k)=-1; Q_gray(k)=1;
elseif b1==1 && b2==1
I_gray(k)=-1; Q_gray(k)=-1;
elseif b1==1 && b2==0
I_gray(k)=1; Q_gray(k)=-1;
end
end
I_signal_gray = kron(I_gray, cos(2*pi*fc*n));
Q_signal_gray = kron(Q_gray, sin(2*pi*fc*n));
qpsk_signal_gray = I_signal_gray + Q_signal_gray;
% BER vs SNR for Gray-coded QPSK
for i = 1:length(snr_range)
qpsk_noisy = awgn(qpsk_signal_gray, snr_range(i), 'measured');
I_rec = qpsk_noisy .* kron(ones(1,length(I_gray)), cos(2*pi*fc*n));
Q_rec = qpsk_noisy .* kron(ones(1,length(Q_gray)), sin(2*pi*fc*n));
I_reshaped = reshape(I_rec, length(n), []);
Q_reshaped = reshape(Q_rec, length(n), []);
I_integrated = sum(I_reshaped);
Q_integrated = sum(Q_reshaped);
I_sym = 2*(I_integrated > 0) - 1;
Q_sym = 2*(Q_integrated > 0) - 1;
received_bits = zeros(1, N);
for k = 1:length(I_sym)
% Gray code decoding
if I_sym(k)==1 && Q_sym(k)==1
received_bits(2*k-1:2*k) = [0 0];
elseif I_sym(k)==-1 && Q_sym(k)==1
received_bits(2*k-1:2*k) = [0 1];
elseif I_sym(k)==-1 && Q_sym(k)==-1
received_bits(2*k-1:2*k) = [1 1];
elseif I_sym(k)==1 && Q_sym(k)==-1
received_bits(2*k-1:2*k) = [1 0];
end
end
Pb_vals_gray(i) = sum(data ~= received_bits) / N;
end
%% ---- PLOT BER vs SNR ---- %%
figure;
semilogy(snr_range, Pb_vals_std, '-o', 'LineWidth', 2); hold on;
semilogy(snr_range, Pb_vals_gray, '-x', 'LineWidth', 2);
xlabel('SNR (dB)');
ylabel('Bit Error Probability (Pb)');
title('QPSK BER vs SNR: Standard vs Gray-coded');
legend('Standard QPSK', 'Gray-coded QPSK');
grid on;
%% ---- OPTIONAL: CONSTELLATION PLOT at 5dB ---- %%
snr_db = 5;
qpsk_noisy = awgn(qpsk_signal_gray, snr_db, 'measured');
I_rec = qpsk_noisy .* kron(ones(1,length(I_gray)), cos(2*pi*fc*n));
Q_rec = qpsk_noisy .* kron(ones(1,length(Q_gray)), sin(2*pi*fc*n));
I_reshaped = reshape(I_rec, length(n), []);
Q_reshaped = reshape(Q_rec, length(n), []);
I_integrated = sum(I_reshaped);
Q_integrated = sum(Q_reshaped);
figure;
scatter(I_integrated, Q_integrated, 'filled');
title('Gray-coded QPSK Constellation at 5 dB SNR');
xlabel('In-phase'); ylabel('Quadrature'); grid on;
OUTPUT:
Lab Task :
Home Task :
CONCLUSION:
Gray-coded QPSK demonstrates improved bit error performance compared to standard QPSK,
especially at lower SNR values. This is due to its property of minimizing bit errors by ensuring
adjacent symbols differ by only one bit. Hence, Gray coding is preferred in practical digital
communication systems for enhanced reliability.