news 2026/9/5 15:45:25

Arduino下SG90 360度连续旋转舵机实测:PWM控制与开环控制详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Arduino下SG90 360度连续旋转舵机实测:PWM控制与开环控制详解

刚入手 SG90 舵机时,我想做一个小型摇头云台,按网上的教程写servo.write(90)确实能转,但换成另一颗“SG90”后,角度却对不上,甚至出现“明明让舵机转 180°,结果它自己转了一圈又一圈”的现象。后来才发现,我拿到的是 SG90 的 360 度连续旋转版本,和普通位置舵机根本不是一回事。

本文就以 Arduino UNO 和 SG90 360 度连续旋转舵机为例,从硬件接线、PWM 控制原理、writeMicroseconds用法到开环控制的概念,做一个完整实测。新手可以把这篇当作入门教程,有基础的开发者也可以直接跳到第 4 节查看可复制代码和排错清单。

1. SG90 与 360 度连续旋转舵机

1.1 舵机是什么

舵机(Servo)是一种能根据控制信号执行动作的小型电机驱动模块。常见的模型舵机内部由直流电机、减速齿轮、控制电路组成。与传统直流电机不一样的是,舵机通常只需要一根信号线,就能让电机轴按要求动作,不需要自己做 H 桥驱动,使用门槛很低。

普通 SG90 是 180 度位置舵机,内部带有一个电位器,用来测量当前输出轴的位置。控制电路通过电位器反馈不断修正电机,让输出轴稳定停在指定角度。

而 360 度连续旋转舵机则是另一种形态。它的内部电位器往往被去掉,或者被固定替换成一个电阻分压网络,因此控制电路不再知道输出轴转到哪里。这时,给它一个 PWM 脉宽,它不会像普通舵机那样回到某个角度,而是会按某个方向和速度连续旋转。

1.2 SG90 标准版与 360 度连续旋转版的区别

很多初学者看到“SG90”就直接认为是 180 度舵机,实际上市场上常见两类:

对比项标准 SG90(位置舵机)SG90 360 度连续旋转舵机
输出轴限位有机械限位,约 0~180 度无机械限位,可连续旋转
内部电位器有,用于位置反馈无,或被固定替代
控制量PWM 脉宽对应目标角度PWM 脉宽对应方向和转速
典型行为给一定脉宽,停在指定角度给一定脉宽,持续朝某方向旋转
适合场景机械臂、云台角度控制小车驱动、摇头风扇、卷帘机构

从外部看,两种舵机都长一个样,重量也差不多,都是 9g 左右的微型舵机。购买时一定要向卖家确认是“180 度标准舵机”还是“360 度连续旋转舵机”,最好看产品标题和外包装,有些商家会把 360 度版本标成“带减速箱的连续旋转舵机”。

1.3 什么是开环控制

连续旋转舵机是一个典型的开环控制对象。所谓开环,是指控制器只管“输出指令”,不检测“实际结果”。比如我让舵机以某一个速度正转 2 秒,舵机到底转了多少圈,是否因为负载太大而转速下降,控制器并不知道。

因此,如果你试图用 360 度舵机精确控制云台转到某个固定角度,会发现很难。就算同样给writeMicroseconds(1700),空载时可能转得比较快,带负载后转速会明显下降。要做到精确定位,必须再加位置反馈,例如编码器或霍尔传感器,组成闭环控制。

本文的实测重点,是在理解这种开环特性的前提下,掌握如何让 360 度舵机稳定正转、反转、变速和停止。

2. 项目准备:硬件与接线

2.1 所需元件清单

我这次使用的环境如下:

  • Arduino UNO 开发板
  • SG90 360 度连续旋转舵机 1 个
  • 面包板 + 若干公对公杜邦线
  • 外部 5V 电源(可选,推荐)
  • 100~470uF 电解电容(可选,用于电源稳定)
  • 电脑 + Arduino IDE

