You are on page 1of 19

WIRELESS COMMUNICATION LAB

ELP-725

EXPERIMENT-3

LAB REPORT

MTECH COMMUNICATION ENGINEERING


SEMESTER-II

HIMSHIKHA 2023EEE2334
BIDISHA MISRA 2023EEE2759
Objective:
a. Estimate the channel quality
b. Assign the modulation (QAM) depending on the location of the receiver from the transmitter to satisfy
Quality of Service in terms of Bit Error Rate.
c. Compare the performance of adaptive modulation scheme with non-adaptive modulation scheme
(demonstrate the benefits of adaptive over non-adaptive)

Equipment used:
1. GNU Radio-companion
2. HackRF one of transceiver
3. One RTL SDR
4. Connecting cables
5. Two laptops

Theory:
Channel estimation:

When a signal passes through a channel, it is distorted by the noise or by other signals traversing the same
medium. This means that when signal is received at its destination, it could have errors. So, in order to
remove the noise and distortion effects of the channel from the received signal, channel properties have to be
found out. The process of figuring out channel characteristics is called Channel Estimation.

Adaptive and Non-Adaptive Modulation Coding techniques:

Adaptive modulation and coding (AMC) and non-adaptive modulation and coding (NAMC) are techniques
used in wireless communication systems to optimize data transmission based on channel conditions.

Non-adaptive modulation and coding (NAMC):

 In NAMC, a fixed modulation and coding scheme (MCS) is used for all data transmissions, regardless
of channel conditions.
 The MCS is predetermined and typically chosen based on worst-case channel conditions to ensure
reliability.
 While NAMC provides consistent performance, it may not efficiently utilize the available bandwidth
under varying channel conditions.

Adaptive modulation and coding (AMC):

 AMC dynamically adjusts the modulation and coding scheme based on real-time channel conditions.
 It continuously monitors the channel quality and adapts the MCS to maximize data rate while
maintaining an acceptable level of error performance.
 Higher MCS (e.g., using higher-order modulation or lower coding rates) are used when the channel
quality is good, allowing for higher data rates. Conversely, lower MCS are selected when the channel
quality deteriorates to ensure reliability.
 AMC enhances spectral efficiency and overall system capacity by utilizing the available resources
more efficiently compared to NAMC.

While NAMC uses a fixed MCS for all transmissions, AMC dynamically adjusts the MCS based on channel
conditions to optimize data rate and reliability.
Working Principle of Adaptive Modulation

Adaptive Modulation is based on the principle of continuous control of the conditions of the channel and is
based on the regulation of the parameters of the modulation. It includes the following:

 Channel Estimation: The receiver always tries to estimate the channel conditions at any point in time.
This involves constantly assessing the Signal-to-Noise Ratio (SNR), levels of interference, and
characteristics of fading within the channel. Such estimation is crucial for adapting the communication
strategy to current conditions, ensuring optimal signal transmission and reception.
 Modulation Scheme Selection: This process involves selecting an appropriate modulation scheme from
a predefined set, mainly depending on the channel estimates, to balance the data rate against reliability.
The choice of modulation scheme affects how data is encoded for transmission, with different schemes
offering trade-offs between data throughput and resilience to channel impairments.
 Transmission: After selecting the modulation scheme, the transmitter encodes the data accordingly and
then transmits it through the channel. This step is where the actual data transmission occurs, with the
encoded data being sent from the transmitter to the receiver over the communication channel.
 Feedback: The receiver provides feedback about the quality of the received signal and the modulation
parameters that need to be adjusted. This feedback is crucial for the transmitter to understand how well
the transmission was received and what adjustments may be needed to improve future transmissions.
Adjustments could involve changing the modulation scheme, power levels, or other parameters to
enhance signal quality and communication reliability.

By its iterative process, this system gets adapted to varying conditions of the channel for real-time performance
optimization with maximum throughput.

Fig 1: Block diagram of Adaptive Modulation and Coding


Procedure:
The following experiment is a very simple recreation of the working principle of AMC. The experiment was
performed on GNU Radio in simulation and then tested on HackRF-one Software Defined Radio.

 Channel Quality Estimation:


