I want to create a python model of a transmitter. The transmitter uses a biphase line code, which looks like this (from a datasheet):
Additionally, the datasheet states that the signal is "passed through a bandpass filter which conditions the signal for the line by limiting the spectral content from 0.2 fBaud to 1.6 fBaud <...> The resulting transmit signal will have a distributed spectrum with a peak at 3/4 fBaud."
The resulting pulses at the actual transmitter output look like this:
How can I adequately reproduce this resulting signal shape in python?
What I've tried:
- Put square pulses through bandpass filter: I would expect it to give me the desired result, but I couldn't figure out the correct implementation.
- Imitate the pulse shape by combining sine waves with different frequencies: it looks very similar in comparison with the actual signal, but it doesn't feel adequate.
Results:
Python code:
import numpy as np
from scipy import signal as sig
import matplotlib.pyplot as plot
from random import randint
from math import sin, pi
data_f = 16 * 10**6 # freq of samples
symbol_f = 320 * 10**3 # freq of symbols
T = int(data_f/symbol_f) # period of symbols
N = 15 # number of symbols
# sequence of random numbers
symbols = np.zeros(N, dtype=np.float32)
for i in range(N):
value = randint(1, 2)
if value==1: symbols[i] = -1
elif value==2: symbols[i] = 1
# bi-phase line coding
biphase_symbols = np.zeros(2*N, dtype=np.float32)
biphase_symbols[0] = symbols[0]
biphase_symbols[1] = -biphase_symbols[0]
for i in range(1,N):
if symbols[i] == symbols[i-1]: biphase_symbols[i*2] = biphase_symbols[i*2-1]
else: biphase_symbols[i*2] = -biphase_symbols[i*2-1]
biphase_symbols[i*2+1] = -biphase_symbols[i*2]
N = 2*N
symbols = biphase_symbols
# Option 1. Square pulses with band pass filter
signal1 = np.zeros((N*T), dtype=np.float32)
for i in range(N):
signal1[T*i:T*i+T-1] = symbols[i]
nyq = 0.5 * data_f
lowcut = 0.2 * symbol_f / nyq
highcut = 1.6 * symbol_f / nyq
order=6
sos = sig.butter(order, [lowcut, highcut], btype='band', output='sos')
signal1 = sig.sosfilt(sos, signal1)
# Option 2. Combination of sin waves
signal2 = np.zeros((N*T), dtype=np.float32)
i = 0
while (True):
if i>= N-1: break
if symbols[i] == symbols[i+1]:
for j in range(2*T):
index = T*i+j
signal2[index] = symbols[i] * (sin(pi*j/(2*T))+sin(3*pi*j/(2*T))/3)
i+=2
else:
for j in range(T):
index = T*i+j
signal2[index] = symbols[i] * (sin(pi*j/(T)))
i+=1
fig,myplot = plot.subplots(2, 1)
myplot[0].plot(signal1)
myplot[0].set_xlabel('Time')
myplot[0].set_ylabel('Amplitude')
myplot[0].grid(True)
myplot[1].plot(signal2)
myplot[1].set_xlabel('Time')
myplot[1].set_ylabel('Amplitude')
myplot[1].grid(True)
plot.tight_layout()
plot.show()