0% found this document useful (0 votes)
29 views24 pages

DC LAB MANUAL

Uploaded by

supreethm16
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views24 pages

DC LAB MANUAL

Uploaded by

supreethm16
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

Exp.

1 Gram-Schmidt Orthogonalization: To find orthogonal basis vectors for the given set
of vectors and plot the orthonormal vectors
Gram-Schmidt Orthogonalization
The Gram-Schmidt process takes a set of linearly independent vectors and produces an
orthogonal or orthonormal set of vectors spanning the same subspace. Here’s how it works
step by step:

Code:
clc;
clear;
close all;

% Parameters
N = 1000; % Number of bits
M = 16; % 16-QAM (16 symbols, 4 bits per symbol)
k = log2(M); % Bits per symbol for 16-QAM
SNR_dB = 20; % Signal to noise ratio in dB

% Generate random binary data


data_bits = randi([0 1], 1, N);

% Reshape bits into groups of 4 (for 16-QAM)


symbols_bits = reshape(data_bits, k, []).';

% Map bits to 16-QAM symbols using Gray coding


% Define the constellation points for 16-QAM (normalized)
% QAM constellation (-3,-1,1,3) for real and imaginary parts
qam_levels = [-3 -1 1 3];
qam_symbols = zeros(1, size(symbols_bits, 1));

for i = 1:size(symbols_bits, 1)
% Convert first 2 bits to in-phase (I) value
I_bits = bi2de(symbols_bits(i, 1:2), 'left-msb');
I_val = qam_levels(I_bits + 1);
% Convert last 2 bits to quadrature (Q) value
Q_bits = bi2de(symbols_bits(i, 3:4), 'left-msb');
Q_val = qam_levels(Q_bits + 1);

% 16-QAM symbol is the combination of I and Q components


qam_symbols(i) = I_val + 1i*Q_val;
end

% Normalize the power of the QAM symbols to 1


qam_symbols = qam_symbols / sqrt(mean(abs(qam_symbols).^2));

% Display the 16-QAM constellation


figure;
plot(real(qam_symbols), imag(qam_symbols), 'bo', 'MarkerSize', 6, 'LineWidth', 2);
xlabel('In-phase (I)');
ylabel('Quadrature (Q)');
title('16-QAM Constellation Diagram');
grid on;
axis([-2 2 -2 2]);

% Simulate AWGN Channel (optional)


rx_signal = awgn(qam_symbols, SNR_dB, 'measured'); % Add noise with SNR

% Display the received constellation with noise


figure;
plot(real(rx_signal), imag(rx_signal), 'ro', 'MarkerSize', 6, 'LineWidth', 2);
xlabel('In-phase (I)');
ylabel('Quadrature (Q)');
title(['16-QAM Constellation Diagram with Noise (SNR = ' num2str(SNR_dB) ' dB)']);
grid on;
axis([-2 2 -2 2]);

Explanation of the MATLAB Code


1. Initialization:
o The matrix V stores the input vectors.
o U is initialized to store the orthogonal vectors, and Q will store the
orthonormal vectors.
2. Gram-Schmidt Process:
o For each vector viv_ivi, we subtract the projections onto the previous
orthogonal vectors to obtain an orthogonal vector.
o We then normalize this orthogonal vector to obtain an orthonormal vector.
3. Plotting:
o We use quiver3 to plot 3D arrows representing the original vectors and the
orthonormal vectors.
o The original vectors are plotted with solid lines, and the orthonormal vectors
are plotted with dashed lines.
o The plot is labeled, and grid and axes are set for clarity.
Exp.2 Simulation of Binary Baseband Signals using Rectangular Pulse and BER Estimation
for AWGN Channel using Matched Filter Receiver
 Rectangular pulse shaping: Binary 0 and 1 are represented using a rectangular
pulse.
 AWGN Channel: Additive White Gaussian Noise (AWGN) channel introduces noise
to the transmitted signal.
 Matched Filter Receiver: Used to maximize the signal-to-noise ratio (SNR) for the
received signal.
 BER Estimation: Estimate the bit error rate (BER) for various values of SNR.

Code:
clc;
clear;
close all;

% Parameters
N = 1e5; % Number of bits
Tb = 1; % Bit duration
fs = 100; % Sampling frequency
SNR_dB = 0:1:10; % SNR values in dB

% Pulse shape (rectangular pulse)


t = 0:1/fs:Tb-1/fs;
rect_pulse = ones(1, length(t)); % Rectangular pulse of duration Tb

% Generate random binary data


data_bits = randi([0 1], 1, N); % Binary 0 or 1

% BPSK Modulation: Map bits to symbols (-1 for 0, 1 for 1)


modulated_signal = 2*data_bits - 1; % 0 -> -1, 1 -> 1