如果你手头只有 USB 供电的 Arduino UNO,只接一个 SG90 空载测试也能转起来,但我不建议在带负载时继续依赖 Arduino 的 5V 引脚供电,原因后面单独讲。

2.2 SG90 引脚定义与接线方式

SG90 通常引出三根线,常见颜色和含义如下:

线色作用接到 Arduino UNO
棕色或黑色GNDGND
红色VCC / 电源正极5V(或外部 5V 正极)
橙色或黄色信号线数字引脚 D9

给出接线表:

SG90 360 度舵机 Arduino UNO 棕色线 --------------- GND 红色线 --------------- 5V 橙色线 --------------- D9

这里有一个需要特别注意的地方:不同品牌、不同批次舵机的线序并不完全一致。有的舵机红色线在中间,有的是棕色线在中间,建议先查看舵机外壳上的丝印或商家提供的规格书,不要凭颜色盲接。接反电源线轻则舵机不转,重则烧毁舵机控制板。

由于本文需要演示舵机转动效果,建议把舵机轴朝上放在桌面上,方便观察输出轴旋转方向。

2.3 供电建议:为什么不能只靠 Arduino 5V

SG90 正常工作电压一般在 4.8V~6V 左右。单独一个舵机堵转时电流可能达到几百毫安甚至更高,启动瞬间也会有较大电流波动。

Arduino UNO 的 5V 引脚由 USB 或 Vin 降压后提供,能输出的电流有限。如果舵机负载较大,电流会把板载 5V 电压拉低,轻则舵机无力、抖动,重则 Arduino 直接重启,串口监视器会看到连接断开或输出乱码。

更稳妥的接法如下:

  1. 舵机红色线接外部 5V 电源正极。
  2. 舵机棕色线接外部 5V 电源负极,同时接到 Arduino 的 GND。
  3. Arduino UNO 单独通过 USB 供电。

这种“共地”做法很重要。Arduino 输出的是信号电平,而舵机的功率电流主要从外部电源获取。信号参考地必须和电源地一致,否则信号无法形成完整回路。

如果手头没有外部电源,临时测试时可以用 Arduino 5V,但最好在 Arduino 5V 和 GND 之间并联一个 100uF 以上的电解电容。注意电容正极接 5V,负极接 GND,反接会损坏电容。

3. 控制核心:PWM 脉宽与 writeMicroseconds

3.1 舵机识别什么样的 PWM 信号

舵机的信号本质是一路周期约 20ms 的 PWM 方波,也就是 50Hz。输出脉冲的宽度通常被称为脉宽,单位是微秒。

标准位置舵机的脉宽和角度大致对应关系如下:

0.5ms -> 0 度左右 1.5ms -> 90 度左右 2.5ms -> 180 度左右

不过实际电路中,SG90 的脉宽范围通常取 1ms~2ms 更常见,比如 1ms 对应 0 度,1.5ms 对应 90 度,2ms 对应 180 度。这也是为什么很多人习惯调用writeMicroseconds(1000)writeMicroseconds(1500)writeMicroseconds(2000)来让舵机分别转到两端和中间。

对 360 度连续旋转舵机来说,脉宽不再对应位置,而对应方向和转速,因此不能用“脉宽等于角度”的思路去理解。常见对应关系如下:

约 1500us:停止 大于 1500us:一个方向连续旋转,脉宽越大转速越快 小于 1500us:另一个方向连续旋转,脉宽越小转速越快

更精确地说,舵机内部有一个“中心点”脉宽,通常默认在 1500us 附近。只要信号脉宽接近中心点,舵机就不会转;偏离中心点越远,目标转速越快。

3.2 writeMicroseconds 与 write 的区别

Arduino 的 Servo 库提供了两个常用方法:

servo.write(angle); servo.writeMicroseconds(pulseWidth);

write()是为普通位置舵机设计的,参数单位是角度。比如servo.write(90)会转换成约 1.5ms 的脉宽输出。如果你使用的是连续旋转舵机,还按角度去思考就会出现混乱。

