3、电流检测法(上):直流分量法、交流分量法、阈值设定策略

各位工程师朋友,咱们接着聊堵转检测。上一章讲了反电动势法,今天换个思路——直接从电流信号里找线索。

电流检测法,说白了就是盯着电机绕组的电流波形。电机正常转和堵转时,电流的“长相”完全不一样。我最早做水泵项目时,就靠这招救过急。当时反电动势法在低速下根本没法用,换成电流检测,问题迎刃而解。

这一节我们重点拆解两种经典方法:直流分量法和交流分量法。最后再聊聊阈值怎么设才靠谱。

3.1 直流分量法:看平均值的变化

直流分量法,思路很直接——监测相电流的平均值(直流偏置)。

电机正常运行时,三相电流基本对称,平均值接近零。一旦堵转,电流会急剧增大,平均值也会明显偏离零点。

核心逻辑:

  • 正常运转:三相电流对称 → 直流分量 ≈ 0
  • 堵转状态:电流不对称或饱和 → 直流分量 ≠ 0

具体怎么算?我习惯用滑动窗口平均,或者一阶低通滤波。代码实现很简单:

// 一阶低通滤波计算直流分量
#define ALPHA 0.05f   // 滤波系数,越小越平滑

float dc_component = 0.0f;

float calc_dc_component(float current_sample)
{
    dc_component = dc_component * (1.0f - ALPHA) + current_sample * ALPHA;
    return dc_component;
}

嗯,这里要注意——滤波系数 ALPHA 很关键。太大,噪声滤不干净;太小,响应太慢。我一般取 0.01~0.1 之间,具体看你的采样率和系统带宽。

我的经验:

直流分量法对采样偏置非常敏感。如果 ADC 本身有 10mV 的偏置,算出来的直流分量可能一直不为零。我建议先做一次“零电流校准”——电机不转时,把采样值记下来,后面做减法。

3.2 交流分量法:看波形的“抖动”

直流分量法有个短板——如果电机带重载启动,电流本来就大,直流分量一直很高,堵转和正常负载就分不清了。

这时候,交流分量法就派上用场了。

交流分量法不看平均值,看的是电流的波动幅度。正常运行时,电流波形比较平滑,波动小。堵转时,转子卡住,电流波形会出现剧烈的“毛刺”或振荡,交流分量明显增大。

怎么提取交流分量?很简单——用原始采样值减去直流分量:

float ac_component = 0.0f;

float calc_ac_component(float current_sample)
{
    float dc = calc_dc_component(current_sample);
    float ac = current_sample - dc;          // 交流分量 = 瞬时值 - 直流分量
    ac_component = sqrtf(ac * ac);           // 取绝对值或RMS
    return ac_component;
}

你想想看,堵转时电流波形会变成什么样?

  • 正常运转:正弦波,平滑,交流分量小
  • 堵转瞬间:电流突变,波形畸变,交流分量骤增
  • 持续堵转:电流可能进入限流模式,波形变平,交流分量反而下降

所以交流分量法更适合检测堵转发生的瞬间,而不是持续堵转状态。

避坑提醒:

我曾经在一个风机项目里只用交流分量法,结果发现启动瞬间电流冲击也会触发误判。后来加了一个“启动抑制窗口”——启动后 200ms 内不检测交流分量,问题就解决了。

3.3 两种方法的对比

我把两种方法的核心差异整理成了一张表,方便你对照选型:

对比维度 直流分量法 交流分量法
检测对象 电流平均值偏移 电流波动幅度
适用场景 持续堵转、稳态检测 堵转瞬间、动态检测
抗噪声能力 强(低通滤波后) 弱(对毛刺敏感)
对采样偏置敏感度 高 低
计算开销 低 中(需要平方根)
误判风险 重载启动时易误判 启动冲击时易误判

我个人习惯是两种方法结合使用。直流分量法做稳态监测,交流分量法做瞬态触发,互补短板。

3.4 阈值设定策略:别拍脑袋

方法选好了,阈值怎么设?这是很多工程师容易翻车的地方。

阈值设得太低,正常运行时频繁误报警;设得太高,堵死了都检测不出来。我见过有人直接拍脑袋写个固定值,结果换一批电机就全废了。

正确的做法是自适应阈值。核心思路:

  1. 空载标定:电机空载运行时,记录直流分量和交流分量的基线值
  2. 负载标定:带额定负载运行时,记录正常波动范围
  3. 阈值计算:阈值 = 基线值 + 安全裕量 × 波动范围

代码实现参考:

typedef struct {
    float baseline_dc;      // 空载直流基线
    float baseline_ac;      // 空载交流基线
    float noise_floor;      // 噪声底限
    float threshold_dc;     // 直流阈值
    float threshold_ac;     // 交流阈值
} StallThreshold_t;

void calibrate_threshold(StallThreshold_t *th, float dc, float ac)
{
    th->baseline_dc = dc;
    th->baseline_ac = ac;
    th->noise_floor = ac * 0.2f;          // 20% 噪声裕量
    th->threshold_dc = dc * 1.5f;         // 1.5倍基线
    th->threshold_ac = ac * 3.0f;         // 3倍基线,交流波动更大
}

我的经验值:

  • 直流分量阈值:基线值的 1.3~1.8 倍
  • 交流分量阈值:基线值的 2.5~4.0 倍
  • 如果系统噪声大,建议先做硬件滤波,别全靠软件扛

3.5 知识体系总览

下面这张图把电流检测法的核心逻辑串起来了,你可以对照着理解:

电流检测法知识体系 电流检测法 直流分量法 交流分量法 低通滤波提取平均值 适合持续堵转检测 瞬时值减直流分量 适合堵转瞬间检测 阈值设定策略 空载标定 → 负载标定 → 自适应阈值

3.6 实际项目中的避坑清单

最后,我把自己踩过的坑整理成了一份清单,你写代码时对照着检查:

  • 采样率别太低:电流检测至少需要 5~10kHz 的采样率,否则交流分量根本抓不住
  • 滤波延迟要算清楚:低通滤波会引入延迟,堵转检测响应时间可能变慢
  • 启动阶段要屏蔽:电机启动瞬间电流冲击很大,建议加 100~300ms 的检测抑制窗口
  • 温度漂移别忽略:MOSFET 和采样电阻的温度系数会导致基线漂移,建议做温度补偿
  • 多相联合判断:别只看一相电流,三相联合判断更可靠

我曾经踩过的坑:

有一次做直流无刷水泵,直流分量法阈值设了 1.5 倍基线。结果夏天水温高,绕组电阻变大,空载电流本身就高了 30%,阈值直接失效。后来我改成动态基线——每隔 10 秒重新标定一次空载值,问题才解决。