We are estimating channel quality by transmitting all the constellations (BPSK, QPSK, PSK-8 and 16-
QAM). To measure the channel quality, MPSK SNR Estimator Probe is used at receiver and SNR is
displayed on the console. For the experiment, distance is varied between the transmitter and receiver
to simulate the channel noise and thus SNR changes is shown using the Message Debug block which
is printing the SNR corresponding to the distance between the transmitter and receiver.
 Adaptive Modulation
1. We have given a text file in File source to transmit it and used different modulation scheme blocks
(BPSK, QPSK and 8-PSK and 16-QAM) which are built using constellation modulators and are
given to a multiplexer to pick the best constellation according to the SNR values of the channel,
obtained by varying the distance between the transmitter and receiver
2. Then the selected modulation scheme is given to the Osmocom sink which will transmit it using
Hack-RF radio transceiver. At the receiver, an antenna is used to receive it.
3. Then a polyphase clock sync block is used to perform clock recovery, provide matched filter to
remove ISI and down-sample the signal.
4. There is feedback between the transmitter and the receiver, so depending on the SNR values of the
channel, whichever constellation is picked by the transmitter according to the channel condition,
is given to the demultiplexer. The DEMUX shows the transmitted constellation and switch among
the constellations in the Time Sink and Constellation Sink blocks. The received text file is captured
in File Sink for every modulation scheme which is used for BER calculation.

Implementation:

1. Channel Estimation

(a) Channel Estimation Transmitter


(b) Channel Estimation Receiver

Fig2: Channel Estimation (checking SNR) (a) Transmitter (b) Receiver

2. Adaptive Modulation and Coding

(a) AMC Transmitter


(b) AMC Receiver

Fig3: Adaptive Modulation and Coding (AMC) (a) transmitter (b) receiver

Results and Observations (Hardware Results):

1. Channel Estimation:

For BPSK

(i)
(ii)
Fig4: Transmitted and received BPSK constellation with corresponding SNR values (i) when channel condition is
moderate (ii) when channel condition is much worse

For QPSK

(i)
(ii)

Fig 5: Transmitted and received QPSK constellation with corresponding SNR values (i) when channel condition
is good (ii) when channel condition is much worse

For 8PSK

(i)
(ii)

Fig6: Transmitted and received 8PSK constellation with corresponding SNR values (i) when channel condition is good
(ii) when channel condition is much worse

For QAM-16

(i)
(ii)

Fig 7: Transmitted and received QAM-16 constellation with corresponding SNR values (i) when channel condition is
good (ii) when channel condition is much worse

Fig (A) Channel Estimation (a) Transmitted and (b) Received constellations and SNRs obtained by varying distances

2. Adaptive Modulation and Coding (Hardware results):


QAM16:

(i) (ii)

(iii) (iv)

Fig 8: Selection of 16-QAM (i) time sink (ii) corresponding SNR when it is selected (iii) transmitted constellation (iv)
received constellation
PSK8:

(i) (ii)

(iii) (iv)

Fig 9: Selection of 8-PSK (i) time sink (ii) corresponding SNR when it is selected (iii) transmitted constellation (iv)
received constellation

QPSK:

(i) (ii)
(iii) (iv)

Fig 10: Selection of QPSK (i) time sink (ii) corresponding SNR when it is selected (iii) transmitted constellation (iv)
received constellation

BPSK:

(i) (ii)

(iii) (iv)

Fig 11: Selection of BPSK (i) time sink (ii) corresponding SNR when it is selected (iii) transmitted constellation (iv)
received constellation

Fig (B) AMC Modulation: showing switching between different constellations based on channel conditions (SNR
values)
3. Comparison of Adaptive and Non-Adaptive Modulation Schemes:

BER vs SNR Data

Table 1: BER vs SNR for BPSK Modulation: Table 1: BER vs SNR for QPSK Modulation:

SNR (dB) BER SNR (dB) BER


4.8 0.0140 8.48 0.0070
4.78 0.0142 8.03 0.0071

4.72 0.0149 7.59 0.0074

3.60 0.0323 7.70 0.0162

3.58 0.0327 7.01 0.0164

3.42 0.0360 6.98 0.0180

2.88 0.0488 6.56 0.0244


2.50 0.0593 5.82 0.0297
1.02 0.1117 5.42 0.0559

Table 1: BER vs SNR for 8PSK Modulation: Table 1: BER vs SNR for QAM16 Modulation:

SNR (dB) BER SNR (dB) BER


