共计 2158 个字符,预计需要花费 6 分钟才能阅读完成。
从波形认识编码器:增量式 vs 绝对式
用示波器抓取两种编码器输出信号时(建议用 1kΩ 终端电阻匹配阻抗),会明显看到:

- 增量式编码器 :
- 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
软件解码方案
-
边沿触发法 (适合低速场景):
// Arduino 中断服务例程 void hallA_ISR() { static uint32_t lastTime = 0; uint32_t now = micros(); rpm = 60e6 / ((now - lastTime) * 6); // 6 极对数 lastTime = now; } -
状态机法 (抗干扰更强):
// 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;
}
进阶思考
- FFT 分析异常 :
- 采集 1 秒原始信号
-
观察频谱中是否出现轴频 / 倍频外的杂波
-
多电机同步 :
- 硬件:共享编码器时钟基准
- 软件:Kalman 滤波补偿传输延迟
实践心得
调试时先用示波器确认霍尔信号质量,再用 LED 指示转动方向,最后上 PID。遇到转速波动大的问题,检查:
- 编码器信号有无毛刺
- 机械连接是否牢固
- PID 参数是否过冲
建议先用开环控制测试电机基本功能,逐步增加控制复杂度。
正文完
发表至: 未分类
近两天内
