4. 软件过流保护算法:数字滤波、有效值计算与自适应阈值

软件过流保护,说白了就是让伺服驱动器的“大脑”——DSP或MCU——自己判断电流是不是超标了。硬件保护像保险丝,动作快但粗暴;软件保护则更精细,能区分是真正的过流还是噪声干扰。我个人习惯把软件过流保护拆成三个环节:先把电流信号洗干净(数字滤波),再算出能反映真实发热或峰值的量(有效值/峰值检测),最后根据工况动态调整保护门限(自适应阈值)。

核心逻辑: 干净的信号 → 准确的特征量 → 合理的阈值。缺一个环节,保护就可能误动或拒动。

4.1 数字滤波算法:把噪声“滤”出去

电流采样信号里总有噪声——开关管动作、电机反电动势、传感器干扰。直接拿原始值做保护,你会被误报警烦死。我在一个高速主轴项目里就吃过这个亏,采样值跳变幅度超过20%,硬件保护没触发,软件却天天报过流。后来加了滤波,世界清净了。

4.1.1 移动平均滤波

移动平均的思路很简单:取最近N个采样点的平均值,作为当前输出。它像一个“滑动窗口”,窗口越大,信号越平滑,但响应也越慢。

// 移动平均滤波示例(C语言伪代码)
#define WINDOW_SIZE 16
uint16_t buffer[WINDOW_SIZE] = {0};
uint8_t index = 0;
uint32_t sum = 0;

uint16_t moving_average(uint16_t new_sample) {
    sum -= buffer[index];          // 减去最旧的值
    buffer[index] = new_sample;    // 存入新值
    sum += new_sample;             // 加上新值
    index = (index + 1) % WINDOW_SIZE;
    return sum / WINDOW_SIZE;      // 返回平均值
}
经验值: 窗口大小N一般取2的幂次(8、16、32),这样除法可以用移位运算,省CPU时间。我常用的窗口是16点,对10kHz采样率来说,延迟约1.6ms,够用。

4.1.2 中值滤波

移动平均对高斯噪声效果好,但对脉冲噪声(比如偶尔一个尖峰)就力不从心了。中值滤波专治这种“野值”——把窗口内的数据排序,取中间那个值。脉冲噪声会被直接扔掉。

// 中值滤波示例(取3点中值,最常用)
uint16_t median_filter_3(uint16_t a, uint16_t b, uint16_t c) {
    if (a > b) { uint16_t t = a; a = b; b = t; }
    if (b > c) { uint16_t t = b; b = c; c = t; }
    if (a > b) { uint16_t t = a; a = b; b = t; }
    return b;  // 中间值
}
注意: 中值滤波的窗口不宜太大,3~5点就够了。窗口太大,计算量暴增,而且会丢失电流波形的细节——你想想看,伺服电流是正弦波,中值滤波窗口太宽会把波峰波谷都抹平,那还怎么检测过流?

4.1.3 两种滤波的对比

特性 移动平均滤波 中值滤波
噪声类型 高斯噪声、随机噪声 脉冲噪声、尖峰干扰
响应速度 较慢(窗口越大越慢) 较快(窗口小)
计算量 低(只需加减和移位) 中等(需要排序)
对波形影响 平滑波形,可能削峰 保留波形边缘,去除野值
推荐场景 稳态电流监测 瞬态电流检测

实际项目中,我经常把两者结合使用:先用中值滤波去掉脉冲噪声,再用移动平均做平滑。这叫“串级滤波”,效果比单用任何一种都好。

4.2 有效值计算与峰值检测

滤波之后,我们需要从干净的电流信号里提取出“特征量”,用来判断是否过流。最常用的两个量是有效值(RMS)和峰值。

4.2.1 有效值(RMS)计算

有效值反映的是电流的发热效应。电机绕组能不能扛住,看的就是有效值。计算公式很简单:先平方,再平均,最后开方。

// 有效值计算(滑动窗口法)
#define RMS_WINDOW 128
int32_t square_sum = 0;
int16_t rms_buffer[RMS_WINDOW] = {0};
uint8_t rms_index = 0;