writeMicroseconds()则直接输出指定的脉宽,单位是微秒,绕开了“角度换算”的中间层。连续旋转舵机本身没有角度概念,用这个函数更直观:

servo.writeMicroseconds(1500); // 停止 servo.writeMicroseconds(1700); // 正向旋转,速度较快 servo.writeMicroseconds(1300); // 反向旋转,速度较快

使用 Servo 库时还会用到attach(pin),它默认支持标准舵机脉宽范围。如果希望自定义角度映射范围,可以写成:

servo.attach(9, 1000, 2000);

这里第二个和第三个参数是角度换算的最小脉宽和最大脉宽。对于 360 度舵机,我们不依赖write()的角度换算,所以通常直接attach(9)就够了。

有一点需要提醒:Servo 库对脉冲宽度有一定限制,太极端或太宽的脉宽可能被裁剪掉。我们实际常用范围在 1000~2000us 之间,完全在支持范围内,不需要担心。

3.3 找到自己舵机的停止脉宽

不同厂家生产的 360 度舵机,中心点不一定是精确的 1500us。有的舵机写 1500us 可能还在缓慢转动,需要手动微调到 1480us 或 1520us 才会停。

因此拿到舵机后,先做一个中心点测试非常有必要。最简单的测试代码如下:

#include <Servo.h> Servo sg90; void setup() { sg90.attach(9); sg90.writeMicroseconds(1500); } void loop() { // 让舵机一直保持 1500us 脉宽,观察是否停止 }

把程序上传到 Arduino 后观察舵机。如果它还在缓慢转动,就把脉宽改成 1480、1490、1510、1520 逐个测试,找到让它完全静止的那个值。后面所有速度控制,都围绕这个实测出的中心值展开。

4. 实战:Arduino UNO 控制 360 度舵机正转、反转、变速、停止

4.1 演示逻辑设计

接下来完成一个完整可运行的实测程序。为了直观地展示 360 度舵机的行为,我们分阶段让舵机执行以下动作:

高速正转 2 秒 中速正转 2 秒 停止 2 秒 中速反转 2 秒 高速反转 2 秒 停止 3 秒

正转方向取决于舵机安装方式,如果发现方向反了,代码中正反转的脉宽对调即可。

4.2 编写完整代码:固定动作演示

新建一个 Arduino 工程,在 IDE 中创建文件,写入如下代码:

#include <Servo.h> Servo sg90; const int servoPin = 9; const int stopPulse = 1500; // 实测中心停止脉宽 void setup() { sg90.attach(servoPin); sg90.writeMicroseconds(stopPulse); delay(500); } void loop() { // 1. 高速正转 sg90.writeMicroseconds(1800); delay(2000); // 2. 中速正转 sg90.writeMicroseconds(1650); delay(2000); // 3. 停止 sg90.writeMicroseconds(stopPulse); delay(2000); // 4. 中速反转 sg90.writeMicroseconds(1350); delay(2000); // 5. 高速反转 sg90.writeMicroseconds(1200); delay(2000); // 6. 停止 sg90.writeMicroseconds(stopPulse); delay(3000); }

代码逻辑很简单:

  • #include <Servo.h>引入 Servo 库。
  • sg90.attach(servoPin)把舵机信号线绑定到 D9 引脚。
  • 每次切换速度前,先调用一次writeMicroseconds(),然后延时一段时间,让舵机转够指定时长。

这里有一个细节:连续旋转舵机写入脉宽后,舵机会持续保持当前转速,不会自动停。所以程序里每个阶段都要明确写新的脉宽。最后写1500us就是为了让舵机停下来。

4.3 编写完整代码:串口在线调速

固定动作演示只能验证舵机基本能力,不方便测试不同脉宽对应的实际转速。我们再用串口做一个更实用的“在线调速”工具:电脑向 Arduino 发送一个脉宽值,舵机立刻按该脉宽运行。

完整代码如下:

