☀️手把手教你Python+matplotlib模拟锁相放大器的原理以及工作过程☀️《❤️记得收藏❤️》

Posted 苏州程序大白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了☀️手把手教你Python+matplotlib模拟锁相放大器的原理以及工作过程☀️《❤️记得收藏❤️》相关的知识,希望对你有一定的参考价值。

目录

🏳️‍🌈开讲啦!!!!🏳️‍🌈苏州程序大白🏳️‍🌈

🌟博主介绍

💂 个人主页:苏州程序大白

🤟作者介绍:中国DBA联盟(ACDU)成员,CSDN全国各地程序猿(媛)聚集地管理员。目前从事工业自动化软件开发工作。擅长C#、Java、机器视觉、底层算法等语言。2019年成立柒月软件工作室。

💬如果文章对你有帮助,欢迎关注、点赞、收藏(一键三连)和C#、Halcon、python+opencv、各大公司面试等一些订阅专栏哦

💅 有任何问题欢迎私信,看到会及时回复

👤 微信号:stbsl6,微信公众号:苏州程序大白

🎯 想加入技术交流群的可以加我好友,群里会分享学习资料

前言

我们先讲讲锁相放大器的基本结构示于下方图 ,包括信号通道、参考通道、相敏检测器 PSD 和低通滤波器 LPF 等。 各个模块的基本功能描述如下:

  • 1、信号通道: 对信号输入进行放大及滤波, 将微弱信号放大到足以推动相敏检测器工作的电平, 并且要滤除部分干扰和噪声。

  • 2、参考输入: 一般是等幅正弦或者方波信号, 它可以是从外部输入的某种周期信号,也可以是系统内原先用于调制的载波信号或用于斩波的信号。

  • 3、参考通道: 对参考输入进行放大或衰减, 以适应相敏检测器对幅度的要求。参考通道的另一个重要功能是对参考输入进行相位锁定及移相等处理,从而产生同频正弦波与余弦波,以提供给相敏检波器进行乘法运算。相敏检波器(PSD): 以参考通道提供的基准正弦与余弦分量作为输入, 对经过信号通道放大滤波的 进行相敏检波(乘法运算), 从而实现检波。

  • 4、 如下方图所示频谱迁移过程。将 的频谱由 处迁移到 处,再经 LPF 滤除噪声, 其输出 对 的幅度和相位都敏感,这样就达到了既鉴幅又鉴相(相位及幅度的测量)的目的。

  • 5、低通滤波器(LPF): 频带可以做得很窄, 所以可使锁相放大器达到较大的 SNIR。 锁相放大器的应用大致分为以下领域:测量噪声中的微弱信号:

  • 红外分光光度计,2次量子光分光分析,光声光谱仪,超导材料的评价,金属材料的张力试验,放大器的CMRR或IMRR测量。

  • 测量被测定体传输函数的微小变化:俄歇电子能谱,金属探测器,涡流探伤器。被测定体的矢量分析:RLC测量仪,电解-阻抗,电子束测量。

python实现模拟锁相放大器

首先引入需要用到的package,使用%matplotlib widget可以产生交互式的图片。

import numpy as np
from scipy.fftpack import fft
from scipy import signal as sg
from matplotlib import pyplot as plt

%matplotlib widget

matplotlib绘图

在本文中将会产生许多的图片,为了方便绘图编写一个展示信号的绘图函数。

def draw(x, y, title='', xlable='time(s)', ylable='amplitude', L=-3.8, H=3.8):
    '''
    draw

    Parameters
    ----------
        x : numpy array
            abscissa
        y : numpy array
            ordinate

    Returns
    -------
    '''
    # canvas settings
    plt.close()
    if L!=H:
        plt.ylim(L, H)
    plt.title(title)
    plt.xlabel(xlable)
    plt.ylabel(ylable)

    plt.plot(x, y)
    plt.show()

绘画正弦波

采用正弦波作为输入信号。另外,参考信号、噪声信号等都需要用到正弦信号,所以第一步将编写一个产生给定幅度、频率和相位的正弦信号的函数。

def g_sin(t=1, amp=1, f0=10, fs=500, phi=0):
    '''
    generate sinusoid

    Parameters
    ----------
        t   : float
            time length of the generated sequence
        amp : float
            amplitude
        f0  : float
            frequency of sinusoid in Hz
        fs  : float
            sampling rate per second
        phi : float
            initial phase in deg

    Returns
    -------
        anonymous : list[numpy array, numpy array]
            [abscissa, a sinusoid signal]
    '''
    T = 1/fs
    N = t/T
    x = 2*np.pi*np.arange(N)*T
    return [np.arange(0, t, T), amp*np.sin(f0*x+phi*np.pi/180)]


x, y = g_sin()
draw(x, y)

