共计 1453 个字符,预计需要花费 4 分钟才能阅读完成。
问题现象
刚接触电机编码器时,最让人困惑的往往是信号质量问题。用示波器观察增量式编码器的 AB 相输出,理想波形应该是两路相位差 90 度的方波(正交信号)。但实际可能会看到:

- 信号抖动(因机械振动或电源噪声)
- 波形畸变(阻抗不匹配导致)
- 毛刺干扰(电磁环境复杂)
这些现象直接影响转速测量精度,严重时甚至导致方向误判。
硬件设计
推荐型号参数对比
| 型号 | 分辨率 (PPR) | 最高转速 (RPM) | 输出类型 | 工作电压 |
|---|---|---|---|---|
| E6B2-CWZ6C | 2000 | 6000 | 集电极开路 | 5-24V |
| HEDS-5500 | 500 | 10000 | 差分输出 | 5V |
| AEDR-8000 | 1600 | 30000 | 推挽输出 | 3.3V |
带隔离的电路连接
[编码器] ----[10K 上拉]---+---[光耦 PC817]---[MCU]
| |
[0.1uF 电容] [100Ω 限流电阻]
关键细节:
- 上拉电阻值根据线长调整(长线用较小阻值)
- 电源端并联 0.1μF 电容滤除高频干扰
- 光耦输出侧加 10nF 电容消除抖动
固件实现
Arduino 中断计数核心代码
// platformio.ini 配置
[env:uno]
platform = atmelavr
board = uno
framework = arduino
// 主程序
volatile long pulseCount = 0;
unsigned long lastTime = 0;
void setup() {pinMode(2, INPUT_PULLUP); // A 相接中断 0
attachInterrupt(0, countPulse, FALLING);
Serial.begin(115200);
}
// 带去抖的中断服务函数
void countPulse() {
static unsigned long lastIntTime = 0;
if(micros() - lastIntTime > 200) { // 200μs 防抖
pulseCount++;
lastIntTime = micros();}
}
void loop() {if(millis() - lastTime > 100) { // 每 100ms 计算转速
noInterrupts();
long currentCount = pulseCount;
pulseCount = 0;
interrupts();
float rpm = (currentCount * 600.0) / (2000 * 0.1); // 2000PPR 编码器
Serial.println(rpm);
lastTime = millis();}
}
转速公式推导
- 已知编码器每转产生 N 个脉冲(PPR)
- 在 Δt 时间内测得 n 个脉冲
- 转速 RPM = (n × 60) / (N × Δt)
例如 2000PPR 编码器,100ms 内测得 300 脉冲:
RPM = (300×60)/(2000×0.1) = 90 转 / 分钟
生产验证
同心度检测方法
使用数显卡尺测量电机轴与编码器安装面的径向偏差:
- 固定电机轴
- 卡尺测量编码器外壳四个对称点
- 偏差应小于 0.1mm
工业现场布线规范
- 使用双绞屏蔽线(如 RVVP2×0.5)
- 屏蔽层单端接地(接控制器 GND)
- 信号线与动力线间距 >30cm
- 过长的线缆增加磁环
故障百科
信号异常
├─ 无脉冲输出
│ ├─ 检查电源电压
│ ├─ 测试输出端对地短路
│ └─ 更换编码器测试
├─ 计数不准确
│ ├─ 检查中断触发方式(上升沿 / 下降沿)│ ├─ 调整防抖时间阈值
│ └─ 确认 AB 相序是否正确
└─ 转速波动大
├─ 检查机械安装同心度
├─ 增加信号滤波电容
└─ 改用差分输入模式
实际项目中,曾遇到因厂房变频器导致编码器信号异常的情况。最终通过改用屏蔽线 + 磁环,并将所有接地点统一到控制柜星形接地点解决。建议新手在实验室阶段就模拟工业环境测试,提前暴露问题。
正文完
