【信号处理】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()
目录
相关文章
|
3月前
|
数据可视化 算法 Python
【数字通信革命】深入剖析Python实现BPSK、QPSK到QAM信号调制的奥秘,解锁高速数据传输的密钥!
【8月更文挑战第2天】在通信系统中,信号调制至关重要,它将信息嵌入载波信号中以便传输。本文通过Python实现三种基本调制技术:BPSK、QPSK和16-QAM,并提供示例代码。首先需安装NumPy、SciPy和Matplotlib库。BPSK是最简单的相位调制,每个符号携带一位信息;QPSK则每个符号携带两位信息,通过四种相位表示;16-QAM结合幅度和相位调制,每个符号携带更多比特信息。本文提供的代码演示了这些调制方式的实现过程,并利用Matplotlib可视化结果。了解这些调制技术有助于深入探索信号处理领域。
140 18
|
3月前
|
Python
【信号处理】python按原理实现BPSK、QPSK、QAM信号调制
本文提供了两种不同的方法来实现16-QAM(正交幅度调制)的调制和解调过程,一种是使用commpy库,另一种是通过手动定义映射字典来实现。
231 8
|
3月前
|
数据可视化 Python
【Python】Python 仿真OFDM发射机、信道和接收机-实现多种调制方式
文章介绍了如何使用Python和Commpy工具包实现OFDM通信系统的仿真,包括发射机、信道和接收机的过程,并支持BPSK、QPSK、8PSK、16QAM、64QAM等多种调制方式,同时展示了导频插入、信道冲击响应、星座映射的可视化,并计算了系统的误比特率。
143 0
|
4月前
|
Python
`scipy.signal`模块是SciPy库中的一个子模块,它提供了信号处理、滤波、频谱分析等功能。这个模块包含了许多用于信号处理的函数和类,其中`butter()`和`filtfilt()`是两个常用的函数。
`scipy.signal`模块是SciPy库中的一个子模块,它提供了信号处理、滤波、频谱分析等功能。这个模块包含了许多用于信号处理的函数和类,其中`butter()`和`filtfilt()`是两个常用的函数。
|
6月前
|
Serverless Python
SciPy信号处理实战:从滤波到频谱分析
【4月更文挑战第17天】本文展示了如何使用Python的SciPy库进行信号处理,包括滤波和频谱分析。首先,通过`scipy.signal`模块实现滤波,如低通滤波器设计和应用,以去除噪声或提取特定频率成分。接着,利用傅里叶变换和`fft`函数进行频谱分析,揭示信号的频率成分和功率分布。通过实例代码,读者可了解从滤波到频谱分析的完整过程,从而在实际项目中有效处理和分析信号。
|
6月前
|
数据可视化 数据挖掘 Python
Scipy 中级教程——信号处理
Scipy 中级教程——信号处理【1月更文挑战第8篇】
257 2
|
10天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
3天前
|
存储 人工智能 数据挖掘
从零起步,揭秘Python编程如何带你从新手村迈向高手殿堂
【10月更文挑战第32天】Python,诞生于1991年的高级编程语言,以其简洁明了的语法成为众多程序员的入门首选。从基础的变量类型、控制流到列表、字典等数据结构,再到函数定义与调用及面向对象编程,Python提供了丰富的功能和强大的库支持,适用于Web开发、数据分析、人工智能等多个领域。学习Python不仅是掌握一门语言,更是加入一个充满活力的技术社区,开启探索未知世界的旅程。
12 5
|
3天前
|
人工智能 数据挖掘 开发者
探索Python编程:从基础到进阶
【10月更文挑战第32天】本文旨在通过浅显易懂的语言,带领读者从零开始学习Python编程。我们将一起探索Python的基础语法,了解如何编写简单的程序,并逐步深入到更复杂的编程概念。文章将通过实际的代码示例,帮助读者加深理解,并在结尾处提供练习题以巩固所学知识。无论你是编程新手还是希望提升编程技能的开发者,这篇文章都将为你的学习之旅提供宝贵的指导和启发。
|
8天前
|
数据处理 Python
从零到英雄:Python编程的奇幻旅程###
想象你正站在数字世界的门槛上,手中握着一把名为“Python”的魔法钥匙。别小看这把钥匙,它能开启无限可能的大门,引领你穿梭于现实与虚拟之间,创造属于自己的奇迹。本文将带你踏上一场从零基础到编程英雄的奇妙之旅,通过生动有趣的比喻和实际案例,让你领略Python编程的魅力,激发内心深处对技术的渴望与热爱。 ###

热门文章

最新文章