uint16_t calc_rms(int16_t current_sample) {
    // 减去最旧值的平方
    square_sum -= (int32_t)rms_buffer[rms_index] * rms_buffer[rms_index];
    // 存入新值
    rms_buffer[rms_index] = current_sample;
    // 加上新值的平方
    square_sum += (int32_t)current_sample * current_sample;
    rms_index = (rms_index + 1) % RMS_WINDOW;
    // 返回均方根值(开方用查表法或近似算法)
    return isqrt(square_sum / RMS_WINDOW);
}
工程技巧: 开方运算很费时间。我一般用查表法或牛顿迭代法做近似开方。如果精度要求不高,也可以用“峰值×0.707”来估算正弦波的有效值——但前提是你确定电流波形是正弦的。在伺服系统里,电流波形可能畸变,所以还是老老实实算RMS吧。

4.2.2 峰值检测

有效值保护的是“热”,峰值保护的是“瞬时”。IGBT或MOSFET的短路耐受时间只有几微秒到几十微秒,必须用峰值检测快速响应。

// 峰值检测(带衰减)
int16_t peak_value = 0;
const float decay_factor = 0.99;  // 衰减系数

int16_t detect_peak(int16_t current_sample) {
    int16_t abs_val = abs(current_sample);
    if (abs_val > peak_value) {
        peak_value = abs_val;      // 上升沿跟随
    } else {
        peak_value = (int16_t)(peak_value * decay_factor);  // 缓慢衰减
    }
    return peak_value;
}
我曾经踩过的坑: 峰值检测的衰减系数不能设得太小,否则峰值会“拖尾”,导致过流保护误动作。我一般设0.99~0.999,具体看电流基频。基频越高,衰减要越快,否则峰值会一直保持在高位。

4.3 过流阈值自适应调整策略

固定阈值有个大问题:电机低速时电流大,高速时电流小;重载时电流大,轻载时电流小。如果阈值设死了,要么低速时频繁误报,要么高速时保护失效。自适应调整就是让阈值跟着工况走。

4.3.1 基于转速的阈值调整

电机转速越低,反电动势越小,同样的负载下电流越大。所以阈值应该随转速升高而降低。

// 基于转速的阈值调整
uint16_t base_threshold = 3000;  // 基准阈值(单位:mA)
int16_t rated_speed = 3000;      // 额定转速(单位:rpm)

uint16_t adaptive_threshold_speed(int16_t current_speed) {
    // 转速越低,阈值越高;转速越高,阈值越低
    float factor = 1.0 + (float)(rated_speed - current_speed) / rated_speed * 0.5;
    if (factor < 0.8) factor = 0.8;  // 下限
    if (factor > 1.5) factor = 1.5;  // 上限
    return (uint16_t)(base_threshold * factor);
}

4.3.2 基于电流变化率的阈值调整

有时候电流突变不是故障,而是负载突变。比如机械手抓取工件时,电流会瞬间增大。这时候如果阈值不变,就会误报。我建议根据电流变化率(di/dt)动态抬高阈值,给系统一个“容忍窗口”。

// 基于电流变化率的阈值调整
int16_t last_current = 0;
uint16_t threshold_dynamic = 3000;

void update_threshold_by_didt(int16_t current) {
    int16_t delta = current - last_current;
    if (abs(delta) > 500) {  // 电流变化超过500mA
        // 临时抬高阈值,持续50ms后恢复
        threshold_dynamic = 4500;
        // 启动定时器,50ms后恢复
    } else {
        threshold_dynamic = 3000;
    }
    last_current = current;
}
关键点: 自适应调整不是无限放宽保护。它只是在确认“这不是故障”的前提下临时放宽。一旦确认是真正的过流(比如持续超限),必须立即触发保护动作。

4.4 知识体系总览

下面这张图把本章的核心逻辑串起来了。你可以看到,从原始采样到最终保护动作,中间经过了滤波、特征提取、阈值判断三个环节。每个环节都有多种选择,具体用哪种,取决于你的应用场景。

软件过流保护算法知识体系 原始电流采样 数字滤波 移动平均滤波 中值滤波 特征提取 有效值(RMS) 峰值检测 阈值判断与自适应调整
我的建议: 不要试图在一个项目里把所有算法都用上。先搞清楚你的主要噪声来源是什么,再选对应的滤波方法;先确定保护目标是“热保护”还是“瞬时保护”,再选RMS还是峰值。贪多嚼不烂,这是我在好几个项目里用加班换来的教训。