共计 1385 个字符,预计需要花费 4 分钟才能阅读完成。
背景痛点
在电机控制项目中,精确的位置和速度检测是核心需求。传统方案如电位器或霍尔传感器存在精度低、寿命短等问题。以常见的智能小车为例,当需要实现厘米级定位时,这些方案的误差可能达到 5% 以上,无法满足精准控制要求。

技术对比
- 增量式编码器 (ABZ 相)
- 分辨率:通常 100-5000PPR(每转脉冲数)
- 优点:成本低(约 20-100 元),结构简单
-
缺点:断电后位置信息丢失,需额外 Z 相归零
-
绝对式编码器
- 分辨率:12-16 位(4096-65536 位置点 / 转)
- 优点:断电保持位置,抗干扰强
- 缺点:价格高(300 元起),接口复杂
核心实现
正交解码原理
当电机旋转时,AB 两相输出相位差 90°的方波。通过检测边沿变化顺序可判断方向,脉冲数即为位移量。
// Arduino 引脚配置
#define ENCA 2 // 中断引脚
#define ENCB 3
volatile long pulseCount = 0;
void setup() {pinMode(ENCA, INPUT_PULLUP);
pinMode(ENCB, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCA), encoderISR, CHANGE);
}
void encoderISR() {int bState = digitalRead(ENCB);
if (digitalRead(ENCA) == bState) {pulseCount++;} else {pulseCount--;}
}
转速计算
通过定时器每 100ms 读取脉冲数,换算转速:
float getRPM() {
static long lastCount = 0;
long current = pulseCount;
float rpm = (current - lastCount) * 600.0 / (1000 * PPR); // 假设 PPR=500
lastCount = current;
return rpm;
}
避坑指南
- 信号处理
- 使用双绞屏蔽线(如 CAT5e 网线)
- 在 A / B 相与地之间并联 100pF 电容
-
线路超过 30cm 时建议改用 RS-422 差分传输
-
机械安装
- 用千分表检查联轴器同轴度(应 <0.1mm)
-
弹性联轴器可补偿微小偏差
-
高速处理
- 超过 2000RPM 时需启用 STM32 硬件编码器接口
- 降低 MCU 中断优先级避免丢失脉冲
进阶测试
滤波实验数据
| 电容值 | 边沿上升时间 | 抗干扰能力 |
|---|---|---|
| 无滤波 | 50ns | ★★☆☆☆ |
| 100pF | 200ns | ★★★★☆ |
| 1nF | 2μs | ★★☆☆☆ |
动手实验:PID 位置控制
// PlatformIO 项目结构
├── include
│ └── PID.h // PID 算法库
├── lib
│ └── Encoder // 编码器驱动
└── src
└── main.cpp
// PID 核心代码片段
void loop() {float currentPos = pulseCount * (360.0 / PPR);
float output = pid.compute(targetPos, currentPos);
analogWrite(MOTOR_PWM, constrain(output, 0, 255));
}
调试技巧 :
1. 先单独测试编码器读数稳定性
2. 从纯 P 调节开始,逐步加入 I / D 参数
3. 用 Serial Plotter 观察响应曲线
通过本文的实践,你应该能避开 80% 的编码器应用陷阱。下次遇到信号干扰时,不妨试试在电源端加个 0.1μF 的去耦电容,这个小改动可能会带来意想不到的效果。
正文完
