【信号处理】Python实现BPSK、QPSK、8PSK、8QAM、16QAM、64QAM的调制和解调

简介: 使用Commpy开源包在Python中实现BPSK、QPSK、8PSK、8QAM、16QAM、64QAM等调制和解调方法的具体代码示例,但不包括8QAM的Commpy实现,以及一个完整的编码和解码示例。

1 引言

本文不涉及原理讲解,只提供实现方法。需要借助Commpy开源包去实现通信中的各种处理。

安装方法

方法一
pip install scikit-commpy
方法二
git clone https://github.com/veeresht/CommPy.git
cd CommPy
python setup.py install

2 实现

2.1 调制

import commpy as cpy
bits = np.random.binomial(n=1,p=0.5,size=(128))
Modulation_type ="BPSK"
if Modulation_type=="BPSK":
    bpsk = cpy.PSKModem(2)
  symbol = bpsk.modulate(bits)
  return symbol
elif Modulation_type=="QPSK":
    qpsk = cpy.PSKModem(4)
  symbol = qpsk.modulate(bits)
  return symbol
elif Modulation_type=="8PSK":
    psk8 = cpy.PSKModem(8)
  symbol = psk8.modulate(bits)
  return symbol
elif Modulation_type=="16QAM":
    qam16 = cpy.QAMModem(16)
  symbol = qam16.modulate(bits)
  return symbol
elif Modulation_type=="64QAM":
    qam64 = cpy.QAMModem(64)
  symbol = qam64.modulate(bits)
  return symbol

注意8QAM,不能用Commpy实现,实现如下

import numpy as np
import matplotlib.pyplot as plt
import math

def split_by_len(str, length):
    return [str[i:i+length] for i in range(0, len(str), length)]

def generate_8qam(signal):
    SAMP = 1
    fc = 4
    qam = []
    t = np.arange(0, SAMP)
    wave = []
    for i in range(8):
        if i % 2 == 0:
            amp = 0.5
        else:
            amp = 1
        wave.append(amp * np.exp(1j * (fc * np.pi * t/SAMP + math.floor(i/2) * np.pi/2)))

    s_bits = split_by_len(signal, 3)
    for s in s_bits:
        qam.extend(wave[int('0b' + s, 0)])
    qam = np.array(qam)
    return qam
bits = np.random.binomial(n=1,p=0.5,size=(128,))
if Modulation_type=="64QAM":
    signal = ''
    for i in range(bits.shape[0]):
        signal = signal+str(bits[i])
    symbol = generate_8qam(signal)
      return symbol

2.2 解调

# 和调制一样,需要先定义调制方法的类,再去调用解调的函数。
import commpy as cpy
bits = np.random.binomial(n=1,p=0.5,size=(128))
# Modem : QPSK
modem = mod.QAMModem(4)
signal = modem.modulate(bits)
modem.demodulate(signal, 'hard')

3 完整编码和解码的例子

来源Commpy 例子

# Authors: CommPy contributors
# License: BSD 3-Clause

from __future__ import division, print_function  # Python 2 compatibility

import math

import matplotlib.pyplot as plt
import numpy as np

import commpy.channelcoding.convcode as cc
import commpy.channels as chan
import commpy.links as lk
import commpy.modulation as mod
import commpy.utilities as util

# =============================================================================
# Convolutional Code 1: G(D) = [1+D^2, 1+D+D^2]
# Standard code with rate 1/2
# =============================================================================

# Number of delay elements in the convolutional encoder
memory = np.array(2, ndmin=1)

# Generator matrix
g_matrix = np.array((0o5, 0o7), ndmin=2)

# Create trellis data structure
trellis1 = cc.Trellis(memory, g_matrix)

# =============================================================================
# Convolutional Code 1: G(D) = [1+D^2, 1+D^2+D^3]
# Standard code with rate 1/2
# =============================================================================

# Number of delay elements in the convolutional encoder
memory = np.array(3, ndmin=1)

# Generator matrix (1+D^2+D^3 <-> 13 or 0o15)
g_matrix = np.array((0o5, 0o15), ndmin=2)

# Create trellis data structure
trellis2 = cc.Trellis(memory, g_matrix)

