AB相编码器测速实战:从原理到Arduino实现

1次阅读
没有评论

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

image.webp

背景痛点

AB 相编码器是电机控制中常用的位置和速度传感器,通过两路相位差 90 度的脉冲信号(A 相和 B 相)提供精确的运动反馈。但在实际应用中,新手常遇到以下问题:

AB 相编码器测速实战:从原理到 Arduino 实现

  • 信号毛刺:由于电机干扰或接线不良,AB 相信号可能出现抖动,导致计数错误
  • 方向误判:软件解码时容易因信号延迟造成方向判断失误
  • 低速精度差:常规测频法在低速时分辨率不足,导致转速波动明显

技术对比:定时器捕获 vs 正交解码

  1. 定时器捕获法 :通过外部中断捕获脉冲边沿,软件判断相位差
  2. 优点:适用所有 MCU
  3. 缺点:CPU 占用高,高速时可能丢失脉冲

  4. 硬件正交解码 :利用定时器的编码器接口模式

  5. 优点:自动处理四倍频和方向判断,零 CPU 占用
  6. 缺点:需要特定硬件支持(如 STM32 的 TIMx)

核心实现

硬件连接(Arduino Uno 为例)

/* AB 相编码器接线图 */
编码器 A 相 —— D2(外部中断 0)编码器 B 相 —— D3(外部中断 1)编码器 VCC —— 5V
编码器 GND —— GND

/* 推荐增加 RC 滤波(R=1kΩ, C=100nF)*/

STM32 硬件正交解码示例

// PlatformIO 环境配置(platformio.ini)[env:bluepill_f103c8]
platform = ststm32
board = bluepill_f103c8
framework = arduino

// 编码器接口初始化
void setup() {
  // 定时器 3 配置为编码器模式
  TIM_Encoder_InitTypeDef encoderConfig;
  encoderConfig.EncoderMode = TIM_ENCODERMODE_TI12;
  encoderConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
  encoderConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
  encoderConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
  encoderConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
  encoderConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  encoderConfig.IC2Prescaler = TIM_ICPSC_DIV1;
  encoderConfig.IC1Filter = 6;  // 适当滤波
  encoderConfig.IC2Filter = 6;

  HAL_TIM_Encoder_Init(&htim3, &encoderConfig);
  HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
}

// 读取计数值(注意处理溢出)int32_t getEncoderCount() {
  static uint16_t lastCnt = 0;
  static int32_t totalCnt = 0;

  uint16_t currCnt = TIM3->CNT;
  int16_t diff = (int16_t)(currCnt - lastCnt);
  totalCnt += diff;
  lastCnt = currCnt;

  return totalCnt;
}

转速计算公式

RPM = (Δcount × 60) / (PPR × 4 × Δt)
其中:Δcount = 采样周期内的脉冲变化量
  PPR = 编码器每转脉冲数(如 500 线)4 = 四倍频系数
  Δt = 采样时间 (s)

避坑指南

  1. 信号滤波参数选择
  2. 典型值:R=1kΩ,C=100nF(截止频率≈1.6kHz)
  3. 高速场合:减小电容值(如 10nF)避免信号延迟

  4. 中断防溢出处理

    // Arduino 外部中断示例
    volatile int32_t encoderCount = 0;
    
    void interruptA() {
      static uint8_t lastState = 0;
      uint8_t currState = digitalRead(pinA) | (digitalRead(pinB) << 1);
    
      // 状态机实现四倍频解码
      if((lastState == 0x00 && currState == 0x01) || 
         (lastState == 0x01 && currState == 0x03) ||
         (lastState == 0x03 && currState == 0x02) ||
         (lastState == 0x02 && currState == 0x00)) {encoderCount++;} else {encoderCount--;}
      lastState = currState;
    }

  5. 低速测周法策略

  6. 当 RPM < 100 时,改为测量单个脉冲周期
  7. 计算公式:RPM = 60 / (PPR × 4 × T)

测试验证

使用示波器观察 AB 相信号:
– 原始信号:可能带有毛刺(示波器触发设置建议:A 相上升沿)
– 滤波后:波形干净,相位差保持 90°

扩展思考:ESP32 移植要点

  1. 利用 PCNT 外设实现硬件计数
  2. 注意 ESP32 的引脚中断响应速度较慢,建议启用 RTOS 任务专用于编码器处理
  3. 双核特性可利用:Core0 处理计数,Core1 计算转速

结语

通过硬件正交解码配合适当的信号处理,可以实现稳定可靠的 AB 相编码器测速。实际项目中还需考虑机械安装同心度、电缆屏蔽等非电气因素。建议先用示波器验证信号质量,再逐步优化算法参数。

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