#include <Servo.h> Servo sg90; const int servoPin = 9; void setup() { Serial.begin(9600); sg90.attach(servoPin); sg90.writeMicroseconds(1500); Serial.println("SG90 360 servo serial test"); Serial.println("Please input pulse width, e.g. 1500"); } void loop() { if (Serial.available() > 0) { int pulse = Serial.parseInt(); // 简单范围保护,避免输入明显异常的值 if (pulse >= 800 && pulse <= 2200) { sg90.writeMicroseconds(pulse); Serial.print("Set pulse: "); Serial.println(pulse); } else { Serial.println("Out of range, please input 800-2200"); } // 清空串口缓冲区,避免连续触发多次 while (Serial.available() > 0) { Serial.read(); } } }

上传后打开 Arduino IDE 的串口监视器,把波特率设为 9600,在输入框中依次输入:

1500 1600 1700 1800 1400 1300 1200

观察舵机变化。输入 1500 时舵机应停止;输入 1700、1800 时朝一个方向旋转,脉宽越大转速越快;输入 1300、1200 时朝另一个方向旋转,脉宽越小转速越快。

4.4 运行与预期结果说明

正常现象如下:

  • 写入 1500us,舵机轴基本静止,用手轻捏输出轴能感觉到电机处于锁止或不输出扭矩的状态。
  • 写入 1700us,舵机以较慢速度持续朝一个方向旋转。
  • 写入 1800us,舵机更快地朝同方向旋转。
  • 写入 1300us,舵机朝另一个方向旋转。
  • 写入 1200us,反转速度更快。

如果通电后舵机不仅不转,还发出“嗡嗡”的抖动声,通常说明信号不正常或供电不足,可以按照第 5 节排查。

4.5 结合电位器做一个简易转速调节

如果希望不依赖电脑串口,也可以用一个 10k 电位器来调节 PWM 脉宽。将电位器两端接 Arduino 5V 和 GND,中间抽头接 A0 引脚,然后用analogRead()读到的 0~1023 映射到 1000~2000us。示例代码如下:

#include <Servo.h> Servo sg90; const int potPin = A0; const int servoPin = 9; void setup() { sg90.attach(servoPin); sg90.writeMicroseconds(1500); } void loop() { int potValue = analogRead(potPin); // 将 0~1023 映射到 1000~2000us int pulse = map(potValue, 0, 1023, 1000, 2000); sg90.writeMicroseconds(pulse); delay(15); }

这个例子说明了一个关键点:360 度舵机的输入信号在 1000~2000us 之间是连续可调的,因此改变电位器位置,就能平滑改变舵机转速和方向。电位器旋到中间位置时输出约 1500us,舵机停止;往两边旋转时,舵机开始加速转动。

5. 常见问题与排查思路

5.1 问题汇总表

问题现象常见原因解决思路
舵机不转,一点反应都没有接线错误或供电不足核对三条线,改用外部 5V 电源
舵机抖动、进退反复信号线接触不良或脉宽处于临界死区重新插紧杜邦线,微调脉宽避开临界值
舵机一直转、无法停止停止脉宽不是 1500us用 3.3 节方法找到真实中心点
转动方向与预期相反正反转脉宽定义反了把大于中心点和小于中心点的值对调
一接舵机 Arduino 就重启舵机启动电流拉低板载电压使用外部电源,增加滤波电容
带负载后转速明显下降电源功率不足或舵机超载换更大电流电源,或降低机械负载
想转固定角度但始终不准360 度舵机无位置反馈改用反馈舵机或添加编码器闭环

5.2 Arduino 一接舵机就重启

这是最常见的问题。由于舵机启动和堵转时电流突增,Arduino 的稳压器件会被严重拉低,甚至 USB 供电自动复位。

解决步骤:

  1. 断开舵机红线与 Arduino 5V 的连接。
  2. 使用外部 5V 电源的正极接舵机红线。
  3. 外部电源负极同时接舵机棕线和 Arduino GND。

