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)  

Plt.Show()