BLDC编码器入门指南:从基础原理到电机控制实战

1次阅读
没有评论

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

image.webp

从波形认识编码器:增量式 vs 绝对式

用示波器抓取两种编码器输出信号时(建议用 1kΩ 终端电阻匹配阻抗),会明显看到:

BLDC 编码器入门指南:从基础原理到电机控制实战

  • 增量式编码器 :
  • A/ B 两路相位差 90°的方波(正交信号)
  • Z 相每转产生 1 个脉冲(索引信号)
  • 典型波形:A: _|‾|_|‾|_,B: ‾|_|‾|_|‾(相位滞后)

  • 绝对式编码器 :

  • 多路并行或串行(如 SSI)数字信号
  • 每个位置对应唯一二进制编码
  • 典型协议:SPI 波形上的 16 位数据包

霍尔传感器信号解码实战

硬件连接要点

  • 霍尔元件供电:4.5-24V(注意上拉电阻取值)
  • 信号线推荐双绞线 + 屏蔽层接地
  • 典型接口电路:
    // Arduino 霍尔信号输入
    #define HALL_A 2  // 使用中断引脚
    #define HALL_B 3
    #define HALL_Z 4

软件解码方案

  1. 边沿触发法 (适合低速场景):

    // Arduino 中断服务例程
    void hallA_ISR() {
      static uint32_t lastTime = 0;
      uint32_t now = micros();
      rpm = 60e6 / ((now - lastTime) * 6); // 6 极对数
      lastTime = now;
    }

  2. 状态机法 (抗干扰更强):

    // STM32 HAL 库实现
    typedef enum {
      STATE_00, // A=0,B=0
      STATE_01,
      STATE_11,
      STATE_10
    } HallState;
    
    void TIMx_IRQHandler() {if(__HAL_TIM_GET_FLAG(&htimx, TIM_FLAG_CC1)) {HallState newState = (HAL_GPIO_ReadPin(GPIOA, HALL_A_Pin) << 1) 
                           | HAL_GPIO_ReadPin(GPIOA, HALL_B_Pin);
        // 状态转移逻辑...
      }
    }

双平台代码对比

Arduino 模拟实现

// 带中值滤波的转速计算
#define FILTER_SIZE 5
uint32_t timeBuffer[FILTER_SIZE];

void updateRPM() {
  static uint8_t idx = 0;
  timeBuffer[idx++] = micros() - lastEdgeTime;
  if(idx >= FILTER_SIZE) idx = 0;

  uint32_t avgTime = 0;
  for(uint8_t i=0; i<FILTER_SIZE; i++) {avgTime += timeBuffer[i];
  }
  currentRPM = 60e6 / (avgTime/FILTER_SIZE * magnetPoles);
}

STM32 硬件编码器模式

// CubeMX 配置:// TIMx -> Encoder Mode -> TI1/TI2

// 读取位置值
int32_t getEncoderCount() {return __HAL_TIM_GET_COUNTER(&htim3);
}

// 带方向的转速计算
float getSpeedRPM() {
  int16_t cnt = TIM3->CNT;
  TIM3->CNT = 0; // 注意原子操作
  return (cnt * 60.0f) / (ENCODER_RESOLUTION * SAMPLING_TIME);
}

PID 控制代码结构

// 增量式 PID 实现(带抗饱和)typedef struct {
  float Kp, Ki, Kd;
  float lastError, integral;
} PIDController;

float pidUpdate(PIDController* pid, float setpoint, float feedback) {
  float error = setpoint - feedback;

  // 积分限幅
  pid->integral += error;
  if(pid->integral > 1000) pid->integral = 1000;
  else if(pid->integral < -1000) pid->integral = -1000;

  float output = pid->Kp * error 
               + pid->Ki * pid->integral
               + pid->Kd * (error - pid->lastError);

  pid->lastError = error;
  return output;
}

避坑指南

机械安装

  • 使用千分表校准电机轴与编码器同轴度(偏差 <0.05mm)
  • 弹性联轴器需预压紧消除反向间隙

信号处理

  • 屏蔽层单端接地(接电机外壳)
  • 信号线远离电源线(至少 3cm 间距)
  • 磁环在干扰严重时加装

软件消抖

// 过零检测的迟滞比较
#define HYSTERESIS 5  // RPM 阈值

bool checkZeroCross(int32_t newPos) {
  static int32_t lastPos = 0;
  if(abs(newPos - lastPos) > ENCODER_RESOLUTION/6 + HYSTERESIS) {
    lastPos = newPos;
    return true;
  }
  return false;
}

进阶思考

  1. FFT 分析异常 :
  2. 采集 1 秒原始信号
  3. 观察频谱中是否出现轴频 / 倍频外的杂波

  4. 多电机同步 :

  5. 硬件:共享编码器时钟基准
  6. 软件:Kalman 滤波补偿传输延迟

实践心得

调试时先用示波器确认霍尔信号质量,再用 LED 指示转动方向,最后上 PID。遇到转速波动大的问题,检查:

  • 编码器信号有无毛刺
  • 机械连接是否牢固
  • PID 参数是否过冲

建议先用开环控制测试电机基本功能,逐步增加控制复杂度。

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