如果仍然不稳定,可以在舵机电源两端并联一个 100~470uF 电解电容,电容尽量靠近舵机电源引脚。

5.3 停止位置需要校准

一部分 360 度舵机标称中心点就是 1500us,但实际会有偏差。比如我手头有一颗舵机,写入 1500us 时还在缓慢正转,改成 1470us 才停。

校准步骤可以按下面来:

  1. 先把脉宽设成 1500us,观察舵机是否停。
  2. 如果还转,每次增减 10us,例如 1480、1470、1460。
  3. 找到“临界停止点”,如果 1470us 不转但 1460us 会反转,说明停止点就在两者之间。
  4. 把这个停止点保存为常量stopPulse,后续代码都用它代替固定 1500。

校准之后,转速控制才能准确。否则你会觉得舵机转速忽快忽慢,其实只是中心点偏移导致的“假象”。

5.4 脉宽接近中心值时舵机抖动

在中心点附近,舵机控制电路会进入临界状态,可能出现输出轴轻微抖动或发出电流声。这是正常现象。工程上可以设置一个“死区”,让脉宽落在一定范围内时强制输出停止脉宽:

if (pulse > 1490 && pulse < 1510) { sg90.writeMicroseconds(stopPulse); } else { sg90.writeMicroseconds(pulse); }

这样执行器就不会因为微小脉宽变化而频繁抖动。

6. 最佳实践与工程建议

6.1 供电设计放在第一位

微型 360 度舵机虽然看起来小,但工程应用时必须把供电当成大头问题。

建议:

  • 不要用 Arduino 5V 引脚驱动多个舵机。
  • 选用能持续输出 1A 以上的 5V 电源,具体按舵机数量和负载评估。
  • 舵机电源与单片机控制板共地,但尽量分别供电。
  • 长线供电时,在舵机端并联一个电容。

如果使用锂电池或大容量电源,还应该在电源输入端并联一个大电容,避免热插拔时拉弧损坏接口。

6.2 把“停止脉宽”定义成常量

与其在代码里到处写 1500,不如在校准后给它一个名字:

const int SERVO_STOP_US = 1470;

这样后期如果更换舵机,只需要修改这一处常量,不需要搜索整个程序替换数字。这也是良好的代码习惯。

6.3 明确开环控制的边界

360 度连续旋转舵机的核心特征是开环速度控制,它适合以下场景:

  • 摇头风扇叶片旋转。
  • 摄像头持续扫描。
  • 小车简单前进后退。
  • 机械结构往复运动。

它不适合以下场景:

  • 云台需要精确停在某个角度。
  • 机械臂关节需要位置保持。
  • 需要判断当前是否发生堵转。
  • 需要知道舵机转了多少圈。

如果你的项目是上面这些“位置敏感”需求,建议换回标准位置舵机,或选用带反馈的 360 度舵机、双轴编码器电机,再配合 PID 控制器实现闭环。

6.4 程序结构建议

即使是一个小小的舵机控制程序,我也建议把关键参数集中管理。示例:

#include <Servo.h> Servo sg90; const int SERVO_PIN = 9; const int STOP_PULSE_US = 1500; const int MAX_SPEED_US = 1800; const int MIN_SPEED_US = 1200; void setup() { sg90.attach(SERVO_PIN); sg90.writeMicroseconds(STOP_PULSE_US); } void drive(int pulseUs, int durationMs) { sg90.writeMicroseconds(pulseUs); delay(durationMs); } void loop() { drive(MAX_SPEED_US, 2000); drive(STOP_PULSE_US, 1000); drive(MIN_SPEED_US, 2000); drive(STOP_PULSE_US, 1000); }

封装之后,后续如果要增加更多动作,只需要维护drive()的调用序列即可。对稍微复杂一点的项目,还能用状态机代替delay(),这里不展开。

6.5 安全与异常保护

连续旋转舵机的输出轴一直转动,如果机械结构卡住,电机会持续堵转并发热,严重时会烧坏舵机内部驱动芯片。

