共计 1778 个字符,预计需要花费 5 分钟才能阅读完成。
1. 为什么 EC11 编码器让人又爱又恨
EC11 旋转编码器 (Rotary Encoder) 作为低成本角度传感器,在智能家居旋钮、工业设备面板等场景随处可见。但许多开发者反馈:

- 明明只转了一格,却触发多次计数
- 快速旋转时方向判断错误
- 信号线稍长就出现随机跳动
这些问题的核心在于:EC11 是机械接触式编码器,触点抖动 (Bounce) 会持续 5 -20ms(不同品牌差异大)。下图是示波器捕捉的典型抖动信号:
A 相: _|¯¯|____|¯¯|__
B 相: __|¯¯|____|¯¯|_ ← 理想信号
实际: _|¯|_|¯|__|¯|_|¯|_ ← 真实抖动信号
2. 硬件消抖 vs 软件消抖的终极对决
2.1 硬件方案:RC 低通滤波
经典做法是在 A / B 相各加 10kΩ 电阻和 0.1μF 电容组成 RC 电路:
EC11 引脚 —— 10kΩ —— Arduino
↓
0.1μF
↓
GND
优点:
– 电路简单成本低
– 不消耗 CPU 资源
缺点:
– 响应速度受限于 RC 时间常数(典型 10ms 延迟)
– 无法完全消除高频抖动
2.2 软件方案:状态机 + 时间窗
推荐采用四步状态机实现:
状态转换图:[00] → [10] → [11] → [01] → [00] (顺时针)
[00] ← [01] ← [11] ← [10] ← [00] (逆时针)
配合时间窗口滤波:
- 记录每次跳变的时间戳
- 20ms 内的新跳变视为抖动忽略
- 超时后更新有效状态
3. 工业级稳定性的代码实现
3.1 硬件连接
// 根据实际接线修改
const int PIN_A = 2; // 必须支持外部中断
const int PIN_B = 3;
const int BUTTON = 4; // 编码器按键
3.2 核心处理逻辑
volatile int8_t state = 0;
volatile int32_t counter = 0;
volatile uint32_t lastTime = 0;
void handleInterrupt() {uint32_t now = millis();
if (now - lastTime < 20) return; // 20ms 防抖窗口
int newState = (digitalRead(PIN_A) << 1) | digitalRead(PIN_B);
// 状态转移检测
if (state == 0x00 && newState == 0x02) state = 0x02;
else if (state == 0x02 && newState == 0x03) state = 0x03;
else if (state == 0x03 && newState == 0x01) {
state = 0x00;
counter++;
}
// 逆时针逻辑类似...
lastTime = now;
}
3.3 中断配置
void setup() {attachInterrupt(digitalPinToInterrupt(PIN_A), handleInterrupt, CHANGE);
attachInterrupt(digitalPinToInterrupt(PIN_B), handleInterrupt, CHANGE);
// 按键建议用轮询检测
}
4. 高级调试技巧
4.1 示波器诊断法
- 观察 A / B 相是否保持 90°相位差
- 测量抖动持续时间(决定时间窗口)
4.2 软件模拟器
在没有硬件时可用此代码模拟编码器信号:
void generateSignal(bool clockwise) {digitalWrite(PIN_A, HIGH);
delay(5); // 模拟抖动
digitalWrite(PIN_A, LOW);
digitalWrite(PIN_B, clockwise ? HIGH : LOW);
// 继续生成完整周期...
}
5. 避坑圣经
- 接地环路:编码器金属外壳必须接 GND
- 线材选择:使用双绞线且长度 <50cm
- 电源滤波:在 VCC 与 GND 间并联 100nF 电容
- 中断冲突:避免与其他高频中断(如 WS2812B)共用
6. 性能优化备忘录
| 方案 | CPU 占用 | 响应延迟 | 适用场景 |
|---|---|---|---|
| 纯轮询 | 100% | <1ms | 低速简单系统 |
| 中断 + 状态机 | <5% | 5-20ms | 多数应用场景 |
| 硬件编码器芯片 | 0% | <1ms | 超高转速场合 |
7. 从编码器到实际应用
尝试用编码器实现:
- PID 参数调节器:旋转调节 P /I/ D 系数,按键确认
- 三级菜单系统:短按进入子菜单,长按返回
- 速度曲线生成器:快速旋转时加速翻页
完整工程代码已开源:github.com/example/ec11-advanced
最后提醒:不同厂商的 EC11 机械特性差异较大,建议批量采购前先做 20000 次旋转寿命测试!
正文完
