共计 1499 个字符,预计需要花费 4 分钟才能阅读完成。
旋转编码器的典型应用
旋转编码器在物联网设备中无处不在,比如:

- 机器人关节角度检测(每旋转 1°触发特定脉冲数)
- 智能家居旋钮(通过旋转圈数调节音量 / 亮度)
- 3D 打印机进料监控(记录耗材消耗长度)
编码器类型选择
增量式编码器(Incremental Encoder)与绝对式编码器(Absolute Encoder)的区别:
- 增量式 :通过 A / B 两相脉冲的相对相位判断方向,价格低但需初始复位
- 绝对式 :每个位置对应唯一二进制编码,成本高但断电不丢失数据
Arduino 项目首选增量式的原因:
- 成本仅为绝对式的 1 /5~1/10
- 仅需 2 个 IO 口即可读取(绝对式需要 4 -12 个 IO)
- 开源库生态完善(如 Encoder 库)
硬件连接实战
接线示意图
编码器 Arduino
-------------------
CLK(A 相) —— D2(中断 0)
DT(B 相) —— D3(中断 1)
VCC —— 5V
GND —— GND
注意事项:
- 优先选择带中断功能的引脚(UNO 的 D2/D3 对应中断 0 /1)
- 线长超过 15cm 时建议加 10KΩ 上拉电阻
- 工业环境推荐使用屏蔽双绞线
核心代码实现
#include <Encoder.h>
// 初始化编码器对象(参数为 A / B 相引脚)Encoder myEncoder(2, 3);
// 去抖动时间阈值(单位 ms)计算公式:// 阈值 = (60/ 最大转速 RPM) × 1000 / 每转脉冲数 PPR × 安全系数 0.3
#define DEBOUNCE_TIME 5
void setup() {Serial.begin(115200);
}
void loop() {
static long oldPos = 0;
long newPos = myEncoder.read();
if (newPos != oldPos) {
oldPos = newPos;
Serial.print("Position:");
Serial.println(newPos);
// 模拟去抖动处理
delay(DEBOUNCE_TIME);
}
}
信号处理关键技术
机械抖动解决方案
抖动现象:
– 物理接触时产生 5 -20ms 的异常脉冲
– 表现为计数器无规律跳变
软件滤波方案:
- 状态机检测:
- 有效跳变需满足 A / B 相状态顺序变化
-
例如 A 上升沿后必须检测到 B 的变化
-
时间窗口法:
- 连续两次跳变间隔小于阈值则视为抖动
- 代码示例:
if (millis() - lastTime < DEBOUNCE_TIME) return; lastTime = millis();
中断优化策略
- 使用 PORT 寄存器直接读取(比 digitalRead 快 10 倍):
uint8_t state = PIND & 0b00001100; // 同时读取 D2/D3 - 避免在中断内执行 Serial.print 等耗时操作
- 多编码器时采用引脚变化中断(PCINT)替代独立中断
生产环境建议
编码器选型
| 类型 | 适用场景 | 寿命 |
|---|---|---|
| 光学编码器 | 洁净环境 / 高精度需求 | 50 万转 |
| 磁性编码器 | 油污 / 粉尘环境 | 100 万转 |
抗干扰设计
- 电源处理:
- 编码器与 MCU 共地
- 并联 100μF+0.1μF 电容滤波
- 信号线处理:
- 双绞线绕制(每厘米 1 - 2 绞)
- 金属外壳接大地
进阶思考
- PID 闭环控制 :
- 将编码器读数作为反馈量
-
计算目标位置与实际位置的误差
error = targetPos - encoder.read(); output = Kp*error + Ki*integral + Kd*derivative; -
高速采样方案 :
- 当转速超过采样能力时(公式:RPM > (采样频率×60)/PPR)
- 解决方案:
- 改用硬件计数器(如 UNO 的 Timer1)
- 使用 32 位 ARM 芯片(如 Teensy 4.0)
通过本文介绍的方法,你应该能避开 80% 的编码器使用陷阱。下次可以尝试用编码器 + 步进电机搭建一个闭环控制系统——你会发现精准控制原来如此简单!
正文完