绘画方波

参考信号可以使用正弦波、方波等。在本实验中将使用方波,而方波的傅里叶级数为:
  
所以我们可以利用上面的正弦波函数,产生一个近似的方波,方波的阶数(即K)越大近似效果越好,K=50时就有很好的效果。 (PS:此处方波均指占空比为50%,正负对称的方波)

def g_square_wave(t=1, amp=1, f0=10, fs=500, K=50):
    '''
    generate square wave

    Parameters
    ----------
        t   : float
            time length of the generated sequence
        amp : float
            amplitude
        f0  : float
            frequency of sinusoid in Hz
        fs  : float
            sampling rate per second
        K   : int
            order of fourier series

    Returns
    -------
        anonymous : list[numpy array, numpy array]
            [abscissa, a square wave]
    '''
    T = 1/fs
    N = t/T
    x = 2*np.pi*np.arange(N)*T

    y = np.zeros(len(x))
    k = 2*np.arange(1, K)-1
    for i in range(len(x)):
        y[i] = amp*np.sum(np.sin(k*f0*x[i])/k)
    return [np.arange(0, t, T), 4*y/np.pi]


x, y = g_square_wave()
draw(x, y)


使用上述两个函数,可以叠加产生带有噪声的信号。

x, y1 = g_sin(amp=0.2, f0=30)
x, y2 = g_sin(amp=0.35, f0=3, phi=45)
x, y3 = g_square_wave(amp=0.1, f0=10)
draw(x, y1+y2+y3)

绘画频域分析

这些噪声在时域中难以分辨。不过信号与噪声不同,往往具有明显的频率特征,而噪声一般是与频率无关的,或者是在特定频率范围内的,所以在频域内可以很好的分辨出输入信号的各种成分。

使用快速傅里叶变换(FFT)从时域转化到频域,并且对振幅谱进行取半归一化。

def FFT(s, fs):
    '''
    fast fourier transform

    Parameters
    ----------
        s  : numpy array
            signal
        fs : float
            sampling rate per second

    Returns
    -------
    '''
    X  = fft(s)
    mX = np.abs(X)   # magnitude
    pX = np.angle(X) # phase

    draw(np.arange(int(fs/2)), mX[range(int(fs/2))]/fs, 
         'Input signal in frequency domain', 'frequency(Hz)', 'amplitude', 0, 0)


FFT(y1+y2+y3, 500)

绘画高斯白噪声

上面的信号添加的噪声还是正弦信号,而现实中比较常见的噪声是白噪声。下面的函数可以根据输入信号产生一个特定信噪比的白噪声。

信噪比的定义是:

在本实验中,功率 P P P可以用功 ‘ W = ∫ P d t = C ∫ A 2 d t `W=\\int Pdt=C\\int A^2dt W=Pdt=CA2dt`代替,因为信号和噪声的积分时间是相同的。而信号的波形是采样得到的,所以 W W W可以用 ∑ x i 2 \\sum x_i^2 xi2代替,于是有:

def wgn(x, snr):
    '''
    generate Gauss white noise
    
    Parameters
    ----------
        x   : numpy array
            signal
        snr : float
            signal-to-noise ratio
        
    Returns
    -------
        anonymous : numpy array
            Gauss white noise
    '''
    snr    = 10**(snr/10.0)
    xpower = np.sum(x**2)/len(x)
    npower = xpower / snr
    return np.random.randn(len(x)) * np.sqrt(npower)


noise = wgn(np.sin(np.arange(0, 1000000)*0.1), 6)
plt.close()
plt.subplot(211)
plt.hist(noise, bins=100)
plt.subplot(212)
plt.psd(noise)
plt.show()

模拟锁相放大器的工作过程

下面开始正式的模拟过程:

获得输入信号,输入信号由10Hz的目标信号和其他频率的正弦噪声以及白噪声组成

A、 增加正弦部分

x, y1  = g_sin(amp=0.1)
x, y2  = g_sin(amp=0.5, f0=50)
x, y3  = g_sin(amp=0.8, f0=3)
x, y4  = g_sin(amp=0.3, f0=200)
signal = y1+y2+y3+y4

B、增加白噪声部分

noise = wgn(signal, 10)
sn    = signal+noise
draw(x, sn)


C、 查看输入信号的频域信息

FFT(sn, 500)


获得参考信号,方波频率与目标信号相同,为10Hz

x, y   = g_square_wave(K=100)
square = y
draw(x, square)


3、前置放大×2倍

sn = sn*2
draw(x, sn)


4、输入信号进行带通滤波,除去/抑制部分噪声,增强锁相放大器的性能(动态储备和输出动态范围)

b, a = sg.butter(1, [0.02, 0.12], 'bandpass') # 5Hz - 30Hz
snq  = sg.filtfilt(b, a, sn)
draw(x, snq)