% Generate baseband signal with rectangular pulse shaping


baseband_signal = rect_pulse' * modulated_signal;

% Matched filter (same as the pulse shape)


matched_filter = rect_pulse;

% Initialize BER array


BER = zeros(1, length(SNR_dB));

% Loop over different SNR values


for i = 1:length(SNR_dB)
% AWGN Channel
snr = 10^(SNR_dB(i)/10); % Convert dB to linear scale
noise_variance = 1/(2*snr); % Noise variance (for BPSK over AWGN)
noise = sqrt(noise_variance) * randn(size(baseband_signal)); % AWGN noise
% Received signal (transmitted signal + noise)
received_signal = baseband_signal + noise;

% Matched filter output (convolution of received signal with matched filter)


filtered_signal = conv(received_signal(:), matched_filter, 'same');

% Sampling at the end of each bit period


sampled_signal = filtered_signal(fs:fs:end);

% Decision: If sampled value > 0, decide 1; otherwise, decide 0


detected_bits = sampled_signal > 0;

% BER calculation
bit_errors = sum(detected_bits ~= data_bits);
BER(i) = bit_errors/N;
end

% Plot the BER curve


figure;
semilogy(SNR_dB, BER, 'b-o', 'LineWidth', 2);
xlabel('SNR (dB)');
ylabel('Bit Error Rate (BER)');
title('BER vs SNR for Baseband Binary Signaling in AWGN Channel');
grid on;

% Theoretical BER for BPSK in AWGN channel


theoretical_BER = qfunc(sqrt(2*10.^(SNR_dB/10)));
hold on;
semilogy(SNR_dB, theoretical_BER, 'r--', 'LineWidth', 2);
legend('Simulated BER', 'Theoretical BER (BPSK)');
hold off;

Explanation of the MATLAB Code