*10^-4
10.9 0.0003 18.02 0.0000
10.23 0.0008 17.83 0.0000
10.11 0.0009 16.50 0.0000
9.50 0.0017 16.46 0.0000
9.48 0.0017 16.08 0.0001
9.32 0.0020 15.55 0.0004
8.92 0.0030 14.43 0.0124
8.73 0.0035 14.09 0.0296
8.54 0.0041 13.30 0.1770
Fig 12: Comparison of adaptive vs non-adaptive modulation schemes

Observation and Analysis:

Channel Estimation:

1. In Fig (A) (4,5,6 and 7), we have performed channel estimation for all the modulation schemes BPSK,
QPSK, 8-PSK and 16-QAM by varying the distance between the transmitter and receiver. For each
modulation scheme, it is seen that when distance between transmitter and receiver is less (channel
condition is good), then received constellation is fairly accurate whereas when distance between
transmitter and receiver is more (channel condition is worse), then the received constellation gets
distorted.

2. This is because when distance between transmitter and receiver increases, the signal strength weakens
due to factors like attenuation and interference, which lowers the SNR. A lower SNR means that the
signal becomes more susceptible to noise, leading to errors in signal detection, hence increasing the BER.

Adaptive Modulation:

1. Channel gain is random and there may be multipaths leading to multiple copies of the signal at the
receiver causing uncertain SNR at the receiver end. We can use adaptive modulation and coding which
adjusts the modulation schemes based on factors like channel conditions, interference, and signal
strength to ensure efficient use of available bandwidth and maximizing the data throughput while
maintaining acceptable BER.

2. From Fig (B) (8,9,10,11), we can see that the multiplexer picks QAM-16 constellation when channel
condition is good (SNR=14), 8-PSK constellation when the channel condition is moderate (SNR=9),
QPSK constellation when channel condition degrades (SNR=7) and BPSK constellation when channel
condition is worst (SNR=4).

3. This is because higher order modulation is picked when the channel condition is good, allowing for
higher data rates whereas lower order modulation is picked when channel condition deteriorates to
ensure reliability in terms of BER.
4. When channel condition is bad (low SNR) and if we transmit higher order constellation (QAM-16),
then BER is high as QAM 16 has the minimum distance between the signaling points, thus there is
more chance of bits getting flipped as noise amplitude will be at least, higher than half of the distance
between the signaling points, so it is better to select lower order constellation like BPSK as there is
more distance between the signaling points as compared to higher order constellations .

Comparison between Adaptive and Non-Adaptive Modulation:

1. In non-adaptive modulation, we use single modulation. In case of higher constellation, if SNR is low,
BER is worst and information is lost, whereas, in case of lower constellation, we do not use complete
channel capacity when SNR is very low.

2. In adaptive modulation, we prevent our data from distortion even if SNR is very low by transmitting
lower order constellation but when the channel condition improves, it switches to higher order
constellation to ensure better utilization of channel capacity.

3. In Fig12., we have plotted BER vs SNR for all the constellations (BPSK, QPSK, 8PSK and 16QAM)
for non-adaptive modulation and in order to show adaptive modulation and its switching among
different modulation schemes we have coded the logic accordingly which is given below MATLAB
code. From graph we can see that when SNR<5dB it transmits BPSK, when 5dB<SNR<8.5dB AMC
gets switched from BPSK to QPSK, and when 8.5dB<SNR<11dB it gets switched from QPSK to
8PSK and for SNR>11dB it picks QAM16.These results can be verified from the graph.

Conclusion:
We have performed channel estimation for different modulation schemes and shown SNR values by varying
distances between Tx and Rx and corresponding picked constellation by adaptive modulation. We can see that
we prevent our data from distortion when channel is very bad by sending lower order modulation scheme and
increase the data rate by sending higher order constellation when channel condition is good.
Adaptive modulation coding technique is useful in such scenarios for proper utilization of channel capacity.
We have compared the transmitted and received file and calculated the BER for different modulation schemes
and finally we plotted the graph of BER vs SNR for different modulation schemes and compared non-adaptive
modulation scheme with adaptive modulation scheme.

Reference:
1. Goldsmith A (2005) Wireless Communications Cambridge University Press Doi:10.1017/CBO9780511841224.
2.https://www.gnuradio.org/

Python Code:

