2、编码器选型与信号处理:编码器类型对比、分辨率选择、信号抖动处理、Z信号校准

编码器这东西,说白了就是运动控制系统的「眼睛」。眼睛不好使,你算法写得再漂亮也没用。我在现场调试过不下百台设备,至少有一半的抖动问题,追根溯源都是编码器选型或信号处理没做好。

这一章,我把自己踩过的坑、积累的经验,一次性倒给你。

2.1 编码器类型对比:增量式 vs 绝对值

先解决最基础的问题:选增量式还是绝对值?

我个人的习惯是,先问自己三个问题:

  • 断电后需不需要记住位置?
  • 现场干扰大不大?
  • 成本预算有多少?

下面这张表,是我自己整理的核心对比,你直接拿去用:

对比项 增量式编码器 绝对值编码器
断电记忆 不支持(需找零) 支持(单圈/多圈)
抗干扰能力 一般(脉冲易丢失) 强(数字通讯)
接线复杂度 简单(A/B/Z三路) 稍复杂(通讯线+电源)
成本 高(尤其多圈)
典型应用 通用伺服、步进 机器人、数控机床

嗯,这里要注意:增量式编码器虽然便宜,但每次上电都得找零位。我见过一个项目,操作员忘了回零,直接撞了夹具,损失好几万。所以,如果你的设备有安全风险,别省那点钱,上绝对值。

2.2 分辨率选择:不是越高越好

很多新手容易犯一个错:分辨率越高越好。其实不是。

分辨率高,意味着每圈脉冲数多,位置反馈更精细。但代价是什么?

  • 信号频率高,对控制器高速计数口要求高
  • 容易受干扰,抖动更明显
  • 线缆成本、屏蔽要求都上去了

我一般按这个经验公式来选:

分辨率(线数) ≥ 2 × 系统定位精度 / 丝杠导程

举个例子:你要定位精度0.01mm,丝杠导程10mm,那分辨率至少是 2 × 0.01 / 10 = 0.002圈,换算成脉冲就是 500线。留点余量,选1000线就够用了。

我曾经在一个贴片机项目里,选了5000线的编码器,结果控制器根本跑不满速度,脉冲频率太高,CPU直接卡死。后来换成2000线,反而跑得稳稳的。

小技巧: 如果控制器支持4倍频(AB相计数),实际分辨率可以乘以4。比如1000线编码器,4倍频后就是4000脉冲/圈。

2.3 信号抖动处理:别让噪声毁了你的精度

信号抖动,是运动控制里最让人头疼的问题之一。你想想看,电机明明停在那里,位置反馈却在±1个脉冲之间跳,速度环能不抖吗?

抖动来源主要有三个:

  1. 电气噪声:变频器、开关电源的干扰
  2. 机械振动:联轴器松动、导轨间隙
  3. 信号反射:长线传输时阻抗不匹配

我处理抖动的三板斧:

第一板斧:硬件滤波

在编码器信号线上加RC低通滤波器。我常用的参数是:电阻100Ω,电容100pF。注意,电容不能太大,否则会把有效信号也滤掉。

// 伪代码:软件滤波示例
// 滑动平均滤波,窗口大小建议4-8
#define FILTER_WINDOW 4
int buffer[FILTER_WINDOW];
int index = 0;
long sum = 0;

int filter(int new_value) {
    sum -= buffer[index];
    buffer[index] = new_value;
    sum += buffer[index];
    index = (index + 1) % FILTER_WINDOW;
    return sum / FILTER_WINDOW;
}

第二板斧:软件去抖

在中断服务程序里做「连续采样确认」。比如连续读到3次相同的值,才认为信号有效。这招对付随机毛刺特别管用。

第三板斧:屏蔽与布线

编码器线必须用双绞屏蔽线,屏蔽层单端接地。我见过一个案例,现场把编码器线和动力线绑在一起走,结果脉冲丢得乱七八糟。分开走之后,问题立刻消失。

警告: 千万不要在编码器线上用普通电线!屏蔽层接地要可靠,接地电阻小于4Ω。否则,干扰会从地线串进来。

2.4 Z信号校准:找到那个唯一的零点

增量式编码器每圈会输出一个Z脉冲(零位脉冲)。这个脉冲很关键,它是我们建立绝对位置参考的唯一依据。

Z信号校准的流程,我一般分三步走:

  1. 硬件触发:将Z信号接入控制器的高速捕获口(CAP或Z相输入)
  2. 软件对齐:在电机上电后,低速转动直到捕获到第一个Z脉冲,记录当前位置为机械零点
  3. 偏差补偿:如果机械安装有偏差,在软件里做偏移量补偿

我曾经遇到一个情况:Z信号总是捕获不到。查了半天,发现是编码器安装时,Z脉冲刚好被机械挡块遮住了。后来调整了安装角度,问题解决。

这里给一个实用的Z信号捕获代码片段:

// Z信号捕获与零点校准
volatile int z_captured = 0;
volatile long z_position = 0;

void Z_Interrupt_Handler() {
    // 捕获到Z脉冲,记录当前计数值
    z_position = encoder_counter;
    z_captured = 1;
    
    // 清除计数器,准备下一圈
    encoder_counter = 0;
}

void calibrate_zero() {
    // 等待Z信号
    while(!z_captured) {
        // 低速转动电机
        motor_run_slow();
    }
    
    // 零点已建立
    system_zero = z_position;
    printf("零点校准完成,位置: %ld\n", system_zero);
}
关键点: Z信号校准必须在电机低速下进行。速度太快,控制器可能来不及响应,导致捕获位置偏差。我一般控制在10rpm以内。

2.5 本章知识体系

下面这张图,是我自己画的编码器选型与信号处理的核心逻辑。你一看就明白:

编码器选型与信号处理知识体系 编码器选型与信号处理 类型对比 分辨率选择 信号抖动处理 Z信号校准 增量式 绝对值 精度公式 4倍频 硬件滤波 软件去抖 硬件捕获 软件对齐

这张图把四个核心模块串起来了。你从类型对比开始,确定用增量式还是绝对值;然后根据精度需求选分辨率;接着处理信号抖动;最后用Z信号建立绝对参考。每一步都踩实了,系统才能跑得稳。


好了,编码器这块就聊到这儿。记住一句话:编码器是系统的眼睛,别让它近视了。下一章我们聊控制器选型与接口匹配,到时候见。

公众号:蓝海资料掘金营,微信deep3321