谐波检测与测量技术
做谐波治理这些年,我最大的感触就是:测不准,就治不好。你想想看,连敌人长什么样、在哪、有多少都不知道,这仗怎么打?谐波检测,就是我们电力电子工程师的“雷达”和“望远镜”。这一章,我把压箱底的经验拿出来聊聊。
傅里叶变换FFT原理与窗函数选择
FFT,说白了就是把时域信号拆成频域信号。我习惯把它比作“分拣机”——把一堆混在一起的频率分量,一个个挑出来。
但这里有个坑:频谱泄露。为什么会有泄露?因为FFT假设信号是周期无限的,可我们只能采样有限长的一段。截断信号时,就像用剪刀“咔嚓”一下,边缘不连续,频谱就“漏”了。
核心要点:窗函数就是用来“软化”这个截断过程的。选对了窗,谐波测量就成功了一半。
我个人常用的窗函数有这几种:
| 窗函数 | 主瓣宽度 | 旁瓣衰减 | 适用场景 |
|---|---|---|---|
| 矩形窗 | 最窄 | -13dB | 瞬态信号、整周期采样 |
| 汉宁窗 | 较宽 | -32dB | 一般谐波分析(我最常用) |
| 布莱克曼窗 | 最宽 | -58dB | 需要高精度幅值测量 |
| 凯塞窗 | 可调 | 可调 | 兼顾主瓣与旁瓣 |
我的经验:做并网变流器谐波检测,我一般先用汉宁窗。它旁瓣衰减够用,主瓣宽度也能接受。如果遇到间谐波(比如5.5次谐波),我会换成布莱克曼窗,虽然计算量大点,但精度有保障。
代码实现其实不复杂。我贴一段实际项目里用过的:
// 汉宁窗函数生成
void hanning_window(float *data, int N) {
for (int i = 0; i < N; i++) {
data[i] *= 0.5 * (1 - cos(2 * PI * i / (N - 1)));
}
}
// FFT计算(使用标准库)
void fft_compute(complex *input, int N) {
// 先加窗
hanning_window((float*)input, N);
// 再调用FFT库
fft(input, N);
}
注意:加窗会损失信号能量,幅值需要修正。汉宁窗的幅值恢复系数是2.0,布莱克曼窗是2.38。我刚开始做时忘了这步,结果谐波幅值全偏小,查了半天才找到原因。
同步采样与锁相环PLL
同步采样,就是让ADC的采样时钟和电网频率严格同步。为什么这么重要?因为FFT要求采样频率是信号频率的整数倍,否则就会频谱泄露。
我见过不少工程师直接用固定采样率(比如12.8kHz)去采50Hz电网。电网频率稍微波动到50.1Hz,谐波测量就开始“跳舞”了。嗯,这里要注意:电网频率不是恒定的。
锁相环PLL就是解决这个问题的。它实时跟踪电网相位,动态调整采样时钟。我常用的PLL结构是SRF-PLL(同步参考坐标系锁相环):
// SRF-PLL 简化实现
typedef struct {
float theta; // 输出相位
float omega; // 输出频率
float kp, ki; // PI参数
float integral; // 积分项
} pll_t;
void pll_update(pll_t *pll, float v_alpha, float v_beta) {
// Park变换
float vd = v_alpha * cos(pll->theta) + v_beta * sin(pll->theta);
float vq = -v_alpha * sin(pll->theta) + v_beta * cos(pll->theta);
// PI调节
float error = vq; // 锁相目标:vq = 0
pll->integral += pll->ki * error;
float delta_omega = pll->kp * error + pll->integral;
// 更新相位
pll->omega = 2 * PI * 50 + delta_omega;
pll->theta += pll->omega * dt;
}
关键参数:PLL的PI参数决定了动态响应和稳态精度。带宽太宽,抗噪差;带宽太窄,跟踪慢。我一般取kp=100,ki=5000,带宽约20Hz,兼顾了速度和稳定性。
我曾经在一个光伏并网项目里,电网频率从49.8Hz跳到50.2Hz,PLL没跟上,导致谐波测量全乱套。后来加了前馈补偿,把电网频率变化率也考虑进去,才稳住。
谐波幅值、相位、相序的精确测量
FFT输出的是复数,幅值和相位都在里面。但实际测量时,有几个细节要注意:
- 幅值校准:ADC的增益误差、互感器的变比误差,都要校准。我习惯在出厂前用标准源打一遍,生成校准系数表。
- 相位补偿:互感器本身有相移,尤其是电流互感器,高频下相移更大。我一般在50Hz下测一次,再在250Hz(5次谐波)下测一次,做线性插值补偿。
- 相序判断:正序、负序、零序,决定了谐波是“推”还是“拉”。我常用对称分量法,把三相电压/电流分解成三序分量。
// 对称分量法计算(以5次谐波为例)
void sequence_calc(complex *va, complex *vb, complex *vc,
complex *v1, complex *v2, complex *v0) {
complex a = { -0.5, 0.866 }; // 旋转因子 e^(j120°)
complex a2 = { -0.5, -0.866 };
// 正序:V1 = (Va + a*Vb + a2*Vc) / 3
*v1 = complex_add(*va, complex_add(complex_mul(a, *vb), complex_mul(a2, *vc)));
v1->real /= 3; v1->imag /= 3;
// 负序:V2 = (Va + a2*Vb + a*Vc) / 3
*v2 = complex_add(*va, complex_add(complex_mul(a2, *vb), complex_mul(a, *vc)));
v2->real /= 3; v2->imag /= 3;
// 零序:V0 = (Va + Vb + Vc) / 3
*v0 = complex_add(*va, complex_add(*vb, *vc));
v0->real /= 3; v0->imag /= 3;
}
避坑指南:我曾经在测量5次谐波相位时,发现结果总是差180度。后来查了半天,原来是电流互感器二次侧接线反了。所以,接线前一定要核对同名端,别问我怎么知道的。
实际项目中的电流/电压互感器选型
互感器选型,看着简单,其实门道很多。我总结了几条铁律:
- 精度等级:谐波测量至少用0.5级,最好用0.2级。我见过用3级互感器测谐波的,那数据基本没法看。
- 频率响应:普通互感器只保证50Hz精度,测到20次谐波(1000Hz)就衰减严重。要选宽频型,比如0.5级/50Hz~2kHz。
- 饱和特性:电流互感器最怕饱和。一旦饱和,二次电流波形畸变,谐波测量全错。我一般选额定电流的1.2倍作为拐点,留足裕量。
- 相移特性:电压互感器相移小,电流互感器相移大。选型时要看厂家给的相移曲线,最好在50Hz和250Hz两个点都确认。
| 参数 | 电压互感器 | 电流互感器 |
|---|---|---|
| 精度等级 | 0.2级 | 0.5级 |
| 频率范围 | 50Hz~2kHz | 50Hz~2kHz |
| 额定值 | 100V/√3 | 5A或1A |
| 相移@50Hz | <5' | <30' |
| 相移@250Hz | <15' | <60' |
重要提醒:电流互感器二次侧绝对不允许开路!开路会产生高压,击穿绝缘,甚至伤人。我每次调试前都会检查二次回路是否闭合,这已经成了肌肉记忆。
好了,谐波检测这块,核心就是“测准”二字。FFT选对窗,PLL锁住相,互感器选对型,再加上校准和补偿,基本就能拿到靠谱的数据。下一节,我们聊聊怎么用这些数据去设计滤波器。
公众号:蓝海资料掘金营,微信deep3321