Digital Modulation Techniques in Python: Pulse Shaping and QPSK
import numpy as np
T = 1 #time period
Fs = 100 #sampling frequency
t = np.
arange(-3*T, 3*T, 1/Fs)
g = lambda t: np.Sinc(t) * np.Cos(np.Pi*0.5*t) / (1-(2*0.5*t)**2) #Defining a lambda function g(t) that represents a raised cosine filter with a roll-off factor of 0.5.
plt.
Figure(figsize=(8,3))
plt.Plot(t, g(t))
binary_sequence = np.Array(np.Random.Randint(2,size=50))
d = 2 * np.Array(binary_sequence) – 1 #making the binary sequence NRZ
def get_signal(d): #to get transmitted signal
t = np.Arange(-2*T, (len(d)+2)*T, 1/Fs)
g0 = g(1e-8) #normALIZATION FACTOR CALCULATION
xt = np.Sum(d[k] * g(t – k*T) for k in range(len(d)))
return t, xt / g0 #MAGNITUDE OF THE SIGNAL IS PROPERLY ADJUSTED
t, y = get_signal(d) #Y=xt/g0
fig, ax = plt.Subplots(2, 2)
ax[0, 1].Plot(t, y)
ax[0, 1].Set_title(“Pulse shaping”)
x = np.Arange(-T, T, 1/Fs)
for i in range(2*Fs, len(y)-3*Fs, Fs):
ax[1, 1].Plot(x, y[i:i+2*Fs], ‘blue’)
ax[1, 1].Set_title(“Eye diagram”)
ax[0, 0].Step(np.Arange(len(binary_sequence)), binary_sequence)
ax[0, 0].Set_title(“Binary message“)
t = np.Arange(-5, 5, 0.01)
ax[1, 0].Plot(t, g(t))
ax[1, 0].Set_title(“impulse response of RC filter”)plt.Tight_layout()
MATCHED FILTER TO IMPROVE SNR (ASSUME THERE IS NO NOISE)
import numpy as np
import matplotlib.Pyplot as plt
from scipy.Signal import square #you can use any signal
fm = 10
fs = 30*fm
t = np.Arange(0,4/fm,1/fs)
message = np.Sign(square(2*np.Pi*fm*t))
message_flip = np.Sign(np.Flip(square(2*np.Pi*fm*(t+20))))
final = np.Convolve(message,message_flip)
plt.Plot(final)
plt.Show()
BPSK – assuming that phase at 45, -45 degrees and amplitude A at 0 and 2A at 1
import numpy as np
import matplotlib.Pyplot as plt
fm = 10
fc = 20
fs = 30*fc
ncycles = fc/fm
t = np.Arange(0,ncycles/fc,1/fs)
def cosinewave(phase):
if phase == (-1*np.Pi/4):
g = np.Cos(2*np.Pi*fc*t + phase)
if phase == (1*np.Pi/4):
g = 2*np.Cos(2*np.Pi*fc*t + phase)
return list(g)
mod0 = cosinewave(-1*np.Pi/4)
mod1 = cosinewave(1*np.Pi/4)
x = np.Array([0,0,1,0,0,0,0,1]) #21 – you can use any signal here
mod_signal = []
for i in x:
if i == 0:
mod_signal = mod_signal + mod0
elif i == 1:
mod_signal = mod_signal + mod1
plt.Figure(figsize=(20,6))
plt.Plot(mod_signal)
plt.Show()
BCD BPSK
import numpy as np
import matplotlib.Pyplot as plt
fm = 10
fc = 20
fs = 30*fc
ncycles = fc/fm
t = np.Arange(0,ncycles/fc,1/fs)
def cosinewave(phase):
g = np.Cos(2*np.Pi*fc*t + phase)
return list(g)
#phase taken as -60 and 50 – you can choose any other phase
mod0 = cosinewave(-1*np.Pi/3) #-60 degrees
mod1 = cosinewave(5*np.Pi/18) #50 degrees
x = np.Array([0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0]) #OK
mod_signal = []
for i in x:
if i == 0:
mod_signal = mod_signal + mod0
elif i == 1:
mod_signal = mod_signal + mod1
plt.Figure(figsize=(20,6))
plt.Plot(mod_signal)
plt.Show()
# gray 20220919 then qpsk
import numpy as np
import matplotlib.Pyplot as plt
#decimal to gray
def decimal_to_gray(num):
binary=bin(num).Replace(‘0b’,”)
gray=binary[0]
for i in range(1,len(binary)):
gray+=str(int(binary[i]) ^ int(binary[i-1]))
return gray
n=int(input(‘Enter the number: ‘))
print(f’Decimal:{n}–> gray code:{decimal_to_gray(n)}’)
fm=10
fc=20
fs=40*fc
x=decimal_to_gray(n)
str_x=[str(int(i))for i in x]
x=”.Join(str_x)
message= [x[2*i:2*(i+1)]for i in range(int(len(x)/2))]
print(f’the bits after pairing: {message}’)
phase_map={
’00’:-3*np.Pi/4,
’01’:-np.Pi/4,
’10’:3*np.Pi/4,
’11’:np.Pi/4
}
modulated_signal=[]
for m in message:
phase=phase_map[m]
t=np.Arange(0,1/fm,1/fs)
modulated_signal=np.Append(modulated_signal,np.Cos(2*np.Pi*fc*t+phase))
t=np.Arange(0,len(modulated_signal)/fs,1/fs)
plt.Figure(figsize=(12,6))
plt.Plot(t,modulated_signal)
plt.Title(‘QPSK modulated signal’)
plt.Xlabel(‘Time’)
plt.Ylabel(‘Amplitude’)
plt.Show()
MATCHED FILTER TO IMPROVE SNR
import numpy as np
import matplotlib.Pyplot as plt
from scipy.Signal import square #you can use any signal
fm = 10
fs = 30*fm
t = np.Arange(0,4/fm,1/fs)
message = np.Sign(square(2*np.Pi*fm*t))
message_flip = np.Sign(np.Flip(square(2*np.Pi*fm*(t+20))))
final = np.Convolve(message,message_flip)
plt.Plot(final)