1. 项目概述
连续旋转伺服电机(Continuous Rotation Servo)是创客项目中常用的执行机构,相比普通伺服电机,它去除了机械限位,可以实现360度连续旋转。这种特性使其非常适合用于机器人底盘驱动、传送带控制等需要连续运动的场景。而树莓派作为一款性价比极高的微型计算机,通过GPIO引脚可以方便地控制这类电机。
我在最近的一个自动喂食器项目中,就采用了树莓派4B配合TowerPro MG995连续旋转伺服电机的方案。实测发现,这种组合既能满足精确控制需求,又保持了较低的成本(整套驱动方案不到100元)。下面我将分享具体的接线方法、控制原理和实战中的调参技巧。
2. 硬件连接与信号原理
2.1 伺服电机接线规范
标准的三线制伺服电机接口包括:
- 红色线:电源正极(通常4.8-6V)
- 棕色/黑色线:电源负极
- 黄色/白色线:PWM信号输入
对于树莓派连接,需要特别注意:
-
切勿直接从树莓派GPIO取电驱动电机!树莓派GPIO最大输出电流仅16mA,而伺服电机启动电流可达500mA以上。我的解决方案是使用外接5V/2A电源,通过面包板分别给树莓派和电机供电。
-
共地处理:必须将树莓派GND与外部电源GND连接,否则PWM信号无法正确传输。我在第一次测试时就因为忘记共地,导致电机出现不规则抖动。
2.2 PWM控制原理详解
连续伺服电机的转速和方向由PWM信号的占空比决定:
- 1.5ms脉冲宽度(占空比7.5%):电机停止
- 1.0ms脉冲宽度(占空比5%):全速逆时针旋转
- 2.0ms脉冲宽度(占空比10%):全速顺时针旋转
树莓派的硬件PWM引脚(GPIO12/13/18/19)能提供更稳定的信号。以GPIO18为例,在终端可以通过以下命令启用硬件PWM:
bash复制sudo apt-get install pigpio
sudo pigpiod
3. 软件控制实现
3.1 Python控制代码解析
推荐使用pigpio库而非RPi.GPIO,因其硬件PWM精度更高(可达μs级)。以下是基础控制类实现:
python复制import pigpio
import time
class ContinuousServo:
def __init__(self, pin):
self.pi = pigpio.pi()
self.pin = pin
self.min_pulse = 1000 # 1ms脉冲
self.max_pulse = 2000 # 2ms脉冲
self.neutral = 1500 # 1.5ms停止位
def set_speed(self, speed):
""" speed范围-1.0到1.0 """
pulse = self.neutral + speed * 500
pulse = max(min(pulse, self.max_pulse), self.min_pulse)
self.pi.set_servo_pulsewidth(self.pin, pulse)
def stop(self):
self.pi.set_servo_pulsewidth(self.pin, 0)
self.pi.stop()
关键参数说明:
set_servo_pulsewidth()的第二个参数单位是微秒(μs)- 实际测试发现MG995电机在1480-1520μs区间才能完全停止,不同电机需微调
3.2 校准技巧与死区处理
新电机首次使用时必须进行校准:
- 上电后发送1500μs脉冲
- 用螺丝刀调节电机底部的电位器,直到完全停止
- 记录实际停止时的脉冲值作为新的neutral值
我在批量使用中发现,即使同一型号电机,neutral值也可能有±20μs的差异。好的做法是建立校准配置文件:
python复制{
"servo1": {"min":980, "max":2020, "neutral":1495},
"servo2": {"min":1020, "max":1980, "neutral":1510}
}
4. 电源管理与保护电路
4.1 电源选型建议
根据电机数量选择电源功率:
- 单个SG90:5V/1A足够
- MG995等大扭矩电机:建议5V/2A以上
- 多电机系统:为每个电机预留1A余量
实测中发现的问题:当两个电机同时启动时,5V/2A电源也会导致树莓派重启。解决方案是:
- 使用1000μF电容并联在电源输入端
- 软件上错开电机启动时间(间隔100ms)
4.2 保护电路设计
必备的保护元件:
- 反接保护二极管:1N4007串联在正极
- 消噪电容:0.1μF陶瓷电容并联在电机端子
- 可选光耦隔离:PC817隔离GPIO与电机驱动
我的实际电路布局经验:
- 电源走线尽量短而粗(AWG20以上)
- 信号线与电源线分开布置
- 电机外壳接地可减少EMI干扰
5. 高级控制技巧
5.1 速度曲线平滑处理
直接切换速度会导致机械冲击,建议采用加速度控制:
python复制def smooth_set_speed(self, target_speed, acceleration=0.1):
current = self.current_speed
while abs(target_speed - current) > 0.01:
current += acceleration * (1 if target_speed>current else -1)
self.set_speed(current)
time.sleep(0.02)
参数调整建议:
- 小负载:acceleration=0.2
- 重负载:acceleration=0.05
- 可通过实验找到最佳值
5.2 位置闭环控制方案
虽然连续伺服本身不带位置反馈,但可以通过外接编码器实现闭环控制。我采用的方案:
- 使用AS5600磁性编码器(I2C接口)
- 胶接磁铁到电机输出轴
- PID控制算法调节转速
核心PID实现片段:
python复制def update(self, current_pos):
error = self.target - current_pos
self.integral += error
derivative = error - self.last_error
output = self.Kp*error + self.Ki*self.integral + self.Kd*derivative
output = max(min(output, 1), -1)
self.last_error = error
self.servo.set_speed(output)
典型PID参数:
- Kp=0.5, Ki=0.01, Kd=0.1(需根据负载调整)
6. 常见问题排查
6.1 电机抖动或不启动
可能原因及解决方案:
-
电源不足:
- 现象:电机发出"咔嗒"声
- 解决:更换更大电流电源,测量电压是否低于4.8V
-
信号干扰:
- 现象:随机改变方向
- 解决:缩短信号线,增加滤波电容
-
脉冲范围错误:
- 现象:只能单方向转
- 解决:用示波器检查实际脉冲宽度
6.2 树莓派GPIO异常
保护措施:
- 始终串联220Ω电阻在信号线
- 避免热插拔电机
- 异常时立即执行
sudo killall pigpiod
调试技巧:
bash复制# 检查PWM信号
sudo pigpiod -t
pigs hp 18 50 1500 # 测试GPIO18输出
7. 项目应用实例
7.1 自动窗帘控制系统
我的实现方案:
- 2个MG995电机(左右窗帘)
- 树莓派Zero W控制
- 光敏电阻自动触发
- Web界面远程控制
关键代码结构:
code复制/var/www/html
├── index.html # 控制界面
├── servo.py # 电机控制后台
└── light.py # 光线监测
7.2 机器人底盘驱动
双电机差速转向要点:
- 左右电机镜像安装
- 基础速度公式:
python复制
left_speed = base_speed - turn_factor right_speed = base_speed + turn_factor - 加入死区防止微小偏差累积
实测转向半径与turn_factor的关系表:
| factor | 半径(cm) | 备注 |
|---|---|---|
| 0.1 | 80 | 缓弯 |
| 0.3 | 30 | 标准转向 |
| 0.5 | 15 | 急转,可能打滑 |
最后分享一个调试小技巧:在电机轴上贴彩色胶带,可以直观观察转速和转向,比听声音判断准确得多。对于需要精确控制的项目,建议先用3D打印一个指针装在电机轴上,配合量角器进行校准。