Arduino编码器计数程序:从硬件连接到抗干扰优化

1次阅读
没有评论

共计 916 个字符,预计需要花费 3 分钟才能阅读完成。

image.webp

正交编码器基础

编码器通过 A / B 两相方波信号的相位差判定方向。典型时序如下:

Arduino 编码器计数程序:从硬件连接到抗干扰优化

 A 相: _|‾|_|‾|_|‾
B 相: _|‾|_|‾|_|‾ (正转时滞后 90°)

硬件连接规范

  1. 必接元件
  2. 10kΩ 上拉电阻(接近编码器侧)
  3. 0.1μF 陶瓷电容(信号对地)

  4. 屏蔽线接法:

  5. 双绞线传输信号
  6. 屏蔽层单点接地

代码实现对比

轮询法(基础版)

// O(n) 时间复杂度,适合低速场景
void loop() {
  static uint8_t lastState = PIND & 0b00001100; // 假设接 D2,D3
  uint8_t newState = PIND & 0b00001100;

  if(newState != lastState) {
    // 状态机判断逻辑
    lastState = newState;
  }
}

中断法(推荐方案)

// 使用 PCINT 中断,响应时间 <2μs
void setup() {PCICR |= (1<<PCIE2); // 启用 PCINT2 组
  PCMSK2 |= (1<<PCINT18)|(1<<PCINT19); // D2,D3
}

ISR(PCINT2_vect) {
  static uint8_t lastAB = 0;
  uint8_t currAB = (PIND >> 2) & 0x03;
  // 方向判断算法...
}

抗干扰实战方案

  1. 硬件滤波
  2. 典型值:R=1kΩ, C=10nF (截止频率 16kHz)
  3. 公式:fc=1/(2πRC)

  4. 软件去抖

    // 状态机实现,检测稳定持续时间
    enum {STATE_0, STATE_1, STATE_2};
    if(steady_time > 50μs) count++;

  5. 中断优化

  6. 使用 volatile 声明共享变量
  7. 避免浮点运算
  8. 最小化 ISR 代码量

关键问题排查

  1. 中断冲突
  2. 用 Saleae 逻辑分析仪捕获
  3. 检查中断标志位清除情况

  4. 计数器溢出

    volatile int32_t totalCount = 0;
    // 在中断中处理 16 位溢出
    if(change > 0x7FFF) totalCount -= 65536;

性能测试数据

转速 (RPM) 误差率 (%)
100 0.02
1000 0.15
5000 1.8

进阶思考

  1. 如何通过脉冲间隔实现零速检测?
  2. 多编码器系统如何优化中断响应时序?
  3. 怎样利用 Timer1 硬件计数提升性能?

(示波器波形图建议位置:硬件滤波章节后插入抖动对比图)

正文完
 0
评论(没有评论)