Software Receiver Design Tutorial 0

B E G I N N I N G   S O F T W A R E   R E C E I V E R 

D E S I G N

Tutorial 0

Abstract
The goal of Software Receiver Design is to transmit a digital data, like a text string, and use DSP techniques to condition and receive the data. The data is pulse amplitude modulated. I will attach my Python code to convert strings to these discrete amplitudes. The goal of this post is to generate the baseband signal. 

I'm writing these posts as I am also trying to create a software receiver system. I branched by GitHub project when I wrote all the files necessary to accomplish just this aspect of it. I'm trying to reduce the overwhelming-ness of sorting through a plethora of software files.

Get the files: tutorial0

Pulse Amplitude Modulation - PAM
I typed Python commands into iPython one by one to show how I convert 'hello world' into pulse amplitude modulation. I did the best I could to make it understandable.

Educational Python Code:
~/Documents/Python/SoftwareReceiverDesign/HTML/letters2pam_edu.py.html
        s = 'dead'
        print ['{:08b}'.format(ord(c)) for c in s ]
        # >>
        # ['01100100', '01100101', '01100001', '01100100']

        print [list('{:08b}'.format(ord(c))) for c in s ]
        # >>
        # [['0', '1', '1', '0', '0', '1', '0', '0'], 
        #  ['0', '1', '1', '0', '0', '1', '0', '1'], 
        #  ['0', '1', '1', '0', '0', '0', '0', '1'], 
        #  ['0', '1', '1', '0', '0', '1', '0', '0']]

        print [np.reshape(list('{:08b}'.format(ord(c))),(4,2)).tolist() for c in s ]
        # >>
        # [[['0', '1'], 
        #   ['1', '0'], 
        #   ['0', '1'], 
        #   ['0', '0']], 
        #  [['0', '1'], 
        #   ['1', '0'],
        #   ['0', '1'], 
        #   ['0', '1']], 
        #  [['0', '1'], 
        #   ['1', '0'], 
        #   ['0', '0'], 
        #   ['0', '1']], 
        #  [['0', '1'], 
        #   ['1', '0'], 
        #   ['0', '1'], 
        #   ['0', '0']]]

        print [[''.join(pair) for pair in np.reshape(list('{:08b}'.format(ord(c))),(4,2)).tolist()] for c in s ]
        # >>
        # [['01', '10', '01', '00'], ['01', '10', '01', '01'], ['01', '10', '00', '01'], ['01', '10', '01', '00']]

        # convert each bit pair to a decimal number, these will represent amplitudes
        print [[int(''.join(pair),2) for pair in np.reshape(list('{:08b}'.format(ord(c))),(4,2)).tolist()] for c in s ]
        # >>
        # [[1, 2, 1, 0], [1, 2, 1, 1], [1, 2, 0, 1], [1, 2, 1, 0]]

        # shift and scale each number to -3, -1, 1, 3
        print [[int(''.join(pair),2)*2-3 for pair in np.reshape(list('{:08b}'.format(ord(c))),(4,2)).tolist()] for c in s ]
        # >>
        # [[-1, 1, -1, -3], [-1, 1, -1, -1], [-1, 1, -3, -1], [-1, 1, -1, -3]]

        # combine all the elements into one list with itertools
        import itertools
        print list(itertools.chain(*[[int(''.join(pair),2)*2-3 for pair in np.reshape(list('{:08b}'.format(ord(c))),(4,2)).tolist()] for c in s ]))
        # >>
        # [-1, 1, -1, -3, -1, 1, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3]


Next, in order to make an analog signal, the pulses have to be turned into an analog signal. The most straightforward way to do this is to represent each data point with a scaled rectangular pulse, but this would make the signal's spectrum very spread out.

Generating the Transmission Signal
The below figure represents the goal of what we are trying to do. 
  • subplot(3,1,1) plots the discrete PAM pulses.
  • subplot(3,1,2) plots the PAM sequence upsampled by zero padding with 100 zeros. 
  • subplot(3,1,3) plots the convolution of the pulse train with a 101 point hamming window.
Python code to create the above figure:
~/Documents/Python/SoftwareReceiverDesign/pulseshape.py.html
from scipy.signal import convolve, hamming
import numpy as np
import matplotlib.pyplot as plt
import pdb
from letters2pam import letters2pam

def pulseshape(signal, M, debug = False):
        mup = np.zeros(M*len(signal))
        mup[np.arange(0,len(mup),M)] = signal
        mup_analog = convolve(hamming(M), mup)

        if debug:
                plt.subplot(311)
                plt.stem(signal)
                plt.title('Data Sequence')
                plt.subplot(312)
                plt.plot(mup)
                plt.title('Oversampling')
                plt.subplot(313)
                plt.plot(mup_analog)
                plt.title('Convolution with Pulse Shape')
                plt.show(block=True)
        return mup_analog

if __name__ == '__main__':
        pulseshape(letters2pam('hell'), 101, True)

No comments:

Post a Comment