# =============================================================================
# Convolutional Code 2: G(D) = [[1, 0, 0], [0, 1, 1+D]]; F(D) = [[D, D], [1+D, 1]]
# RSC with rate 2/3
# =============================================================================

# Number of delay elements in the convolutional encoder
memory = np.array((1, 1))

# Generator matrix & feedback matrix
g_matrix = np.array(((1, 0, 0), (0, 1, 3)))
feedback = np.array(((2, 2), (3, 1)))

# Create trellis data structure
trellis3 = cc.Trellis(memory, g_matrix, feedback, 'rsc')

# =============================================================================
# Basic example using homemade counting and hard decoding
# =============================================================================

# Traceback depth of the decoder
tb_depth = None  # Default value is 5 times the number or memories

for trellis in (trellis1, trellis2, trellis3):
    for i in range(10):
        # Generate random message bits to be encoded
        message_bits = np.random.randint(0, 2, 1000)

        # Encode message bits
        coded_bits = cc.conv_encode(message_bits, trellis)

        # Introduce bit errors (channel)
        coded_bits[np.random.randint(0, 1000)] = 0
        coded_bits[np.random.randint(0, 1000)] = 0
        coded_bits[np.random.randint(0, 1000)] = 1
        coded_bits[np.random.randint(0, 1000)] = 1

        # Decode the received bits
        decoded_bits = cc.viterbi_decode(coded_bits.astype(float), trellis, tb_depth)

        num_bit_errors = util.hamming_dist(message_bits, decoded_bits[:len(message_bits)])

        if num_bit_errors != 0:
            print(num_bit_errors, "Bit Errors found!")
        elif i == 9:
            print("No Bit Errors :)")

# ==================================================================================================
# Complete example using Commpy features and compare hard and soft demodulation. Example with code 1
# ==================================================================================================

# Modem : QPSK
modem = mod.QAMModem(4)

# AWGN channel
channels = chan.SISOFlatChannel(None, (1 + 0j, 0j))

# SNR range to test
SNRs = np.arange(0, 6) + 10 * math.log10(modem.num_bits_symbol)

# Modulation function
def modulate(bits):
    return modem.modulate(cc.conv_encode(bits, trellis1, 'cont'))

# Receiver function (no process required as there are no fading)
def receiver_hard(y, h, constellation, noise_var):
    return modem.demodulate(y, 'hard')

# Receiver function (no process required as there are no fading)
def receiver_soft(y, h, constellation, noise_var):
    return modem.demodulate(y, 'soft', noise_var)

# Decoder function
def decoder_hard(msg):
    return cc.viterbi_decode(msg, trellis1)

# Decoder function
def decoder_soft(msg):
    return cc.viterbi_decode(msg, trellis1, decoding_type='soft')

# Build model from parameters
code_rate = trellis1.k / trellis1.n
model_hard = lk.LinkModel(modulate, channels, receiver_hard,
                          modem.num_bits_symbol, modem.constellation, modem.Es,
                          decoder_hard, code_rate)
model_soft = lk.LinkModel(modulate, channels, receiver_soft,
                          modem.num_bits_symbol, modem.constellation, modem.Es,
                          decoder_soft, code_rate)