5、调谐放大输入信号×5,增大信噪比

b, a = sg.butter(1, [0.038, 0.042], 'bandpass') # 9.5Hz - 10.5Hz
sns  = sg.filtfilt(b, a, snq)
snq  = sns*4+snq
draw(x, snq)


6、PSD(相敏检波器)处理输入与参考信号(本质为乘法器)

snqx = snq*square
draw(x, snqx)

FFT(snqx, 500)


7、低通滤波,减少其他信号对直流分量的影响(等效噪声宽度很小)

b, a = sg.butter(3, 0.00004, 'lowpass') # 0 - 0.01Hz
sns  = sg.filtfilt(b, a, snqx)
draw(x, sns)


8、直流放大×5

sns = sns*5
draw(x, sns)

🌟8、作者相关的文章、资源分享🌟

🌟让天下没有学不会的技术🌟

学习C#不再是难问题

🌳《C#入门到高级教程》🌳

有关C#实战项目

👉C#RS232C通讯源码👈

👉C#委托数据传输👈

👉C# Modbus TCP 源代码👈

👉C# 仓库管理系统源码👈

👉C# 欧姆龙通讯Demo👈

👉C# 欧姆龙通讯Demo👈

👉2021C#与Halcon视觉通用的框架👈

✨有关C#项目欢迎各位查看个人主页✨

🌟机器视觉、深度学习🌟

🌌《Halcon入门到精通》🌌

🌌《深度学习资料与教程》🌌

有关机器视觉、深度学习实战

👉2021年C#+HALCON视觉软件👈

👉2021年C#+HALCON实现模板匹配👈

👉C#集成Halcon的深度学习软件👈

👉C#集成Halcon的深度学习软件,带[MNIST例子]数据集👈

👉C#支持等比例缩放拖动的halcon WPF开源窗体控件👈

👉2021年Labview联合HALCON👈

👉2021年Labview联合Visionpro👈

👉基于Halcon及VS的动车组制动闸片厚度自动识别模块👈

✨有关机器视觉、深度学习实战欢迎各位查看个人主页✨

🌟Java、数据库教程与项目🌟

🍏《JAVA入门到高级教程》🍏

🍏《数据库入门到高级教程》🍏

有关Java、数据库项目实战

👉Java经典怀旧小霸王网页游戏机源码增强版👈

👉Java物业管理系统+小程序源码👈

👉JAVA酒店客房预定管理系统的设计与实现SQLserver👈

👉JAVA图书管理系统的研究与开发mysql👈

✨有关Java、数据库教程与项目实战欢迎各位查看个人主页✨

🌟分享Python知识讲解、分享🌟

🥝《Python知识、项目专栏》🥝

🥝《Python 检测抖音关注账号是否封号程》🥝

🥝《手把手教你Python+Qt5安装与使用》🥝

🥝《用一万字给小白全面讲解python编程基础问答》🥝

🥝《Python 绘制android CPU和内存增长曲线》🥝

有关Python项目实战

👉Python基于Django图书管理系统👈

👉Python管理系统👈

👉2021年9个常用的python爬虫源码👈

👉python二维码生成器👈

✨有关Python教程与项目实战欢迎各位查看个人主页✨

🌟分享各大公司面试题、面试流程🌟

🍏《2021年金九银十最新的VUE面试题☀️《❤️记得收藏❤️》》🍏

🍏《只要你认真看完一万字☀️Linux操作系统基础知识☀️分分钟钟都吊打面试官《❤️记得收藏❤️》》🍏

🍏《❤️用一万字给小白全面讲解python编程基础问答❤️《😀记得收藏不然看着看着就不见了😀》》🍏

✨有关各大公司面试题、面试流程欢迎各位查看个人主页✨

🏳️‍🌈关注苏州程序大白,持续更新技术分享。谢谢大家支持🏳️‍🌈


❤️关注苏州程序大白公众号❤️


👇 👇👇

以上是关于☀️手把手教你Python+matplotlib模拟锁相放大器的原理以及工作过程☀️《❤️记得收藏❤️》的主要内容,如果未能解决你的问题,请参考以下文章

❤️手把手教你做一个爱情保温软件❤️——python封装.exe文件+爬虫(每日情话系列)

❤️python表白神器手把手教你用代码浪漫追求对象!❤️(附完整源码+讲解)

还不会Python数据可视化? 手把手教你用 Matplotlib 实现数据可视化(珍藏版)

手把手教你做一个python+matplotlib的炫酷的数据可视化动图

☀️手把手教你用 C# 下载文件的十八般武艺☀️《❤️记得收藏❤️》

☀️手把手教你HALCON在VS2017中搭建C++环境☀️《❤️记得收藏❤️》