(Multiplexer)
"""
Embedded Python Blocks:

Each time this file is saved, GRC will instantiate the first class it finds
to get ports and parameters of your block. The arguments to _init_ will
be the parameters. All of them are required to have default values!
"""

import numpy as np
from gnuradio import gr
import pmt

from gnuradio import grc


import inspect

class blk(gr.sync_block): # other base classes are basic_block, decim_block, interp_block


"""Embedded Python Block example - a simple multiply const"""

def _init_(self): # only default arguments here


"""arguments to this function show up as parameters in GRC"""
gr.sync_block._init_(
self,
name='Multiplexer', # will show up in GRC
in_sig=[np.complex64,np.complex64,np.complex64,np.complex64],
out_sig=[np.complex64]
)
self.selectPortName = 'snr'
self.message_port_register_in(pmt.intern(self.selectPortName))
self.set_msg_handler(pmt.intern(self.selectPortName), self.handle_msg)
self.last_snr = 0
self.is_mod_changed=False;
self.selector=0
self.last_selector=0
self.bpsk_max=5
self.qpsk_max=8.5
self.psk8_max=11
self.qam16_max=20
self.tag_added=True
self.index=0;

def handle_msg(self, msg):


self.last_snr=pmt.to_float(msg)
if self.last_snr >= -2 and self.last_snr < self.bpsk_max:
self.selector=0
elif self.last_snr >= self.bpsk_max and self.last_snr < self.qpsk_max:
self.selector=1
elif self.last_snr >= self.qpsk_max and self.last_snr < self.psk8_max:
self.selector=2
else:
self.selector=3
#print(self.last_snr)
if self.selector!=self.last_selector:
self.last_selector=self.selector
#print(self.selector)
self.tag_added=False

def work(self, input_items, output_items):


"""example: multiply with constant"""
if self.tag_added!= True:
self.add_item_tag(0, self.nitems_written(0), pmt.intern('mod'), pmt.from_long(self.selector))
self.tag_added=True
output_items[0][:] = input_items[self.selector]
return len(output_items[0])

(DeMux)
"""
Embedded Python Blocks:

Each time this file is saved, GRC will instantiate the first class it finds
to get ports and parameters of your block. The arguments to _init_ will
be the parameters. All of them are required to have default values!
"""

import numpy as np
from gnuradio import gr
import pmt

class blk(gr.sync_block): # other base classes are basic_block, decim_block, interp_block


"""Embedded Python Block example - a simple multiply const"""

def _init_(self): # only default arguments here


"""arguments to this function show up as parameters in GRC"""
gr.sync_block._init_(
self,
name='DeMux', # will show up in GRC
in_sig=[np.complex64],
out_sig=[np.complex64,np.complex64,np.complex64,np.complex64]
)
self.current_out=1;

def work(self, input_items, output_items):