# Test
BERs_hard = model_hard.link_performance(SNRs, 10000, 600, 5000, code_rate)
BERs_soft = model_soft.link_performance(SNRs, 10000, 600, 5000, code_rate)
plt.semilogy(SNRs, BERs_hard, 'o-', SNRs, BERs_soft, 'o-')
plt.grid()
plt.xlabel('Signal to Noise Ration (dB)')
plt.ylabel('Bit Error Rate')
plt.legend(('Hard demodulation', 'Soft demodulation'))
plt.show()
目录
相关文章
|
1月前
|
数据可视化 算法 Python
【数字通信革命】深入剖析Python实现BPSK、QPSK到QAM信号调制的奥秘,解锁高速数据传输的密钥!
【8月更文挑战第2天】在通信系统中,信号调制至关重要,它将信息嵌入载波信号中以便传输。本文通过Python实现三种基本调制技术:BPSK、QPSK和16-QAM,并提供示例代码。首先需安装NumPy、SciPy和Matplotlib库。BPSK是最简单的相位调制,每个符号携带一位信息;QPSK则每个符号携带两位信息,通过四种相位表示;16-QAM结合幅度和相位调制,每个符号携带更多比特信息。本文提供的代码演示了这些调制方式的实现过程,并利用Matplotlib可视化结果。了解这些调制技术有助于深入探索信号处理领域。
80 18
|
1月前
|
Python
【信号处理】python按原理实现BPSK、QPSK、QAM信号调制
本文提供了两种不同的方法来实现16-QAM(正交幅度调制)的调制和解调过程,一种是使用commpy库,另一种是通过手动定义映射字典来实现。
72 8
|
1月前
|
数据可视化 Python
【Python】Python 仿真OFDM发射机、信道和接收机-实现多种调制方式
文章介绍了如何使用Python和Commpy工具包实现OFDM通信系统的仿真,包括发射机、信道和接收机的过程,并支持BPSK、QPSK、8PSK、16QAM、64QAM等多种调制方式,同时展示了导频插入、信道冲击响应、星座映射的可视化,并计算了系统的误比特率。
64 0
|
2月前
|
Python
`scipy.signal`模块是SciPy库中的一个子模块,它提供了信号处理、滤波、频谱分析等功能。这个模块包含了许多用于信号处理的函数和类,其中`butter()`和`filtfilt()`是两个常用的函数。
`scipy.signal`模块是SciPy库中的一个子模块,它提供了信号处理、滤波、频谱分析等功能。这个模块包含了许多用于信号处理的函数和类,其中`butter()`和`filtfilt()`是两个常用的函数。
|
4月前
|
Serverless Python
SciPy信号处理实战:从滤波到频谱分析
【4月更文挑战第17天】本文展示了如何使用Python的SciPy库进行信号处理,包括滤波和频谱分析。首先,通过`scipy.signal`模块实现滤波,如低通滤波器设计和应用,以去除噪声或提取特定频率成分。接着,利用傅里叶变换和`fft`函数进行频谱分析,揭示信号的频率成分和功率分布。通过实例代码,读者可了解从滤波到频谱分析的完整过程,从而在实际项目中有效处理和分析信号。
|
4月前
|
数据可视化 数据挖掘 Python
Scipy 中级教程——信号处理
Scipy 中级教程——信号处理【1月更文挑战第8篇】
127 2
|
4天前
|
Python
Python编程中的异常处理:理解与实践
【9月更文挑战第14天】在编码的世界里,错误是不可避免的。它们就像路上的绊脚石,让我们的程序跌跌撞撞。但是,如果我们能够预见并优雅地处理这些错误,我们的程序就能像芭蕾舞者一样,即使在跌倒的边缘,也能轻盈地起舞。本文将带你深入了解Python中的异常处理机制,让你的代码在面对意外时,依然能保持优雅和从容。
139 73
|
4天前
|
人工智能 数据挖掘 数据处理
揭秘Python编程之美:从基础到进阶的代码实践之旅
【9月更文挑战第14天】本文将带领读者深入探索Python编程语言的魅力所在。通过简明扼要的示例,我们将揭示Python如何简化复杂问题,提升编程效率。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往高效编码世界的大门。让我们开始这段充满智慧和乐趣的Python编程之旅吧!
|
3天前
|
数据采集 机器学习/深度学习 人工智能
Python编程入门:从零基础到实战应用
【9月更文挑战第15天】本文将引导读者从零开始学习Python编程,通过简单易懂的语言和实例,帮助初学者掌握Python的基本语法和常用库,最终实现一个简单的实战项目。文章结构清晰,分为基础知识、进阶技巧和实战应用三个部分,逐步深入,让读者在学习过程中不断积累经验,提高编程能力。
|
4天前
|
机器学习/深度学习 数据采集 人工智能
探索Python的奥秘:从基础到进阶的编程之旅
在这篇文章中,我们将深入探讨Python编程的基础知识和进阶技巧。通过清晰的解释和实用的示例,无论您是编程新手还是有经验的开发者,都能从中获得有价值的见解。我们将覆盖从变量、数据类型到类和对象的各个方面,助您在编程世界里游刃有余。
21 10