共计 1649 个字符,预计需要花费 5 分钟才能阅读完成。
背景与痛点
电机控制在机器人、自动化生产线、无人机等领域有着广泛应用。对于 Arduino 开发者来说,实现电机精准调速是常见需求,但过程中常遇到以下问题:

- PWM 调速时电机转速不稳定,出现抖动现象
- 编码器读数不准确,存在信号跳变
- 开环控制无法应对负载变化导致的转速波动
- 信号干扰影响系统可靠性
技术原理
PWM 控制电机速度的基本原理
- PWM(Pulse Width Modulation)通过调节脉冲占空比来控制平均电压
- 占空比越大,等效电压越高,电机转速越快
- Arduino UNO 的 PWM 频率默认为 490Hz(引脚 5,6)和 980Hz(其他 PWM 引脚)
编码器工作原理
- 增量式编码器通过 A / B 两相脉冲信号记录转动信息
- A/ B 相相位差 90 度,可判断转动方向
- 每转产生的脉冲数 (PPR) 决定分辨率
闭环控制优势
- 通过反馈实时修正输出,提高系统鲁棒性
- 能自动补偿负载变化带来的干扰
- PID 是常用的闭环控制算法
硬件连接
典型连接方案:
- Arduino PWM 引脚 → 电机驱动器 PWM 输入
- 电机驱动器输出 → 电机电源线
- 编码器 A / B 相 → Arduino 中断引脚(如 2,3)
- 共地连接确保信号参考电平一致
推荐使用 L298N 等 H 桥驱动器,支持 PWM 调速和方向控制。
代码实现
// 电机控制引脚定义
#define PWM_PIN 5
#define DIR_PIN 4
// 编码器引脚定义
#define ENC_A 2
#define ENC_B 3
volatile long encoderCount = 0;
void setup() {
// 初始化串口
Serial.begin(115200);
// 配置电机控制引脚
pinMode(PWM_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
// 配置编码器中断
pinMode(ENC_A, INPUT_PULLUP);
pinMode(ENC_B, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENC_A), encoderISR, CHANGE);
}
void loop() {
// 设置电机方向
digitalWrite(DIR_PIN, HIGH);
// 速度控制示例
for(int speed=0; speed<=255; speed+=10){analogWrite(PWM_PIN, speed);
Serial.print("Speed:");
Serial.print(speed);
Serial.print("\tEncoder:");
Serial.println(encoderCount);
delay(500);
}
}
// 编码器中断服务程序
void encoderISR() {if(digitalRead(ENC_A) == digitalRead(ENC_B)) {encoderCount++;} else {encoderCount--;}
}
调试技巧
PWM 频率选择
- 标准直流电机:490Hz-1kHz 较为适宜
- 过高频率可能导致电机驱动器过热
- 可通过修改定时器寄存器调整频率
编码器信号处理
- 使用硬件消抖电路(0.1uF 电容并联 10kΩ 电阻)
- 软件消抖:检测到边沿后延迟 50-100μs 再采样
- 中断服务程序应尽可能简短
PID 参数整定
- 先调 P(比例),再调 I(积分),最后调 D(微分)
- 从较小值开始逐步增大
- 观察系统响应调整参数
避坑指南
常见问题及解决方案:
- 电机不转:检查电源电压、使能信号、接线顺序
- 转速不稳定:检查 PWM 频率是否合适,增加滤波电容
- 编码器计数异常:检查中断引脚配置,确保信号质量
- 电机发热严重:降低 PWM 占空比或频率
性能优化
- 使用正交编码模式,4 倍频提高分辨率
- 采用硬件定时器生成 PWM,提高精度
- 优化 PID 算法计算周期,提高响应速度
- 添加速度前馈补偿,改善动态性能
扩展思考
- 尝试实现位置控制模式
- 探索更先进的控制算法:模糊 PID、自适应控制
- 应用于多电机同步控制系统
- 结合 ROS 实现更复杂的运动控制
通过本文介绍的方法,开发者可以构建稳定可靠的电机控制系统。实际应用中需要根据具体电机和负载特性调整参数,建议通过实验找到最优配置。
正文完
