看似125Hz的875Hz信号
一句话总结
仅凭采样点中看到了 125Hz,不能说原来的输入也是 125Hz。分别改变观测时钟、模拟滤波器和数值收敛,确认能区分到什么程度。
为什么需要它
太空温室的传感器负责人报告说,每次打开风扇都会产生 125Hz 的振动。在前一个单元中,通过延长 ADC 的采集时间,减少了上一个通道的记忆。可是这一次,即使电压已经充分建立,奇怪的频率也没有消失。风扇真的含有 125Hz 的成分吗?还是把快速的振动用较慢的节奏去观测,换了一个名字在看?
采集时间的问题,问的是一次采样是否足够接近目标电压。混叠的问题,问的是不同的连续信号是否可能产生相同的采样序列。前者是减小每个采样点误差的问题,后者是因观测而丢失了可区分性的问题。增加位数,或者多输出几位小数,并不能同时解决这两个问题。
Analog Devices 的输入滤波器 FAQ说明,带外成分在采样之后会折叠进关注频段,而且无法把这种成分与原来频段内的信号区分开。这里不止步于引用这一原理,而是生成两个真实的 ngspice 输出文件并加以对照。这不是向设备施加电压的实验。
工作原理
有两个时钟
仿真器计算电路的时间间隔,与我们从结果中抽取采样点的间隔是不同的。ngspice 为了求解电路方程,会保留一些时间点。不能把波形文件的行号当作 ADC 时钟。由于第一个区间的微小时间间隔或内部自适应计算,行间隔可能与观测周期不同。
这次的电路是 1V 幅度的余弦输入、串联的 1kΩ 电阻,以及接地的电容。有电容时,截止频率 fc=1/(2πRC),比较 300Hz 和 80Hz。无滤波用 10¹²Ω 的负载来代替电容。因为这个负载,增益在数学上并不恰好为 1,但这个差异远小于这次的容差。
ngspice 官方教程说明了用网表定义电路,并把瞬态分析结果以文件处理的流程。提供的辅助程序只负责这件事。挑选采样点、计算频谱、判定条件的部分,要自己编写。所用的版本是镜像中附带的 ngspice42,不假定与网页文档中安装的版本相同。
电路计算的最大间隔 dt 是 2µs 和 1µs,总长度是 90ms。观测起点是 24ms,采样点数是 64 个。把观测率 fs 从 1000Hz 改为 4000Hz 时,也要真正地改变 tᵢ=0.024+i/fs。1kHz 观测的最后一个采样点是 87ms,4kHz 观测是 39.75ms。只把同样的 64 个数字的频率轴放大四倍,并不是新的测量。
如果原始文件中没有准确的观测时刻,就对紧邻前后两行的输出电压做线性插值。必须选择的是滤波器之后的 v(out),而不是输入列 v(in)。拒绝随意延伸范围之外的外推。即使文件在中途中断,只因为有一部分所需的采样点,也不能生成正常的报告。会提供一个加载器,先确认是否为完整的 90ms 波形。
不同的频率获得相同名称的原因
实数信号的第一奈奎斯特区间是 0 到 fs/2。对正的输入频率 f,求 r=f mod fs,则该区间内的观测频率是 min(r,fs−r)。当 fs=1000 时,125、875、1125、1875Hz 都会折叠到 125Hz。如果只用 abs(fs−f),在第一个相邻区间中看起来是对的,但在更远的区间中就会出错。
请代入余弦的采样点。cos(2π(fs−f)i/fs)=cos(2πi−2πfi/fs)=cos(2πfi/fs)。这次的起点 24ms 与两个输入的相位也一致,所以无滤波的 125Hz 和 875Hz 的采样序列在数值容差之内重合。这并不意味着在任意的起点、相位、滤波器下,采样序列总是相同。因为 RC 滤波器不仅会改变幅度,也会改变相位。
因此,比较函数不只看频谱的最大幅度。在确认相同的 fs、起点和采样点数之后,求每个采样点的最大绝对差。幅度频谱会丢掉相位信息。例如,符号相反的余弦具有相同的幅度频谱,但采样序列并不相同。这里 indistinguishable 这个名称,意味着在指定的观测和 100µV 的容差之内无法区分。
为什么要亲手计算 DFT
对 64 个采样点 xᵢ,计算 Zₖ=(1/N)Σxᵢ exp(−j2πki/N)。第 k 个频点的频率是 kfs/N。实数信号的单边结果只保留 k=0..N/2。内部频点的幅度是 2|Zₖ|,但 DC 和奈奎斯特频点是 |Zₖ|。如果把两个端点也无条件地乘以 2,就会夸大恒定电压和符号交替变化的信号的幅度。
在 1kHz 下,频点间隔是 15.625Hz,125Hz 位于第 8 个频点。在 4kHz 下,间隔是 62.5Hz,125Hz 位于第 2 个频点,875Hz 位于第 14 个频点。两种观测都选择为信号周期恰好整数次落入 DFT 窗口。这个条件称为相干采样(coherent sampling)。多亏了这一点,才能不与窗函数校正或频点之间的峰值估计混在一起,而专门学习混叠本身。
如果频率与频点不吻合,能量可能扩散到多个频点上。这时,不能只把最大频点的幅度当作原信号的幅度。这次分析约定中的两个输入对,限定为 [125,875] 和 [375,625]。为了不给无信号时的浮点残渣贴上频率名称,最大幅度在 1µV 以下时,peak_hz 为 null。这是这次的报告约定,并不是通用的传感器检测极限。
有滤波器与满足要求是两回事
一阶 RC 的稳态增益是 G(f)=1/√(1+(f/fc)²)。这个 f 是实际进入滤波器的原始频率。如果把 875Hz 换成已经折叠的 125Hz 再计算 RC 增益,就把滤波与采样的顺序弄反了。
假设希望保留 125Hz 的幅度不低于 0.9V,并把干扰的 875Hz 减小到 0.1V 以下。两个输入的幅度都是 1V。解析公式的四舍五入值如下。在实际运行的报告中,填入的不是计算值,而是从文件中观测到的值。
| 条件 | 期望的 125Hz 幅度 | 干扰的 875Hz 幅度 | 是否同时满足? |
|---|---|---|---|
| 无滤波 | 约 1.000V | 约 1.000V | 否 |
| fc=300Hz | 约 0.923V | 约 0.324V | 否 |
| fc=80Hz | 约 0.539V | 约 0.091V | 否 |
80Hz 的滤波器虽然减小了干扰,但也把期望的信号削弱得太多。三个候选中都没有答案,那就继续寻找第四个 fc 吗?整理不等式,通带条件是 fc≥125/√(1/0.9²−1),阻带条件是 fc≤875/√(1/0.1²−1)。分别约为 258.09Hz 以上和 87.94Hz 以下。两个区间不重叠,所以这个要求无法由任何单个 RC 满足。
这不是实验的失败,而是设计结论。不能为了填满候选列表,而放宽容差或偷偷改变要求条件。在下一次设计中,应当审查滤波器阶数、观测率、输入频带假设等。只是这次三个滤波器失败的表格,与整个单个 RC 区间的交集为空的证明,是强度不同的依据。
分别汇报数值精度与设计适用性
把同一个电路分别用 dt=2µs 和 1µs 求解,检查在两个观测率下采样点之差是否在 100µV 以内。然后确认四份报告的频率和幅度是否符合折叠公式与 RC 解析公式。收敛并不意味着电路正确。即使是接错的输入列,缩小时间间隔后也可能稳定地收敛到同一个错误答案。
最后,确认期望频带与干扰频带的要求是否都满足。报告要把是否收敛、模型是否一致、设计要求,保留为独立的字段。运行错误作为错误,正常分析后没有可采用的滤波器时,则保留为空的候选。如果把两者合并,就无法区分是需要更换模型,还是需要修复运行环境。
在现场相遇的样子
在处理传感器、音频、振动数据的团队中,如果发现了低频峰值,就先确认输入频带、滤波器的位置和真实的采样时钟。不要只相信文件里写的 sample_rate 这个数字,而要同时留下时间戳和采集配置。分析自动化的价值,不仅在于快速绘制图形,还在于无论谁重新运行,都能对照相同的条件。
Analog Devices 的理想 ADC 混叠说明区分了过采样与模拟、数字滤波器各自的作用。对于已经折叠进关注频段的干扰,仅靠数字低通是无法挑出并去除的。不声称运行了该页面的 Java 小程序,只参考其说明的原理。真正的计算依据是这次保存的波形。
这次的结果是关于理想 RC 和均匀采样的。噪声、量化、时钟抖动、非线性 ADC、有源滤波器的稳定性、随温度变化的元件变化,都不在模型中。因此不把它扩大为实际电路板的性能认证或安全判定。前一阶段的采集开关模型,也没有自动合并到这次的电路中。要把不同实验的结论结合起来,必须先验证模型的连接部分。
下一项实验要做什么
在 8 个步骤中,依次制作折叠函数、时间插值、单边 DFT、文件分析、采样点比较、RC 要求区间、滤波器判定、条件比较 CLI。同时阅读辅助程序生成的网表、配置、日志、原始波形,以及自己制作的 JSON 报告。最后的课题是:把在 1kHz 下无法区分的输入,用 4kHz 重新观测并加以区分,并说明单个 RC 的空候选为什么是正当的结论。