1. Initialization:
o We define the total number of bits (N), the bit duration (Tb), and the
sampling frequency (fs).
o A range of SNR values (SNR_dB) is defined to simulate the effect of noise on
the system.
2. Rectangular Pulse Shaping:
o A rectangular pulse of duration Tb is generated using ones. This will be used
to shape the transmitted signal.
3. Data Generation and BPSK Modulation:
o Random binary bits (data_bits) are generated using randi.
o Binary Phase Shift Keying (BPSK) modulation is applied, where bit 0 is
mapped to -1 and bit 1 to 1. This is done using 2*data_bits - 1.
4. Baseband Signal:
o The baseband signal is created by modulating the rectangular pulse with the
modulated BPSK signal (rect_pulse' * modulated_signal).
5. AWGN Channel Simulation:
o For each value of SNR, we calculate the noise variance (1/(2*snr)) and
generate AWGN noise. The noise is added to the transmitted signal to
simulate transmission through an AWGN channel.
6. Matched Filter:
o The matched filter used is identical to the pulse shape (rectangular pulse).
The received signal is passed through the matched filter using convolution
(conv).
o After filtering, the signal is sampled at the end of each bit period
(sampled_signal).
7. Detection and BER Calculation:
o The detected bits are decided by checking whether the sampled signal is
greater than 0 (decide 1) or less than 0 (decide 0).
o The bit error rate (BER) is calculated by comparing the detected bits with the
original transmitted bits and counting the errors.
8. Plotting:
o The BER curve is plotted for each SNR value using a semilogy plot (logarithmic
y-axis).
o The theoretical BER for BPSK over an AWGN channel is also plotted for
comparison (qfunc(sqrt(2*snr))).
Results
 The plot shows the simulated BER vs. SNR and compares it with the theoretical BER
for BPSK in an AWGN channel.
 As expected, the BER decreases as the SNR increases, and the simulated results
should align closely with the theoretical values at higher SNRs.
Exp. 3 QPSK (Quadrature Phase Shift Keying) Modulation and Demodulation
QPSK (Quadrature Phase Shift Keying) is a digital modulation technique where two bits are
transmitted simultaneously by using four distinct phase shifts. Each phase represents a
unique symbol corresponding to two bits, such as:

Code:
clc;
clear;
close all;

% Parameters
N = 1000; % Number of bits
fs = 100; % Sampling frequency for plotting
M = 4; % QPSK (4 symbols)

% Generate random binary data


data_bits = randi([0 1], 1, N); % Random binary bits

% Group bits into symbols (QPSK uses 2 bits per symbol)


symbols = reshape(data_bits, 2, []).';

% Map bits to QPSK symbols (Gray encoding)


% 00 -> 1 + 0i (0°), 01 -> 0 + 1i (90°), 11 -> -1 + 0i (180°), 10 -> 0 - 1i (270°)
symbol_mapping = [1 + 1i, -1 + 1i, -1 - 1i, 1 - 1i]; % QPSK constellation points
bit_pairs = [0 0; 0 1; 1 1; 1 0]; % Gray coded bit pairs

% Modulate: Convert bit pairs to QPSK symbols


modulated_signal = zeros(1, length(symbols));
for i = 1:length(symbols)
bits = symbols(i, :);
index = find(ismember(bit_pairs, bits, 'rows')); % Find the matching bit pair
modulated_signal(i) = symbol_mapping(index); % Map to QPSK symbol
end

% Upsample for plotting (using zero padding between symbols)


upsampled_signal = upsample(modulated_signal, fs);

% Pulse shaping: Use rectangular pulse shaping for simplicity


rect_pulse = ones(1, fs); % Rectangular pulse of duration 1 symbol
qpsk_signal = conv(upsampled_signal, rect_pulse, 'same');

% Display the modulated QPSK signal


figure;
plot(real(qpsk_signal), 'r'); hold on;
plot(imag(qpsk_signal), 'b');
xlabel('Time (samples)');
ylabel('Amplitude');
title('QPSK Modulated Signal');
legend('In-phase', 'Quadrature');
grid on;

% Constellation plot (before channel)


figure;
plot(real(modulated_signal), imag(modulated_signal), 'bo', 'MarkerSize', 6, 'LineWidth', 2);
xlabel('In-phase (I)');
ylabel('Quadrature (Q)');
title('QPSK Constellation Diagram');
grid on;
axis([-1.5 1.5 -1.5 1.5]);

% AWGN Channel (optional: Add noise, set SNR to inf for no noise)
SNR_dB = 15; % SNR in dB
rx_signal = awgn(modulated_signal, SNR_dB, 'measured'); % Received signal with noise

% Display the constellation diagram after noise addition


figure;
plot(real(rx_signal), imag(rx_signal), 'bo', 'MarkerSize', 6, 'LineWidth', 2);
xlabel('In-phase (I)');
ylabel('Quadrature (Q)');
title(['QPSK Constellation Diagram with Noise (SNR = ' num2str(SNR_dB) ' dB)']);
grid on;
axis([-1.5 1.5 -1.5 1.5]);

% Demodulation (detecting symbols)


demodulated_symbols = zeros(size(rx_signal));
for i = 1:length(rx_signal)
% Find the nearest QPSK constellation point
distances = abs(symbol_mapping - rx_signal(i));
[~, idx] = min(distances);
demodulated_symbols(i) = symbol_mapping(idx);
end

% Convert demodulated symbols back to bits


demodulated_bits = zeros(size(data_bits));
for i = 1:length(demodulated_symbols)
symbol_idx = find(symbol_mapping == demodulated_symbols(i));
demodulated_bits(2*i-1:2*i) = bit_pairs(symbol_idx, :);
end

% Calculate BER (Bit Error Rate)


bit_errors = sum(data_bits ~= demodulated_bits);
BER = bit_errors / N;

% Display results
disp(['BER: ', num2str(BER)]);

Explanation of the MATLAB Code


1. Initialization:
o The number of bits (N), sampling frequency (fs), and modulation order (M=4
for QPSK) are set.
2. Binary Data Generation:
o A sequence of random binary bits (data_bits) is generated using randi.
3. Bit Grouping and Symbol Mapping:
o The binary bits are grouped into pairs, as QPSK transmits two bits per symbol.
o We define the QPSK symbol mapping based on Gray encoding:

o
4. QPSK Modulation:
o For each pair of bits, the corresponding QPSK symbol is chosen from the
constellation points (symbol_mapping).
5. Upsampling and Pulse Shaping:
o For plotting purposes, the QPSK signal is upsampled (increased sampling rate)
and passed through a rectangular pulse shaping filter.
6. Modulated Signal Plot:
o The real and imaginary parts of the modulated QPSK signal are plotted to
visualize the in-phase and quadrature components of the modulated signal.
7. Constellation Diagram:
o The QPSK symbols are plotted in the complex plane (real vs. imaginary) to
display the constellation diagram.
8. AWGN Channel (Optional):
o Noise is added to the QPSK signal using the awgn function, with the specified
SNR (SNR_dB). This simulates transmission through a noisy channel.
9. Demodulation:
o The received noisy signal is demodulated by finding the nearest QPSK symbol
for each received symbol.
o Each detected symbol is mapped back to the corresponding bit pair using the
reverse of the modulation process.
10. Bit Error Rate (BER) Calculation:
o The demodulated bits are compared to the original transmitted bits, and the
bit error rate (BER) is calculated.
11. Constellation Plot with Noise:
o After adding noise, the constellation diagram is plotted again to show how
the received symbols deviate from the ideal points due to the noise.
Results
 Modulated QPSK Signal: Shows how the in-phase and quadrature components of
the signal vary over time.
 Constellation Diagram (Before Channel): Displays the ideal QPSK constellation with
four distinct points representing the four symbols.
 Constellation Diagram (After Channel): Displays the received symbols with noise,
showing deviation from the ideal constellation points.
 BER Calculation: Displays the bit error rate, which should be low for high SNR values
but increases as noise increases.
Exp. 4 16-QAM (Quadrature Amplitude Modulation) Modulation and Constellation
In 16-QAM (Quadrature Amplitude Modulation), 16 symbols are used to transmit data, each
representing 4 bits (2 bits for the in-phase component and 2 bits for the quadrature
component). The symbols are arranged in a 4x4 grid on the constellation diagram, with both
amplitude and phase changes used to distinguish between different symbols.
Each symbol in 16-QAM is a complex number, where the real part represents the in-phase
(I) component, and the imaginary part represents the quadrature (Q) component.

Code:
clc;
clear;
close all;

% Parameters
N = 1000; % Number of bits
M = 16; % 16-QAM (16 symbols, 4 bits per symbol)
k = log2(M); % Bits per symbol for 16-QAM
SNR_dB = 20; % Signal to noise ratio in dB

% Generate random binary data


data_bits = randi([0 1], 1, N);

% Reshape bits into groups of 4 (for 16-QAM)


symbols_bits = reshape(data_bits, k, []).';

% Map bits to 16-QAM symbols using Gray coding


% Define the constellation points for 16-QAM (normalized)
% QAM constellation (-3,-1,1,3) for real and imaginary parts
qam_levels = [-3 -1 1 3];
qam_symbols = zeros(1, size(symbols_bits, 1));

for i = 1:size(symbols_bits, 1)
% Convert first 2 bits to in-phase (I) value
I_bits = bi2de(symbols_bits(i, 1:2), 'left-msb');
I_val = qam_levels(I_bits + 1);

% Convert last 2 bits to quadrature (Q) value


Q_bits = bi2de(symbols_bits(i, 3:4), 'left-msb');
Q_val = qam_levels(Q_bits + 1);

% 16-QAM symbol is the combination of I and Q components


qam_symbols(i) = I_val + 1i*Q_val;
end

% Normalize the power of the QAM symbols to 1


qam_symbols = qam_symbols / sqrt(mean(abs(qam_symbols).^2));
% Display the 16-QAM constellation
figure;
plot(real(qam_symbols), imag(qam_symbols), 'bo', 'MarkerSize', 6, 'LineWidth', 2);
xlabel('In-phase (I)');
ylabel('Quadrature (Q)');
title('16-QAM Constellation Diagram');
grid on;
axis([-2 2 -2 2]);

% Simulate AWGN Channel (optional)


rx_signal = awgn(qam_symbols, SNR_dB, 'measured'); % Add noise with SNR

% Display the received constellation with noise


figure;
plot(real(rx_signal), imag(rx_signal), 'ro', 'MarkerSize', 6, 'LineWidth', 2);
xlabel('In-phase (I)');
ylabel('Quadrature (Q)');
title(['16-QAM Constellation Diagram with Noise (SNR = ' num2str(SNR_dB) ' dB)']);
grid on;
axis([-2 2 -2 2]);

Explanation of the MATLAB Code


1. Initialization:
o We set the total number of bits (N) and modulation order (M = 16) for 16-
QAM.
o The number of bits per symbol is k = log2(M) = 4 because 16-QAM transmits
4 bits per symbol.
2. Binary Data Generation:
o A sequence of random binary bits (data_bits) is generated using randi. The
total number of bits generated is N.
3. Bit Grouping:
o The binary bits are reshaped into groups of 4 (since each 16-QAM symbol
represents 4 bits) using the reshape function.
4. Symbol Mapping:
o The constellation points for 16-QAM are arranged in a grid where both the
real and imaginary components can take values from [-3, -1, 1, 3].
o Each pair of bits is converted into a corresponding real part (in-phase
component, I) and imaginary part (quadrature component, Q).
o The in-phase and quadrature components are obtained from the qam_levels
array, which holds the four possible values for the QAM levels.
o The in-phase (I_val) and quadrature (Q_val) values are combined to form the
complex QAM symbol.
5. Normalization:
o The symbols are normalized to ensure that the average power of the symbols
is 1. This is important for proper comparison in scenarios involving noise or
different modulation schemes.
6. 16-QAM Constellation Display:
o The constellation points are plotted in the complex plane using plot, where
the x-axis represents the real part (in-phase component) and the y-axis
represents the imaginary part (quadrature component).
o This plot shows the distinct grid-like structure of 16-QAM, with 16 points
forming a 4x4 grid.
7. AWGN Channel Simulation (Optional):
o To simulate a realistic communication scenario, Additive White Gaussian
Noise (AWGN) is added to the transmitted signal using the awgn function.
The SNR (Signal-to-Noise Ratio) is set to 20 dB.
o The noisy constellation diagram is plotted to observe how the received points
are affected by the noise.
Results
 16-QAM Constellation Diagram:
o The constellation diagram shows 16 distinct points arranged in a 4x4 grid.
Each point represents a unique combination of in-phase and quadrature
values corresponding to 4 bits of data.
 Constellation with Noise (Optional):
o When noise is added, the received symbols deviate from their ideal positions,
but the constellation points are still grouped around the original positions.
Higher SNR values lead to smaller deviations, resulting in better performance.
Exp. 5 Huffman Coding: Encoding and Decoding in MATLAB
Huffman coding is a lossless data compression technique where frequently occurring
symbols are encoded with shorter codes, while less frequent symbols are encoded with
longer codes. The process involves building a binary tree based on the frequency of each
symbol and assigning binary codes to each symbol based on their position in the tree.

Code:
clc;
clear;
close all;

% Input data (symbols and their corresponding probabilities)


symbols = ['A', 'B', 'C', 'D', 'E', 'F']; % Symbols
probabilities = [0.25, 0.2, 0.2, 0.15, 0.1, 0.1]; % Probabilities for each symbol

% Huffman encoding: Generate the Huffman dictionary


[dict, avglen] = huffmandict(symbols, probabilities);

% Display the Huffman dictionary (symbols and corresponding binary codes)


disp('Huffman Dictionary:');
for i = 1:length(symbols)
disp([symbols(i), ' -> ', num2str(cell2mat(dict{i,2}))]);
end

% Input message to encode


input_message = ['A', 'B', 'A', 'D', 'F', 'C', 'B', 'E', 'C', 'A'];

% Huffman encoding of the input message


encoded_message = huffmanenco(input_message, dict);

% Display the encoded binary message


disp('Encoded Message:');
disp(num2str(encoded_message'));

% Huffman decoding: Decode the encoded message back to original


decoded_message = huffmandeco(encoded_message, dict);

% Display the decoded message


disp('Decoded Message:');
disp(char(decoded_message'));

% Verify that the decoded message matches the original input


if isequal(input_message, decoded_message)
disp('Decoding successful: Original message matches the decoded message.');
else
disp('Decoding failed: Original message does not match the decoded message.');
end
Explanation of the MATLAB Code
1. Initialization:
o The symbols array contains the unique symbols (in this case, characters) to
be encoded, and the probabilities array contains their corresponding
probabilities.
o The probabilities must sum to 1 for a valid Huffman tree construction.
2. Huffman Dictionary Construction:
o The huffmandict function generates the Huffman dictionary based on the
input symbols and their probabilities. The dictionary maps each symbol to its
corresponding binary Huffman code.
o The output dict is a cell array where the first column contains the symbols,
and the second column contains the corresponding Huffman codes.
o The average length of the Huffman code is stored in avglen.
3. Display the Huffman Dictionary:
o The dictionary is displayed, showing the binary code assigned to each symbol.
4. Input Message Encoding:
o A sample input message is defined, which is a sequence of symbols from the
symbol set.
o The huffmanenco function is used to encode this message into a sequence of
binary bits using the Huffman dictionary.
5. Display the Encoded Message:
o The encoded message (binary sequence) is displayed.
6. Decoding the Encoded Message:
o The huffmandeco function is used to decode the encoded binary sequence
back to the original symbols using the Huffman dictionary.
7. Verify the Decoded Message:
o The decoded message is compared with the original input message. If they
match, the decoding is considered successful.

Example of Encoding
For the input message ['A', 'B', 'A', 'D', 'F', 'C', 'B', 'E', 'C', 'A']:
 The encoded message is a sequence of binary digits that represents the Huffman
codes for each symbol:
A -> 0
B -> 10
A -> 0
D -> 110
F -> 1010
C -> 111
B -> 10
E -> 1011
C -> 111
A -> 0

 The encoded message: 0100110101110111100


Example of Decoding
The encoded binary sequence is decoded back to the original message, which should match
the input message.
Advantages of Huffman Coding
 Optimal Compression: Huffman coding provides optimal lossless compression for
the given probability distribution.
 Variable-length Codes: Frequently occurring symbols have shorter codes, while
infrequent symbols have longer codes, reducing the overall size of the encoded
message.
Exp. 6 Hamming Code: Encoding and Decoding of Binary Data
Hamming code is a method of error detection and correction used to detect and correct
single-bit errors in data transmission. It is a type of linear block code that adds redundant
parity bits to a binary message to allow the detection and correction of errors in
transmission.
The general steps to encode a message using Hamming code are:
1. Add parity bits at specific positions.
2. Calculate the values of the parity bits based on the message bits.
3. Transmit the message along with the parity bits.
To decode, we:
1. Check the parity bits.
2. Identify and correct any single-bit errors.

Code:
clc;
clear;
close all;

% Define the binary data to be encoded (4-bit data for Hamming(7,4))


data_bits = [1 0 1 1]; % Example 4-bit data

% Hamming (7,4) Code: Adding parity bits to 4-bit data to make it 7-bit
% The positions of the parity bits are at positions 1, 2, and 4 (powers of 2)
% Positions: [p1, p2, d1, p4, d2, d3, d4]

% Initialize the encoded data with placeholders for parity bits


encoded_bits = zeros(1, 7);
encoded_bits([3, 5, 6, 7]) = data_bits; % Place data bits at positions 3, 5, 6, and 7

% Calculate parity bits


encoded_bits(1) = mod(encoded_bits(3) + encoded_bits(5) + encoded_bits(7), 2); % Parity
bit 1
encoded_bits(2) = mod(encoded_bits(3) + encoded_bits(6) + encoded_bits(7), 2); % Parity
bit 2
encoded_bits(4) = mod(encoded_bits(5) + encoded_bits(6) + encoded_bits(7), 2); % Parity
bit 4

% Display the encoded bits


disp('Encoded bits:');
disp(encoded_bits);

% Introduce a single-bit error in the encoded data (for testing correction)


received_bits = encoded_bits;
received_bits(5) = mod(received_bits(5) + 1, 2); % Flip bit 5 to simulate error

% Display the received (corrupted) bits


disp('Received bits (with error):');
disp(received_bits);

% Syndrome calculation: Check for errors using parity bits


s1 = mod(received_bits(1) + received_bits(3) + received_bits(5) + received_bits(7), 2);
s2 = mod(received_bits(2) + received_bits(3) + received_bits(6) + received_bits(7), 2);
s4 = mod(received_bits(4) + received_bits(5) + received_bits(6) + received_bits(7), 2);

% Calculate the syndrome (which tells the position of the error)


syndrome = s1 + s2*2 + s4*4;

% Correct the error if the syndrome is non-zero


if syndrome ~= 0
disp(['Error detected at position ', num2str(syndrome)]);
received_bits(syndrome) = mod(received_bits(syndrome) + 1, 2); % Correct the bit
else
disp('No errors detected.');
end

% Display the corrected received bits


disp('Corrected received bits:');
disp(received_bits);

% Extract the original data bits (positions 3, 5, 6, 7)


decoded_bits = received_bits([3, 5, 6, 7]);

% Display the decoded data bits


disp('Decoded data bits:');
disp(decoded_bits);

% Verify that the decoded data matches the original data


if isequal(data_bits, decoded_bits)
disp('Decoding successful: Original data matches the decoded data.');
else
disp('Decoding failed: Original data does not match the decoded data.');
end
Explanation of the MATLAB Code
1. Initialization:
o The binary data to be encoded is defined as a 4-bit message (data_bits = [1 0
1 1]). This represents the original data that needs to be transmitted.
2. Hamming (7,4) Code Structure:
o The Hamming (7,4) code adds 3 parity bits to the 4-bit data, creating a 7-bit
encoded message. The positions of the parity bits are at positions 1, 2, and 4
(powers of 2), while the data bits are placed in the remaining positions (3, 5,
6, and 7).
o Parity bits:
 Parity bit 1 (p1): Covers positions 1, 3, 5, and 7.
 Parity bit 2 (p2): Covers positions 2, 3, 6, and 7.
 Parity bit 4 (p4): Covers positions 4, 5, 6, and 7.
3. Parity Bit Calculation:
o The parity bits are calculated based on the XOR (mod 2) of the relevant data
bits. Each parity bit ensures that the sum of bits it covers is even (or odd,
depending on the chosen convention).
4. Display the Encoded Bits:
o The encoded 7-bit message is displayed after adding the parity bits.
5. Error Introduction (Optional):
o For testing purposes, a single-bit error is introduced at position 5 by flipping
the bit. This simulates a transmission error.
6. Syndrome Calculation:
o The syndrome is calculated by checking the parity of the received bits using
the same rules used to generate the parity bits.
o The syndrome indicates the position of the error. If the syndrome is non-zero,
it points to the position where the error occurred.
7. Error Correction:
o If an error is detected (syndrome is non-zero), the bit at the corresponding
position is flipped to correct the error.
8. Decoding:
o After correcting the error, the original data bits (positions 3, 5, 6, and 7) are
extracted from the received message.
9. Verification:
o The decoded message is compared to the original data. If they match, the
decoding is successful.
Example
Given the data bits: [1 0 1 1]
The encoded bits using Hamming (7,4) code will be:
[0 1 1 0 0 1 1]
If a single-bit error is introduced at position 5, the received bits become:
[0 1 1 0 1 1 1]
The syndrome calculation identifies the error at position 5, and the error is corrected:
[0 1 1 0 0 1 1]
The decoded data bits are:
[1 0 1 1]
Exp. 7 Cyclic Redundancy Check (CRC) Using CRC-CCITT Polynomial
The Cyclic Redundancy Check (CRC) is an error-detection technique used to ensure data
integrity. The CRC-CCITT polynomial is commonly used in communication systems and is
defined as:

This corresponds to the generator polynomial: G(x)=10001000000100001G(x) =


10001000000100001G(x)=10001000000100001
CRC works by appending a sequence of redundant bits (called the CRC code) to the data to
be transmitted. At the receiver's end, the data is checked by recomputing the CRC and
comparing it with the received CRC value.
Steps for CRC:
1. Encoding: Compute the CRC by dividing the data by the generator polynomial.
Append the remainder (CRC code) to the data.
2. Verification: Recalculate the CRC on the received data and check if the remainder is
zero (for error-free data) or non-zero (for corrupted data).
Code:
clc;
clear;
close all;

% Define the CRC-CCITT generator polynomial (16-bit)


% Polynomial: x^16 + x^12 + x^5 + 1
generator = [1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1];

% Input binary data (example data)


data_bits = [1 0 1 1 0 1 0 1]; % Example 8-bit data

% Display the original data


disp('Original Data Bits:');
disp(data_bits);

% Append 16 zeros to the data (for CRC-16)


data_with_zeros = [data_bits zeros(1, length(generator)-1)];

% Perform the division (modulo-2 division)


remainder = mod2div(data_with_zeros, generator);

% Calculate the CRC (remainder)


crc_code = remainder;

% Append the CRC to the original data


encoded_data = [data_bits crc_code];

% Display the encoded data (original data + CRC)


disp('Encoded Data (with CRC):');
disp(encoded_data);
% ------------------------------
% Case 1: Without Error
% ------------------------------
disp('Case 1: Without Error');
received_data_no_error = encoded_data; % No error in the received data

% Verify CRC at receiver (perform modulo-2 division again)


remainder_no_error = mod2div(received_data_no_error, generator);

if all(remainder_no_error == 0)
disp('No errors detected.');
else
disp('Error detected.');
end

% ------------------------------
% Case 2: With Error
% ------------------------------
disp('Case 2: With Error');
received_data_with_error = encoded_data;
received_data_with_error(5) = mod(received_data_with_error(5) + 1, 2); % Introduce an
error at bit 5

% Verify CRC at receiver (perform modulo-2 division again)


remainder_with_error = mod2div(received_data_with_error, generator);

if all(remainder_with_error == 0)
disp('No errors detected.');
else
disp('Error detected.');
end

% Function to perform modulo-2 division (binary division)


function remainder = mod2div(dividend, divisor)
len_divisor = length(divisor);
temp = dividend(1:len_divisor); % Initial bits to divide

for i = len_divisor:length(dividend)
if temp(1) == 1
temp = xor(temp, divisor); % XOR with the divisor if the first bit is 1
end
temp = [temp(2:end) dividend(i)]; % Shift left and append the next bit
end
remainder = temp(1:end-1); % The last (len_divisor - 1) bits are the remainder
end
Explanation of the MATLAB Code
1. Initialization:
o We define the CRC-CCITT generator polynomial (x^16 + x^12 + x^5 + 1),
which is represented by the binary vector generator = [1 0 0 0 1 0 0 0 0 0 0 0
1 0 0 0 1].
o The data_bits array contains the binary data to be transmitted (e.g., [1 0 1 1
0 1 0 1]).
2. Appending Zeros to the Data:
o Before performing the CRC computation, 16 zeros (same as the degree of the
polynomial) are appended to the original data. This is stored in the variable
data_with_zeros.
3. Modulo-2 Division (Binary Division):
o The function mod2div performs modulo-2 division, which is binary division
without carries. This function is used to divide the data (with appended
zeros) by the generator polynomial. The remainder from this division is the
CRC code.
4. Appending CRC Code to the Data:
o The calculated CRC code (remainder) is appended to the original data to form
the encoded data.
5. Case 1: Without Error
o The received data (without errors) is checked by performing the modulo-2
division again using the mod2div function. If the remainder is zero, it
indicates that no errors occurred during transmission.
6. Case 2: With Error
o To simulate an error, we flip one of the bits in the received data (e.g., at
position 5). After recalculating the CRC, if the remainder is non-zero, it
indicates that an error was detected.
7. Binary Division Function (mod2div)
o This function performs modulo-2 division on the dividend (data) using the
divisor (generator polynomial). It returns the remainder, which is used to
calculate the CRC and verify errors.
Results
Case 1: Without Error
For the case without errors, the receiver performs the CRC check and verifies that the
remainder is zero, indicating that the received data is error-free.
Case 2: With Error
For the case with an error (in this case, an error is introduced at position 5), the receiver's
CRC check results in a non-zero remainder, indicating that an error has occurred.
Example Output
Original Data Bits:
1 0 1 1 0 1 0 1
Encoded Data (with CRC):
1 0 1 1 0 1 0 1 0 1 0 0 0 0 1 1 0 1 1 0
Case 1: Without Error
No errors detected.
Case 2: With Error
Error detected.
Exp.8 Convolutional Coding: Encoding and Decoding
Convolutional coding is an error-correcting coding technique used in communication
systems to add redundancy to the transmitted data, allowing for error detection and
correction at the receiver. Unlike block codes, which operate on fixed-size blocks of data,
convolutional codes work on continuous data streams, encoding each bit of data based on
the current bit and a number of previous bits.
A common representation for convolutional codes is through a state machine or trellis
diagram, which shows how each bit transitions from one state to another.
MATLAB Code for Convolutional Encoding and Decoding
In this example, we will use a rate 12\frac{1}{2}21 convolutional code with constraint length
3 and generator polynomials g1=78g_1 = 7_8g1=78 and g2=58g_2 = 5_8g2=58. These
polynomials correspond to a memory-2 convolutional encoder, which looks at the current
input bit and the two previous bits to generate two encoded output bits.

Code:
clc;
clear;
close all;

% Define the generator polynomials (in octal format)


% For rate 1/2 convolutional code
g1 = [1 1 1]; % Generator polynomial g1 = 7 (octal)
g2 = [1 0 1]; % Generator polynomial g2 = 5 (octal)

% Input binary data (example data)


data_bits = [1 0 1 1 0 1 1 0]; % 8-bit input message

% Display the original data bits


disp('Original Data Bits:');
disp(data_bits);

% Convolutional Encoding
encoded_bits = conv_encode(data_bits, g1, g2);

% Display the encoded bits


disp('Encoded Bits:');
disp(encoded_bits);

% ------------------------------
% Decoding using Viterbi Algorithm
% ------------------------------
decoded_bits = viterbi_decode(encoded_bits, g1, g2);

% Display the decoded bits


disp('Decoded Bits:');
disp(decoded_bits);
% Check if the decoded bits match the original data
if isequal(data_bits, decoded_bits)
disp('Decoding successful: Original data matches the decoded data.');
else
disp('Decoding failed: Original data does not match the decoded data.');
end

% ----------------------------------------------
% Convolutional Encoder Function
% ----------------------------------------------
function encoded_bits = conv_encode(data_bits, g1, g2)
% Get the constraint length
K = length(g1); % Constraint length is 3 for this example

% Initialize the shift register


shift_register = zeros(1, K-1); % Memory size is K-1 (2 in this case)

% Encode the data bits


encoded_bits = [];
for i = 1:length(data_bits)
% Shift the data bits into the shift register
shift_register = [data_bits(i) shift_register(1:end-1)];

% Compute the encoded bits using the generator polynomials


output_bit1 = mod(sum(shift_register .* g1), 2); % Output using g1
output_bit2 = mod(sum(shift_register .* g2), 2); % Output using g2

% Append the encoded bits


encoded_bits = [encoded_bits output_bit1 output_bit2];
end
end

% ----------------------------------------------
% Viterbi Decoder Function
% ----------------------------------------------
function decoded_bits = viterbi_decode(encoded_bits, g1, g2)
% Define trellis states (4 states for constraint length 3: 00, 01, 10, 11)
K = length(g1); % Constraint length
num_states = 2^(K-1); % Number of states for trellis

% Trellis structure: Define state transitions and output for each state
trellis = [
0 0; % State 0 (00) -> next states 0 and 1
1 1; % State 1 (01) -> next states 2 and 3
2 2; % State 2 (10) -> next states 0 and 1
3 3 % State 3 (11) -> next states 2 and 3
];
% Initialize the path metrics and state paths
path_metrics = zeros(num_states, 1); % Path metrics (starting from zero)
state_paths = cell(num_states, 1); % Store state paths

% Decode the encoded bits using Viterbi algorithm


for i = 1:2:length(encoded_bits)
% Get the two received bits
received_bits = encoded_bits(i:i+1);

% Update the path metrics for each state based on the received bits
for state = 1:num_states
% Find the possible transitions to the current state
prev_states = find(trellis(:, state) == state - 1); % State transitions
end
end

You might also like