在项目中建议:

  1. 在程序中增加运行时间保护,避免舵机长时间同一方向运行。
  2. 机械结构预留限位或过载打滑空间。
  3. 必要时在电源回路中串联自恢复保险丝。

举个例子,如果你在做一个自动卷帘机构,舵机正转 3 秒应该到达上限,但万一限位开关失效,程序就会一直输出正转信号。此时可以加一个简单判断:连续正转超过 5 秒就强制停止并报错。

7. 总结与上手清单

写到这里,关于 SG90 360 度连续旋转舵机的基础知识和测试方法已经讲得比较完整了。我建议你拿到舵机后,按下面这个顺序做一遍初测:

第 1 步:确认舵机确实是 360 度连续旋转版本。 第 2 步:正确接线,尽量使用外部电源并共地。 第 3 步:写入 1500us,观察舵机是否停止。 第 4 步:如果还在转,用串口工具微调出真实停止脉宽。 第 5 步:分别测试 1700us 和 1300us,确认正反转方向。 第 6 步:把测试结果整理成常量,再开始做实际项目。

这样做的好处是,你不会跳过供电和停止脉宽校准这两个最容易踩坑的步骤。后面无论是做云台摇头、小车驱动,还是其他自动化工装,都能少走不少弯路。如果遇到舵机抖动、方向相反或 Arduino 重启的问题,可以直接参考本文第 5 节的排查表。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/5 15:43:53

MoE 负载均衡深度解析:专家累死、摸鱼与负载崩塌

简介 MoE(混合专家模型)最致命的原生缺陷:路由器马太正反馈引发负载崩塌。训练过程中路由器会持续把 Token 路由到少数表现更好的专家,其余专家长期接收样本不足陷入休眠;显存、参数资源大量浪费,MoE 稀疏加速增益直接消失,性能甚至劣于同规模稠密大模型。 行业主流解法…

作者头像 李华
网站建设 2026/9/5 15:42:41

基于STM32与PAJ7620的手势识别系统:从硬件搭建到软件抗干扰实战

简介&#xff1a;本资源是一套基于STM32F10x系列微控制器与PAJ7620红外手势识别传感器的完整嵌入式开发实践方案&#xff0c;面向嵌入式初学者、课程设计学生及智能交互硬件开发者&#xff0c;解决非接触式人机交互系统从驱动适配到手势响应的全流程实现问题。压缩包共98个文件…

作者头像 李华
网站建设 2026/9/5 15:39:36

PMSM无感FOC转子初始位置辨识:脉冲注入法原理与工程实践

PMSM 无感 FOC 控制中&#xff0c;电机启动前的转子初始位置辨识是一个绕不开的环节。很多人第一次接触“脉冲注入法”时&#xff0c;会以为它和传统的高频方波注入类似&#xff0c;只要向 d 轴注入电压脉冲就能收敛到磁极方向。实际做实机测试后才会发现&#xff0c;IPM 电机的…

作者头像 李华
网站建设 2026/9/5 15:39:24

MATLAB实现TVP-VAR模型:时变参数估计与三维脉冲响应可视化

简介&#xff1a;本资源是一套面向宏观经济学与金融计量研究者的TVP-VAR&#xff08;时变参数向量自回归&#xff09;模型MATLAB实现代码&#xff0c;适用于具备基础计量经济学知识和MATLAB编程能力的研究生、青年学者及政策分析人员&#xff0c;用于估计时变结构关系、开展动态…

作者头像 李华
网站建设 2026/9/5 15:34:21

毕业论文修改的进阶指南:从工具选择到降重实战

在毕业论文的写作旅程中&#xff0c;文本修改与降重是每位学子必经的关卡。无论是盲审前的最后冲刺&#xff0c;还是提交前的格式校对&#xff0c;我们总会面临一个核心问题&#xff1a;面对琳琅满目的修改工具和方法&#xff0c;究竟该如何选择&#xff1f;传统的同义词替换、…

作者头像 李华