ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Arduino控制SG90 360度连续旋转舵机:脉宽控制与开环校准实战

Arduino控制SG90 360度连续旋转舵机:脉宽控制与开环校准实战 这次我们来看一个容易被“先入为主”带偏的硬件控制问题手头的 SG90 舵机到底能不能当普通 180 度舵机用如果你买的型号是SG90 360 度连续旋转舵机那么答案是不建议直接按角度写。它的真实控制方式是writeMicroseconds() 输出脉宽控制速度不是 write() 控制角度。这篇内容会围绕 Arduino UNO 展开讲清楚这类舵机的本质、接线、启动测试、停机值校准、串口实时控制以及为什么它属于开环控制。先说结论方便你判断是否需要继续往下看360 度连续旋转舵机没有角度限位不能精准定位到指定角度。控制信号仍然是 50Hz 左右的 PWM核心调用是Servo.writeMicroseconds()。脉宽 1500us 附近通常是停止点但不是所有舵机都刚好是 1500必须实测校准。这类舵机适合转台、云台旋转、简单小车轮子驱动不适合机械臂关节或需要反馈控制的场景。后面会给出 3 份可以直接烧录到 Arduino UNO 的测试代码以及串口输入脉宽的调试方法。下面直接进入正题。1. SG90 360 度舵机核心能力速览能力项说明项目类型SG90 变体舵机控制属于 360 度连续旋转舵机控制方式50Hz PWM 脉宽控制核心函数writeMicroseconds()开环/闭环开环控制不带位置反馈无法获知当前角度可调参数脉宽值、旋转方向、电机速度、运行时间能实现的功能连续正转、连续反转、停止、不同转速的近似控制不能实现的功能精确角度定位、位置闭环、力矩保持时的角度校正推荐控制板Arduino UNO、Nano、Mega 等 AVR 平台均可信号引脚舵机信号线接 UNO 数字引脚示例中使用 D9供电建议建议外部 5V 供电并共地避免直接占用 UNO 板载稳压电流适合读者刚入门 Arduino 舵机控制的开发者、做简单转台/小车方向的开发者这个表很重要的一点是360 度连续旋转舵机是“去掉限位并改写控制逻辑”的产物。不同厂家、不同批次的 SG90-360控制脉宽范围和停止点都会存在差异。网络上“1000us 正转、1500us 停止、2000us 反转”只能作为默认参考真正上电以后需要逐个测试。2. SG90 360 度连续旋转舵机和普通 180 度舵机差在哪2.1 机械结构差异普通 SG90 舵机内部有机械限位输出轴只能在 0 到 180 度左右摆动。你在驱动它的时候如果脉宽超过最大或最小角度舵机会顶在限位处电流升高、发出“嗡嗡”声长时间堵转还会发热。360 度连续旋转舵机内部去掉了这个限位挡块或通过改电路让电机可以连续旋转。它输出的不是角度变化而是连续转动。2.2 控制语义差异普通 180 度舵机角度和脉宽大致对应0 度对应脉宽约 500us 或 1000us90 度对应脉宽约 1500us180 度对应脉宽约 2500us 或 2000us所以直接用write(90)让舵机转到中间位置是合理的。但 360 度连续旋转舵机上角度概念不存在了。脉宽变成“停止 / 正转速度 / 反转速度”的指令中间脉宽附近通常约 1500us对应电机停止。脉宽偏大或偏小对应不同方向的旋转。偏离中心越远电机转速越快。正因为没有反馈舵机不知道自己转到哪里这就是明显的“开环控制”。2.3 购买时如何分辨SG90 型号非常多看包装和商品标题时要注意。如果标题写“SG90 360 度连续旋转”“SG90 无角度限制”那就是这种版本如果写“SG90 9g 舵机 180 度”那才是普通角度舵机。低成本舵机的批次差异很大。有些号称 360 度连续旋转实际死区很宽很难找到完全停止的脉宽有些在同一脉宽下正反转速度也不对称。因此拿到手后先跑一遍测试程序比直接翻参数更靠谱。3. 适用场景与安全边界3.1 适合的场景需要一个持续旋转的云台底盘比如小型摄像头云台的左右旋转轴。做一个简单的转盘演示展示圆周运动。小车上使用这类舵机作为减速轮驱动虽然精度和扭矩都有限但入门够用。模拟雷达扫描效果可以做 360 度旋转但没角度反馈就需要配合外部传感器做限位。测试 Arduino PWM 输出、脉宽控制电机基本逻辑。3.2 不适合的场景需要精确到达某个角度的机械臂关节。需要位置闭环的高精度云台指向。需要承受持续大扭矩的负载或长时间堵转。对重复精度有要求的生产级设备。360 度连续旋转舵机本质上是给小功率设备做“速度调节”的而不是做“位置控制”的。如果坚持让它在没有反馈的情况下完成精确角度动作结果会非常脆弱供电电压波动、齿轮间隙、负载变化都会累计误差。3.3 使用边界与安全提醒舵机没有限位如果外部结构加了机械挡板不要高速长时间让舵机顶住挡板否则齿轮和电机容易损坏。空载测试最安全尽量不要一开始就带大负载。涉及自制转台、小车、云台时注意不要夹到手指不要让 USB 线缠绕到旋转轴。本项目只适合学习、原型验证和合法自用设备改造不要用于未经授权的自动化设备或任何违规场合。4. 硬件准备与 Arduino UNO 接线4.1 硬件清单器件数量Arduino UNO 或兼容板1 块SG90 360 度连续旋转舵机1 个杜邦线公对公或母对公3 根外部 5V 电源可选但推荐USB 数据线1 根串口监视器由 Arduino IDE 提供如果手上只有普通 SG90也不影响练习只是你的舵机会被限位挡住达不到连续旋转效果。4.2 SG90 引脚定义SG90 的 3 根线颜色常见如下线色功能接法棕色GND接 Arduino GND 和外部电源 GND红色VCC接 5V 电源正极橙色或黄色Signal接 Arduino 数字引脚示例接 D9不同厂家线序可能不同接线前仔细看舵机标签。插反信号线有可能损坏舵机驱动板或引脚。4.3 供电方式选择原则只有一条舵机的电源不要只依赖 UNO 的板载 5V 输出能用外部电源就尽量用外部电源。常见的错误接法是直接把舵机红线接到 UNO 的 5V 引脚然后 USB 供电给 UNO。这种做法对于 1 个空载 SG90 也许能跑但一旦舵机启动电流变大USB 口电压被拉低Arduino 可能自动复位。更坏的情况是舵机堵转电流长时间过大。推荐接线方式Arduino UNO SG90 360 D9 ------- 橙色信号线 5V (来自外部电源) --- 红色正极注意先不接 UNO 5V而是接外部电源 GND ------- 棕色 GND 外部电源 GND ---- Arduino GND更稳妥的接法舵机正极接外部 5V 电源。舵机 GND 同时连接 Arduino GND 和外部电源 GND这叫共地。Arduino 用 USB 独立供电。舵机信号线直接接 Arduino D9。4.4 UNO 引脚占用说明Arduino 的 Servo 库在 UNO 上会占用 Timer1。Timer1 与引脚 D9、D10 的 PWM 输出有关。当使用 Servo 库时D9 和 D10 的analogWrite()会受到影响不能同时可靠工作。如果后面需要 D10 输出 PWM 控制其他设备需要重新规划引脚。5. 第一个测试程序用 writeMicroseconds 把舵机转起来5.1 代码思路连续旋转舵机的输入是脉宽。Servo库中servo.writeMicroseconds(1500);表示输出 1500 微秒的脉宽这是最常见的停止值。但要注意writeMicroseconds()并不是“写微秒时间长度”这么简单它最终会换算成对应周期的 PWM 占空比。Arduino Servo 库默认周期约 20ms也就是 50Hz符合常规遥控舵机信号标准。5.2 示例代码下面程序会让舵机按顺序执行停止 - 正转 - 停止 - 反转 - 停止。每个状态持续 2 秒方便观察方向是否正确。#include Servo.h Servo myServo; const int servoPin 9; void setup() { Serial.begin(9600); // 显式设置脉宽范围避免不同商家舵机范围不一致 myServo.attach(servoPin, 500, 2500); myServo.writeMicroseconds(1500); Serial.println(SG90 360 test start); delay(1000); } void loop() { // 停止 Serial.println(1500us - stop); myServo.writeMicroseconds(1500); delay(2000); // 正转 Serial.println(1000us - forward); myServo.writeMicroseconds(1000); delay(2000); // 停止 Serial.println(1500us - stop); myServo.writeMicroseconds(1500); delay(2000); // 反转 Serial.println(2000us - reverse); myServo.writeMicroseconds(2000); delay(2000); }5.3 预期观察现象烧录程序后舵机应该先停 2 秒然后转动约 2 秒再停 2 秒再反向转动 2 秒循环运行。如果 1000us 时舵机不转只听到“吱吱”声说明 1000us 落在停止死区内或者舵机批次的最小运行脉宽不够低。可以改成 900 或 800 再试。如果 2000us 时舵机停转或轻微抖动也可以继续加大到 2100 甚至 2400。这个测试的意义不是运行一个“好看”的动作而是确认舵机信号线是否接对。供电是否足够。当前脉宽与旋转方向、停止位置的实际对应关系。6. 串口实时控制与停机值校准6.1 为什么需要校准“1500us 停止”是一个理论值。实际 SG90-360 舵机的停止点可能落在 1450 到 1550 之间甚至有些批次漂移更严重。如果 1500us 输出后舵机还在慢慢转后面的控制逻辑会整个乱掉。所以拿到舵机后的第一步不是直接写小车控制代码而是先在串口监视器里手动输入脉宽找到它的真实停止点。6.2 串口输入脉宽控制代码这份代码读取串口十进制整数并把它作为脉宽输出。你可以在 Arduino IDE 串口监视器输入1500、1000、2000等值观察舵机状态。#include Servo.h Servo myServo; const int servoPin 9; void setup() { Serial.begin(9600); myServo.attach(servoPin, 500, 2500); myServo.writeMicroseconds(1500); Serial.println(Input pulse width, e.g. 1500); } void loop() { if (Serial.available() 0) { int value Serial.parseInt(); if (value 500 value 2500) { myServo.writeMicroseconds(value); Serial.print(Set pulse: ); Serial.println(value); } else { Serial.println(Invalid range, use 500-2500); } } delay(10); }6.3 校准步骤打开串口监视器波特率选 9600。输入1500观察舵机是否完全停止。如果仍在微转尝试输入1490、1480、1470、1510、1520等直到舵机完全停住。把找到的“完全停止值”记为STOP_PULSE。输入1000舵机应朝一个方向转动输入2000舵机应朝另一个方向转动。如果方向和你预期相反调整程序中正转/反转对应的脉宽即可。继续用900、1100、2000、2100测试记录基本转速差异。校准完成后把1500替换成自己实测的STOP_PULSE。比如你的舵机在1480才停那么代码中所有停止位置都写1480。6.4 死区问题连续旋转舵机的死区指的是脉宽在某个范围内时舵机既不转也不产生明显扭矩。死区过宽会让控制“迟钝”指令变化一点但舵机没反应死区过窄则可能导致舵机在停止点附近抖动。如果发现舵机在停止点附近出现来回抖动最直接的办法是把停止脉宽设置在死区中心避免使用临界值。7. 开环控制入门动作时间与角度估测7.1 什么是开环控制开环控制的意思是控制器发出指令后不检查执行结果是否达到预期。360 度连续旋转舵机就是典型的开环执行器——它没有角度传感器没有编码器也没有电流反馈。你发出“以某速度转 1 秒”它理论上转过的角度是多少控制器并不知道。这意味着如果你希望它“转 90 度后停下”只能通过“某个脉宽跑多少毫秒”来估算。这种估算会受到供电电压、负载、温度、齿轮阻力影响误差会逐步累积。7.2 开环动作序列示例下面的程序演示一个不含反馈的简单流程启动 - 正向转 1.5 秒 - 停止 - 反向转 1.2 秒 - 停止。这里用STOP_PULSE变量统一管理停止值校准后只需要改一个地方。#include Servo.h Servo myServo; const int servoPin 9; const int STOP_PULSE 1500; // 改为你实测的停止值 const int FORWARD_PULSE 1000; // 正向脉宽 const int REVERSE_PULSE 2000; // 反向脉宽 void setup() { Serial.begin(9600); myServo.attach(servoPin, 500, 2500); myServo.writeMicroseconds(STOP_PULSE); delay(1000); } void moveForMs(int pulse, int durationMs) { myServo.writeMicroseconds(pulse); delay(durationMs); myServo.writeMicroseconds(STOP_PULSE); delay(500); } void loop() { Serial.println(forward 1.5s); moveForMs(FORWARD_PULSE, 1500); Serial.println(reverse 1.2s); moveForMs(REVERSE_PULSE, 1200); delay(2000); }实际运行时会发现两次运行之间最终停留在哪个角度往往不一致。这正好说明开环控制的局限。7.3 辅助限位与外部传感器如果你确实需要在一个开环系统里“大致回到起点”可以加一个外部传感器做辅助在转台上安装一个挡片配合红外对管或霍尔传感器每次触碰到传感器就清零位置。使用电位器检测转轴位置把模拟电压读到 Arduino形成简单的角度反馈。使用 MPU6050 陀螺仪估算旋转角速度不过积分漂移会随时间增大。这些方法都不需要改造舵机本身但只有加上反馈之后控制系统才从“开环”变成“闭环”才能谈得上有定位能力。8. 资源占用、供电影响与性能观察8.1 Arduino UNO 上的软硬件资源Arduino UNO 的 ATmega328P 资源有限。Servo 库在 UNO 上会占用 Timer1同时库内部最多可以驱动 12 路舵机但每路舵机的刷新仍然依赖同一个定时器中断。实际项目中如果还要用millis()做非阻塞计时需要注意Servo 库的中断频率较高虽然millis()不受影响但如果你自己注册了Timer1中断或依赖 D9、D10 的 PWM 输出就很可能冲突。更稳妥的设计是把“舵机控制”和“业务逻辑”在程序结构上分离舵机只使用一个引脚其他 PWM 输出尽量放到 D3、D5、D6、D11 这些由 Timer2/Timer0 控制的引脚。8.2 电流与电压观察方法实测过程中建议这样观察USB 供电时舵机高速转动瞬间USB 电压可能被拉低。如果 Arduino 莫名其妙复位优先怀疑供电。用万用表串联测量舵机电流可以非常直观地看到空载、转动、堵转三个状态下的电流差值。堵转时电流最大因此不要让舵机长时间顶着机械结构。不同批次 SG90-360 的工作电压、堵转电流差异很大。以你手头实物为准不要直接把某个教程的电流值硬套到自己项目里。8.3 转速非线性的影响脉宽从停止点向两侧偏移得越多舵机转速通常越快但“脉宽差值”和“转速”不是严格的线性关系。比如从 1500 改为 1300转速可能变化很小从 1200 改为 1000转速增速却很明显。所以在做开环动作序列时不要把转速直接按脉宽差值线性估算。在实际负载下建议用秒表或计时器量出“1 秒大概转几圈”再用转速做时间换算。9. 常见问题与排查方法问题现象可能原因排查方式解决方案上电后完全不动信号线没接对、脉宽落在停止点或死区检查接线颜色使用串口程序输入偏离中心脉宽重新接信号线输入 1000 或 2000 测试舵机持续“嗡嗡”响但不转供电不足或脉宽仍在死区附近听声音判断是否堵转用可调脉宽逐个扫描改外部电源逐渐把脉宽调到更偏中心的值1500us 时舵机还在缓慢转动停止点不在默认中心值串口输入 1450-1550 之间的值逐个测试找到真实停止值并更新STOP_PULSE1000us 和 2000us 转向不符合预期方向定义与自己设计不一致测试中记录实际方向在代码里把“正转”和“反转”的常量值对调正反转速差异大舵机批次差异、供电电压不稳空载对比 1000us 和 2000us 的转速如果应用允许给不同方向设置不同脉宽值Arduino 在转动瞬间重启电流过大USB 口供电能力不足打开串口监视器观察复位信息舵机使用外部 5V 电源GND 共地转动到一半卡住并抖动机械负载过大或外部挡板限制让舵机空载测试去掉负载不要在有机械限位的情况下持续旋转D9 或 D10 的analogWrite()失效Servo 库占用 Timer1查看项目里是否同时使用这两个引脚舵机换到其他引脚或在架构上分开控制串口输入脉宽没反应波特率不一致或程序被阻塞检查串口监视器波特率是否为 9600确认Serial.begin(9600)与实际选择一致停止时舵机“吱吱”微调停止脉宽落在死区边缘用更小步进找中心使用更稳定的停止值不要在临界值附近运行10. 最佳实践与后续升级方向10.1 调试阶段建议先把舵机固定在测试台或桌面上不要让它在桌上乱跑。调试时尽量使用“停止 - 低速 - 停止”的节奏不要一上来就给最大脉宽避免突然的高转速和冲击。把找到的停止脉宽、正转速度范围、反转速度范围记录在代码开头形成一组可复用的常量。这样后续写小车、云台或机械结构时不必每次都从零校准。10.2 批量测试思路如果需要测试多台 SG90-360 舵机的一致性比如验收一批模块建议用串口发送指令的方式写一个简单测试脚本。思路是上位机通过串口发送脉宽值。Arduino 接收后输出到舵机。人工或摄像头观察舵机是否动作、是否停在预期位置。如果只是寿命测试可以让 Arduino 程序自己循环运行“正转 1 秒、停 0.5 秒、反转 1 秒、停 0.5 秒”然后记录运行时长。这种批量测试需要避免长时间堵转并给舵机留出散热时间。10.3 从开环走向闭环当你发现开环控制不够用时升级路径有两条更换带反馈的舵机或电机比如带编码器的直流减速电机、总线舵机等。保留 SG90-360但外部增加编码器、电位器或测速模块把位置或速度反馈给 Arduino。如果只是做简单的小车转向或转台旋转360 度舵机很好用但一旦需要精确角度、重复定位或闭环调速就应该尽早换方案。10.4 把舵机接入更大系统Arduino UNO 只是其中一种控制器。你可以把同样的脉宽控制逻辑移植到 ESP32、ESP8266、树莓派 Pico 等平台。如果通过上位机或 ROS 控制也是按“20ms 周期脉宽”发送控制信号。在接入实际设备前务必确认供电能力是否满足、机械结构是否安全、舵机堵转保护策略是否存在。舵机只是执行器不负责判断边界边界逻辑要由代码和机械设计来保证。11. 总结这篇内容围绕 SG90 360 度连续旋转舵机在 Arduino UNO 上的控制展开重点是掌握writeMicroseconds()的脉宽控制思路理解连续旋转舵机为什么是开环控制以及如何通过串口校准找到真实的停止点。建议收藏备用。如果你还没开始动手第一件事不是写复杂控制逻辑而是先把“串口输入脉宽”程序烧进去输入 1500、1000、2000确认舵机的停止、正转、反转都能正常响应。校准完成后再把脉宽和时间组合成动作序列后续写小车、转台或云台项目会顺利很多。
返回列表