"""example: multiply with constant"""
index=0;
out_index=[0,0,0,0]
for sample in input_items[0]:
tag = self.get_tags_in_window(0, index, index+1)
if tag!=[] and pmt.to_python(tag[0].key) == 'mod':
#print(tag)
self.current_out=pmt.to_long(tag[0].value)
print(self.current_out)
#output_items[self.current_out][out_index[self.current_out]] = sample
if self.current_out==0:
output_items[self.current_out][index] = sample
output_items[1][index] = 0
output_items[2][index] = 0
output_items[3][index] = 0
elif self.current_out==1:
output_items[self.current_out][index] = sample
output_items[0][index] = 0
output_items[2][index] = 0
output_items[3][index] = 0
elif self.current_out==2:
output_items[self.current_out][index] = sample
output_items[0][index] = 0
output_items[1][index] = 0
output_items[3][index] = 0
else:
output_items[self.current_out][index] = sample
output_items[0][index] = 0
output_items[1][index] = 0
output_items[2][index] = 0
#print(sample)
#out_index[self.current_out]=out_index[self.current_out]+1
index=index+1
'''
tagTuple = self.get_tags_in_window(0, 0, len(input_items[0]))
for tag in tagTuple:
#if tag.key=='mod':
print(pmt.to_long(tag.value))
self.current_out=pmt.to_long(tag.value)
output_items[self.current_out][:] = input_items[0]
'''
return len(output_items[0])
MATLAB CODE
(To compare adaptive vs non-adaptive Modulation)
clc;
close all;
clear all ;
sdb_bpsk = [4.8 4.78 4.72 3.60 3.58 3.42 2.88 2.50 1.02];
sdb_qpsk = [8.48 8.03 7.70 7.59 7.01 6.98 6.56 5.82 5.42];
sdb_8psk = [10.9 10.23 10.11 9.50 9.48 9.32 8.92 8.73 8.54];
sdb_qam16= [18.02 17.83 16.50 16.46 16.08 15.55 14.43 14.09 13.30];
% sdb=[sdb_bpsk,sdb_qpsk,sdb_8psk,sdb_qam16];
sdb_bpsk_1 = flip ( sdb_bpsk );
sdb_qpsk_1 = flip ( sdb_qpsk );
sdb_8psk_1 = flip ( sdb_8psk);
sdb_qam16_1 =flip (sdb_qam16);
sdb_1=[sdb_bpsk_1,sdb_qpsk_1,sdb_8psk_1,sdb_qam16_1];
sdb= flip(sdb_1);
%slin_bpsk = 10.^( sdb_bpsk /10) ;
%slin_qpsk = 10.^( sdb_qpsk /10) ;
%slin_8psk = 10.^( sdb_8psk /10) ;
%slin_qam16 = 10.^( sdb_qam16 /10) ;
slin = 10.^( sdb /10) ;
ber_bpsk = 2*qfunc ( sqrt (2* slin ) ) ;
% ber_qpsk = ber_bpsk ;
ber_qpsk=qfunc ( sqrt (2* slin ) ) ;
ber_8psk = (2/ log2 (8) ) * qfunc ( sqrt (2* slin * log2 (8) )* sin ( pi /8) );
ber_qam16 = (4/ log2 (16) ) *qfunc(sqrt(3*slin*log2(16)/(16-1)));
for i=1:length(sdb)
if sdb(i)<5
ber_adap(i)=ber_bpsk(i);
elseif sdb(i)>5 & sdb(i)<8.5
ber_adap(i)=ber_qpsk(i);
elseif sdb(i)>8.5 & sdb(i)<11
ber_adap(i)=ber_8psk(i);
else
ber_adap(i)=ber_qam16(i);
end
end
figure ;
semilogy ( sdb , ber_bpsk , 'rx -', sdb , ber_qpsk , 'bo -', sdb ,ber_8psk , 'g^ -',sdb ,ber_qam16 , 'c*
-') ;
hold on
semilogy(sdb,ber_adap,'k');
hold off
title ('BER vs SNR plot for PSK schemes ')
xlabel ('SNR dB ')
ylabel ('BER')
legend ('BPSK ', 'QPSK ', '8 PSK ','QAM-16','Adaptive Modulation',Location='southeast');
grid ;

BER Calculation:
MATLAB CODE FOR BER of BPSK

tx1 = fopen("amctx.txt",'rb'); %transmitted data


rx1 = fopen("bpskrx.txt",'rb'); %received data
tx = fread(tx1,Inf,"char");
rx = fread(rx1,Inf,"char");
tx2=tx(1:size(rx));
ber_bpsk = sum(tx2(:)~= rx(:))/numel(tx2(:)); %BER calculated
MATLAB CODE FOR BER of QPSK

tx1 = fopen("amctx.txt",'rb'); %transmitted data


rx1 = fopen("qpskrx.txt",'rb'); %received data
tx = fread(tx1,Inf,"char");
rx = fread(rx1,Inf,"char");
tx2=tx(1:size(rx));
ber_qpsk = sum(tx2(:)~= rx(:))/numel(tx2(:)); %BER calculated

MATLAB CODE FOR BER of 8PSK:

tx1 = fopen("amctx.txt",'rb'); %transmitted data


rx1 = fopen("pskrx.txt",'rb'); %received data
tx = fread(tx1,Inf,"char");
rx = fread(rx1,Inf,"char");
tx2=tx(1:size(rx));
ber_8psk = sum(tx2(:)~= rx(:))/numel(tx2(:)); %BER calculated

MATLAB CODE FOR BER of 16QAM:

tx1 = fopen("amctx.txt",'rb'); %transmitted data


rx1 = fopen("qamrx.txt",'rb'); %received data
tx = fread(tx1,Inf,"char");
rx = fread(rx1,Inf,"char");
tx2=tx(1:size(rx));
ber_qam16 = sum(tx2(:)~= rx(:))/numel(tx2(:)); %BER calculated

You might also like