I was trying to write 4QPSK in Python for my self learning based on the book Digital Modulations Using Python.
When I have my sampling frequency set to 4 times the carrier frequency, I get exactly 4 points in the eye diagram using the inphase and quadrature values. Also I get only 4 unique phases with modulated complex value(s_t)
If I change my sample frequency to multiples of any number (say OF) other than 4, my eye diagram gives me OF number of coordinates.
My code is below. Also demodulation is not providing me with correct value even without introducing any noise. For code given below against given input [1 0 1 1 0 0 0 1], got demodulated output as [1 0 1 1 0 1 0 0]
Please help me correct my mistake.
%matplotlib inline import numpy as np from scipy.signal import upfirdn #NRZ encoder import matplotlib.pyplot as plt baseband_bit_sequence = np.array([1, 0, 1, 1, 0, 0, 0, 1 ]) # Parameters Fc = 10 # Carrier frequency Hertz OF = 16 #Over sampling Factor Fs = OF*Fc # Sampling frequency Hertz (i.e. Number of samples per second) uL = OF*2 #Up Sampling repeat I = baseband_bit_sequence[0::2] Q = baseband_bit_sequence[1::2] #Given Baseband bit sequence is very small. So let we up sample the same to get better visualization #Let we upsample the given baseband_bit_sequence by value uL #The same bit values in baseband_bit_sequence will be repeated uL times I = np.repeat(I, uL)*2 - 1 Q = np.repeat(Q, uL)*2 - 1 #Now we have len(I) Inphase symbols and len(Q) Quadrature symbols (len (I) = len(Q) ) #For a given Sampling frequency Fs, now we have len(I) samples #The duration (in seconds) taken for sending Fs symbol is 1 second becuase Fs is samples per second #The duration (in seconds) taken for sending len(I) symbol is ((len(I)/Fs)*1sec) duration = (len(I)/Fs)*1 #duration = ((len(I) + len(Q))/Fs)*1 #The time taken for sending one symbol is 1/Fs one_symbol_duration = 1/Fs #Time axis for duration D at regular interval of 1/Fs is t = np.arange(0,duration,one_symbol_duration) #time base I_t = I*np.cos((2*np.pi*Fc*t));Q_t = Q*np.sin((2*np.pi*Fc*t)) #Let we do frequency mixing to postive frequency s_t = I_t + Q_t * 1j # QPSK modulated baseband signal print (np.angle(s_t, deg=True)) # I should get only 4 unique phase angle ??? #For eye diagram do not plot all samples #Only desired samples to be plot to get perfect 4 quadrant in eye diagram desired_sample_value_index = int(OF/4) plt.plot(s_t.real[::desired_sample_value_index], s_t.imag[::desired_sample_value_index], 'ro') plt.plot(s_t.real, s_t.imag, 'ro') plt.xlabel('Real Part'), plt.ylabel('Imag part') #QPSK Demodulation x=s_t*np.cos(2*np.pi*Fc*t) # I arm y=s_t*np.sin(2*np.pi*Fc*t) # Q arm x = np.convolve(x,np.ones(uL)) # integrate for L (Tsym=2*Tb) duration y = np.convolve(y,np.ones(uL)) #integrate for L (Tsym=2*Tb) duration x = x[uL-1::uL] # I arm - sample at every symbol instant Tsym y = y[uL-1::uL] # Q arm - sample at every symbol instant Tsym a_hat = np.zeros(2*len(x)) a_hat[0::2] = (x>0) # even bits a_hat[1::2] = (y>0) # odd bits print(a_hat) print(baseband_bit_sequence)