BPSK Signal Modulation and Demodulation in Python
Learn and simulate in Python how communication systems work
In the ever-evolving landscape of digital communication, the need for efficient and reliable data transmission techniques has become paramount. One such technique that has gained significant popularity due to its simplicity is Binary Phase Shift Keying (BPSK) modulation. BPSK is a digital modulation scheme that encodes binary data onto a carrier signal by altering its phase, offering a simple yet powerful method for transmitting information.
In our previous article, we provided an overview of phase shift keying modulation and explored its fundamental concepts. Also, a function to modulate data into a BPSK signal has been proposed. Now, we delve deeper into the world of BPSK demodulation, uncovering its principles and showcasing its application through a Python simulation.
BPSK Modulation
A BPSK modulator gets bits and maps into symbols to be transmitted. For example, in this case we are mapping 0 bits to 1 and 1 bits to -1. Then, symbols are upsampling to get a signal with L samples per symbol. Finally, the symbol signal is multiplied by the carrier. A BPSK modulator scheme is shown below.

A BPSK simulator in Python has ben already presented in the previous article.
import numpy as np
def psk_modulation(bits, samples_per_symbol):
modulation_order = 2
# Define the phase states for the chosen modulation order
phase_states = np.linspace(0, 2*np.pi, modulation_order, endpoint=False)
# Map the bits to the corresponding phase states
phase_sequence = [phase_states[int(b)] for b in bits]
# Generate the continuous phase signal with the desired samples per symbol
phase_signal = np.repeat(phase_sequence, samples_per_symbol)
# Generate the carrier signal
t = np.arange(0,len(phase_signal))/10e3
fc = 0.5e3
carrier_signal = np.sin(2*np.pi*fc*t+phase_signal)
return carrier_signal
# Example inputs
bits = [0, 1, 0, 1, 1, 0] # Sequence of bits
samples_per_symbol = 20 # Number of samples per symbol
# Compute the PSK signal
psk_signal = psk_modulation(bits, samples_per_symbol)It may be seen how the data is modulated in the signal phase. Bits equal to 0 correspond to signal phase = 0, while bits equal to 0 correspond to signal phases = pi/2 radians.

BPSK Demodulation
A BPSK demodulator known as integrate and dump is shown in the figure below. First, the signal is multiplied by the carrier. Then, the signal is integrated over the symbol period. Finally, the integrated signal is sampled every L samples (the samples per symbol of the receiver).

The code to carry out the demodulation is:
import numpy as np
from matplotlib import pyplot as plt
from numpy.lib.stride_tricks import sliding_window_view
def psk_demodulation(signal, samples_per_symbol):
# Generate the carrier signal
t = np.arange(0,len(signal))/10e3
fc = 0.5e3
carrier_signal = np.sin(2*np.pi*fc*t)
# Multiply rx signal by carrier
x = carrier_signal*signal
# Integrate an sample
x = np.sum(sliding_window_view(x, window_shape=samples_per_symbol), axis=1)
symbols = x[::20]
# Get bits from symbols
bits = symbols<0
return bits.astype(int)
demod_data = psk_demodulation(psk_signal, samples_per_symbol)whose output is array([1, 0, 1, 0, 0, 1]), which corresponds to the data used to modulate de PSK signal.
Related articles:






