光谱分析仪spectrumAnalyzer
EngeeDSP库包括一个用于评估和可视化信号谱的高级工具,即spectrumAnalyzer系统对象。 让我们来看看它的应用程序的各种信号的频谱分析的任务的基本场景,也学习如何改变一个对象的参数。
频谱估计的方法
在本节中,我们将了解EngeeDSP的主要参数。spectrumAnalyzer对象,以及,特别是,与可用的频谱估计方法-滤波器组和韦尔奇方法。
第一测试信号:
首先,让我们创建一个测试信号。 x 进行分析。 这是两个正弦和高斯噪声的总和。 信号的采样率 Fs 它等于20MHz,正弦曲线的主要频率为2MHz和4MHz(频率较高的正弦曲线的振幅为0.25)。 同样重要的是要注意,对于分析,我们选择了一个持续时间为 nsamp =40,000计数。
Fs = 20e6;
dt = 1/Fs;
nsamp = 40000;
t = 0:dt:(nsamp*dt)-dt;
f1 = 2e6;
f2 = 4e6;
x = sin.(2*pi*f1*t) .+ 0.25*sin.(2*pi*f2*t) + randn(length(t));
plot(t,x, xlim = (0,t[200]), leg = false)
让我们确保信号在整个长度上在零附近波动。 使用函数 std 图书馆工程:
EngeeDSP.Functions.std(x)
我们正在观察一个接近于零的数学期望。
光谱分析系统对象
创建系统对象 scope1 类型EngeeDSP.spectrumAnalyzer。 我们将明确指定一些参数,即采样率。 SampleRate 和频谱表示(单侧)。 我们将默认保留其他参数值。
scope1 = EngeeDSP.spectrumAnalyzer();
scope1.SampleRate = Fs;
scope1.PlotAsTwoSidedSpectrum = false;
scope1
显示了可用于修改的参数的广泛列表,但现在我们将注意频谱估计方法的参数。 Method = "filter-bank",显示类型为"功率谱" SpectrumType = "power", ViewType = "spectrum",以及设置频率分辨率 RBWSource 在值 "auto".
如果你申请一个变量的"输入" scope1 我们的测试信号 x,然后自动显示信号功率谱图。 顺便说一下,图形的名称和轴标签也是系统对象的参数。 设置字段值 Title,并调用对象:
scope1.Title = "spectrumAnalyzer-两个正弦,滤波器组";
scope1(x)
滤波器组是一组复盖所研究的整个频率范围的多个滤波器(通常是带通滤波器)。 许多实际设备,频谱分析仪,使用滤波器组将信号分成多个频段。 这允许您更详细地分析信号频谱,因为它被分成子信道(在分析库中),然后可以恢复(在合成库中)。
你可以阅读更多关于方法[这里](https://kit-e.ru/bank-czifrovyh-filtrov /)。
在变量中记录光谱样本
功能 getSpectrumData 允许您以矢量或矩阵的形式获取频谱值的数值样本。 到字典 spectrumdata 我们将放置频率的值和功率谱的样本。 然后我们将使用变量显示频谱 f1 和 s1 在标准图形上,函数 plot. 现在,我们可以以交互和编程方式评估功率水平和与测试正弦曲线相对应的峰值位置。:
spectrumdata = EngeeDSP.getSpectrumData(scope1);
f1 = spectrumdata["frequencies"];
s1 = spectrumdata["spectrum"];
plot(f1,s1,leg=false)
韦尔奇方法
Welch方法是基于快速傅立叶变换(FFT)估计信号频谱的基本方法之一。 它被广泛用于大多数光谱分析任务,特别是当处理不是实时进行和易于配置是重要的。
让我们创建频谱分析仪的另一个系统对象 scope2 但这次我们将指定韦尔奇方法作为评估的主要方法。 我们还将更改参数,以便我们可以显式控制频率分辨率。 RBW,并将其值设置为20,000hz。
scope2 = EngeeDSP.spectrumAnalyzer();
scope2.SampleRate = Fs;
scope2.PlotAsTwoSidedSpectrum = false;
scope2.Method = "welch";
scope2.RBWSource = "property";
scope2.RBW = 2e4;
scope2.Title = "spectrumAnalyzer-两个正弦曲线,welch,RBW=2e4";
scope2(x)
让我们使用两种方法比较功率谱估计值,并将结果显示在一个图形上。:
welchdata = EngeeDSP.getSpectrumData(scope2);
f2 = welchdata["frequencies"];
s2 = welchdata["spectrum"];
plot(f1,s1, label = "filter-bank")
plot!(f2,s2, label = "welch", title = "方法的比较")
通过在使用Welch方法时改变频率分辨率,还可以观察到噪声电平的变化。 当使用滤波器组方法时,重要的是监测信号的持续时间,并且当短的"段"到达时,累积它们以进行能量的准确评估。
非平稳信号的频谱
让我们使用spectrumAnalyzer对象的功能来评估频率成分随时间变化的信号的频谱。 用于这种分析的典型信号是频率调制的。
让我们创建一个频率随时间线性增加的信号,即具有线性频率调制(lfm)的信号。 为此,请使用函数 chirp 来自EngeeDSP图书馆:
LFM = EngeeDSP.Functions.chirp(t,0,t[end],7e6);
plot(t,LFM, xlim = (0,t[2000]), label = "的LFM信号")
信号频率 LFM 在"模拟"期间从0到7MHz线性增加。
现在让我们创建另一个频谱分析仪对象并命名它 chirpscope. 我们将在括号中初始化期间立即设置其参数。 注意诸如平均方法和"遗忘"系数、FFT参数(点数、窗口大小)、Welch方法的重叠百分比以及窗口函数的类型等参数。 由此产生的图形形状取决于它们。
chirpscope = EngeeDSP.spectrumAnalyzer(
SampleRate = Fs,
Method = "welch",
SpectrumType = "power",
AveragingMethod = "exponential",
ForgettingFactor = 0.99,
Window = "hamming",
WindowLength = 1024,
OverlapPercent = 75,
FrequencyResolutionMethod = "window-length",
FFTLengthSource = "property",
FFTLength = 1024,
PlotAsTwoSidedSpectrum = false,
FrequencySpan = "full",
ReferenceLoad = 1)
chirpscope.Title = "光谱分析仪-LCHM"
chirpscope(LFM)
通过这些参数,我们观察到LFM信号频谱的预期形状,它占据了从0到7MHz的频带。 然而,不可能在这样的图上观察光谱随时间变化的动态。
频谱图
使用频谱图在频域中显示非平稳信号的频谱是很有用的。 为此,我们需要更改对象的一些参数。 chirpscope:
release!(chirpscope)
chirpscope.ViewType = "spectrogram";
chirpscope.ForgettingFactor = 0.2;
chirpscope.RBWSource = "property";
chirpscope.RBW = 1e5;
chirpscope.TimeSpanSource = "property";
chirpscope.TimeSpan = 0.012;
chirpscope.Colormap = "parula";
chirpscope.Title = "光谱分析仪-LFM,光谱图";
chirpscope(LFM)
频谱的累积和平均
在处理流式信号时,用于对在信号的相继时间间隔上计算的频谱进行累加和平均的技术用于更精确地评估所研究的有用频谱分量的能量并降低噪声。 让我们看看dynamics中的这个过程。
SineWaveDSP系统对象
让我们创建一个新的测试信号,现在使用EngeeDSP库的另一个系统对象-正弦源**SineWaveDSP。**此对象允许您按顺序生成未中断的正弦信号段。 在我们的例子中,我们将把长输入信号分成5,000个样本的片段(参数 fSz):
fSz = 5000;
sig1 = EngeeDSP.SineWaveDSP();
sig1.Amplitude = 1;
sig1.Frequency = 4e6;
sig1.SampleTime = 1/Fs;
sig1.SamplesPerFrame = fSz;
sig2 = EngeeDSP.SineWaveDSP();
sig2.Amplitude = 0.25;
sig2.Frequency = 6e6;
sig2.SampleTime = 1/Fs;
sig2.SamplesPerFrame = fSz;
plot(sig1() + sig2() + randn(fSz), xlim = (0,100), label = "SineWaveDSP")
当我们使用滤波器组方法分析噪声信号的相对"短"段时,我们无法准确估计峰值能量,并且我们还观察到频谱中的高噪声水平。:
release!(scope1)
scope1(sig1() + sig2() + randn(fSz))
在实际设备中,信号以精确的缓冲段顺序进入分析仪输入,为了正确的评估,必须对其进行累加。
SpectrumAnalyzer系统对象支持各种频谱平均方法。 让我们考虑动态中平均的累积。 为此,我们将创建一个动画,顺序调用带有加性高斯噪声的正弦源的系统对象,并通过对象估计频谱 scope1:
release!(scope1)
anim = @animate for i = 1:30
scope1(sig1() + sig2() + randn(fSz));
tempdata = EngeeDSP.getSpectrumData(scope1);
tempf = tempdata["frequencies"];
temps = tempdata["spectrum"];
plot(tempf,temps, ylim = (-25,25), leg = false, title = "频谱平均,滤波器组")
end
gif(anim, "spectrum_averaging.gif", fps = 5)
我们看到噪声水平逐渐降低,以及对峰值水平的准确评估的近似值。
结论
我们熟悉了EngeeDSP库的spectrumAnalyzer系统对象的基本功能。 我们研究了其初始化和调用的语法,设置其参数的具体细节,并观察了它们对评估各种测试信号光谱的结果的影响。
.png)
.png)
.png)
.png)
.png)
.gif)