MG995/MG996R舵机全解析:从PWM控制到机器人项目实战

发布时间:2026/10/7 11:04:38
MG995/MG996R舵机全解析:从PWM控制到机器人项目实战
1. 为什么MG995和MG996至今仍是机器人项目的热门选择1.1 从参数看本质这两颗舵机到底强在哪MG995和MG996R算是舵机圈里的“老熟人”了。但凡接触过机械臂、仿生机器人、双足行走或者云台项目的人大概率都用过或者至少听说过这两颗舵机。它们之所以能长期占据入门到中端机器人项目的选型清单核心原因就一个在扭矩、价格、体积三者之间找到了一个极其舒服的平衡点。先看关键参数。MG995的标称扭矩大约在9到11 kg·cm之间取决于供电电压MG996R稍微高一些能到10到13 kg·cm。这个扭矩水平意味着什么你可以把它理解成在舵机摇臂末端1厘米的位置它能拉动大约10公斤的重物。放到实际项目里驱动一个20到30厘米长的机械臂关节、转动一个中等尺寸的云台、或者带动仿生机器人的腿部关节这个力量是够用的。工作电压方面两者都支持4.8V到7.2V的宽电压范围。这里有个很多人忽略的细节标称扭矩通常是在6V甚至7.2V下测得的。如果你只用5V供电实际扭矩会打折扣大概只有标称值的70%左右。所以做项目时供电方案的设计直接决定了你能不能把舵机的性能榨干。再说控制方式。MG995和MG996R都是标准的PWM舵机接收50Hz的PWM信号通过脉冲宽度来控制角度。典型情况下0.5ms脉宽对应0度2.5ms对应180度1.5ms对应中间位置90度。这个控制逻辑非常简单几乎任何一款单片机都能轻松驱动。参数项MG995MG996R标称扭矩9-11 kg·cm10-13 kg·cm工作电压4.8V-7.2V4.8V-7.2V控制信号PWM 50HzPWM 50Hz转动范围约180度约180度齿轮材质金属金属重量约55g约55g空载速度0.20s/60度0.17s/60度从表格能看出来MG996R基本就是MG995的改进版速度稍快、扭矩稍大齿轮结构也更耐用一些。实际项目中如果预算允许优先选MG996R会省心不少。1.2 谁适合用这两颗舵机典型应用场景盘点MG995和MG996R的应用场景非常广泛我按自己接触过的项目类型来分类说说。机械臂关节驱动是最常见的用法。一个四自由度或者六自由度的桌面机械臂底座旋转、大臂抬升、小臂弯曲、腕部旋转每个关节用一颗MG996R配上铝合金支架和轴承整体成本能控制在几百块以内。这种方案在创客教育和入门级科研项目里非常流行。仿生机器人也是大户。不管是四足爬行机器人还是双足行走机构MG995的扭矩刚好能支撑起小型机身的重量。我见过不少人用12颗MG995做四足机器人每条腿三个关节走起来虽然不如高端舵机那么丝滑但胜在成本低、替换方便。云台和转向机构同样适用。两轴云台用两颗MG996R一个控制俯仰一个控制偏航搭载摄像头或者激光测距模块做目标跟踪或者环境扫描都很合适。另外像智能小车的转向舵机、太阳能板追光装置、自动门锁机构也经常能看到这两颗舵机的身影。教育和竞赛项目里它们更是常客。价格便宜意味着学生可以大胆试错坏了换一颗就行不会因为烧了一个舵机就导致整个项目停摆。而且PWM控制原理简单非常适合用来教学舵机控制原理和闭环反馈的概念。1.3 选型前必须想清楚的三个问题在动手之前有三个问题必须先回答清楚否则后面很容易返工。第一你的项目需要多大扭矩别只看舵机标称值要算实际负载。比如机械臂大臂关节负载包括小臂重量、腕部重量、末端执行器重量再加上力臂长度算出来的扭矩需求可能远超你的直觉。经验做法是估算出理论扭矩后至少留50%的余量。也就是说如果你算出来需要6 kg·cm那就选10 kg·cm以上的舵机。第二供电能不能跟上MG996R堵转电流能到2.5A甚至更高多颗舵机同时动作时瞬间电流可能超过10A。如果你用Arduino板上的5V引脚直接供电大概率会遇到舵机抖动、复位甚至单片机重启的问题。独立供电是必须的后面我会详细讲供电方案。第三控制精度要求高不高MG995和MG996R是模拟舵机内部没有位置反馈输出控制精度大概在±3到5度左右。如果你的项目需要高精度角度控制比如精密抓取或者激光指向那可能需要考虑数字舵机或者总线舵机。但对于大多数入门和中级项目来说这个精度完全够用。2. 舵机控制原理与PWM信号深度拆解2.1 PWM到底是怎么控制舵机角度的PWM控制舵机的原理说白了就是用脉冲宽度传递角度信息。舵机内部有一个基准电路产生周期20ms也就是50Hz的基准信号同时有一个位置反馈电位器检测当前输出轴的角度。控制电路把外部输入的PWM信号和内部基准进行比较得到偏差电压驱动电机正转或者反转直到偏差为零。这个过程是闭环的但闭环在舵机内部完成你不需要自己做PID。你只需要告诉它“我要你去哪个角度”它自己会转过去并保持住。这也是舵机比普通直流电机好用的地方——你给角度它执行不需要额外的编码器和控制算法。具体到信号参数周期固定20ms高电平持续时间从0.5ms到2.5ms线性对应0到180度。换算一下每度对应的高电平时间变化是(2.5-0.5)/180 ≈ 0.0111ms也就是大约11.1微秒。这个精度要求不算高普通定时器都能轻松实现。但这里有个坑不同厂家、不同批次的舵机脉宽范围可能有偏差。有的舵机0.4ms就到0度了有的要到0.6ms。如果你发现舵机转到极限位置时发出“吱吱”的堵转声说明脉宽超出了它的实际范围需要适当收窄。我一般会在代码里把脉宽范围限制在0.6ms到2.4ms牺牲一点角度范围换取舵机寿命。2.2 用Arduino驱动MG995的完整代码与接线Arduino驱动舵机是最常见的入门方案因为有现成的Servo库几行代码就能跑起来。但简单归简单接线和供电如果做不对照样翻车。先看接线。MG995有三根线棕色接GND红色接VCC4.8V-7.2V橙色接信号线。信号线接到Arduino的任意数字引脚比如9号脚。但红色线绝对不要接到Arduino的5V引脚上原因前面说过了电流不够。正确的供电方案是用一个独立的5V或6V电源比如LM2596降压模块从12V锂电池降压或者直接用4节镍氢电池组给舵机供电电源的GND和Arduino的GND连在一起信号线照常接。这样舵机吃自己的电Arduino吃USB的电互不干扰。#include Servo.h Servo myServo; void setup() { myServo.attach(9); // 信号线接9号引脚 } void loop() { myServo.write(0); // 转到0度 delay(1000); myServo.write(90); // 转到90度 delay(1000); myServo.write(180); // 转到180度 delay(1000); }这段代码是最基础的来回扫动。Servo库默认的脉宽范围是544到2400微秒对应0到180度。如果你发现舵机在0度或180度时抖动厉害可以用myServo.attach(9, 600, 2400)来手动指定脉宽范围把两端各收一点。注意Arduino的Servo库会占用定时器在UNO上最多同时控制12个舵机在Mega2560上最多48个。如果你需要控制更多舵机或者需要更精确的定时控制就得自己写定时器代码或者用PCA9685这样的舵机驱动板。2.3 用ESP32和STM32实现更灵活的控制Arduino方便归方便但如果你要做多舵机协同、需要WiFi/蓝牙远程控制、或者对实时性有要求ESP32和STM32是更好的选择。ESP32控制舵机的优势在于它有多路LEDCLED PWM控制器通道可以独立产生PWM信号不占用CPU时间。而且ESP32自带WiFi和蓝牙做手机APP控制或者网络远程控制非常方便。用Arduino框架开发ESP32时可以用ledcSetup()和ledcWrite()函数来配置PWM。// ESP32控制舵机示例 int servoPin 18; int channel 0; int freq 50; int resolution 16; void setup() { ledcSetup(channel, freq, resolution); ledcAttachPin(servoPin, channel); } void setAngle(int angle) { // 0.5ms-2.5ms 映射到 16位分辨率下的占空比 int duty map(angle, 0, 180, 1638, 8192); ledcWrite(channel, duty); } void loop() { setAngle(0); delay(1000); setAngle(90); delay(1000); setAngle(180); delay(1000); }这里的计算逻辑是这样的50Hz周期是20ms16位分辨率下最大值是65535所以20ms对应65535。0.5ms对应的占空比是65535 * 0.5 / 20 16382.5ms对应65535 * 2.5 / 20 8192。用map函数把角度线性映射到这个范围就行。STM32控制舵机通常用定时器PWM输出模式。以STM32F103为例配置TIM3的通道1产生50Hz PWM预分频器和自动重装载值的计算如下系统时钟72MHz预分频器设为71得到1MHz计数频率自动重装载值设为19999得到20ms周期。然后修改捕获比较寄存器的值来改变脉宽。// STM32 HAL库配置TIM3 CH1 PWM输出 // 预分频器 72-1, 自动重装载值 20000-1 // 计数频率 72MHz / 72 1MHz, 周期 20000 / 1MHz 20ms void setServoAngle(TIM_HandleTypeDef *htim, uint32_t channel, uint8_t angle) { // 0.5ms - 500, 2.5ms - 2500 uint32_t pulse 500 (angle * 2000) / 180; __HAL_TIM_SET_COMPARE(htim, channel, pulse); }STM32的方案适合需要多路舵机、同时还要跑其他任务的项目。如果你用FreeRTOS可以把舵机控制放在一个独立任务里通过队列接收目标角度这样不会阻塞主循环。2.4 多舵机协同与电源管理的实战经验单个舵机好搞多个舵机一起动就是另一回事了。我做过一个六自由度机械臂六颗MG996R同时动作时电流表显示瞬间峰值到了12A。如果你用一块5V 3A的电源结果就是电压被拉低舵机全部抖动单片机反复复位。电源方案的选择我试过几种说说各自的优缺点。第一种是用大容量锂电池加降压模块比如3S锂电池11.1V配LM2596降压到6V。优点是能量密度高、续航长缺点是降压模块本身有压降和发热大电流下效率会下降。第二种是用开关电源直接输出6V比如5V 10A的开关电源调到6V优点是稳定、便宜缺点是要插220V不方便移动。第三种是用多节镍氢电池组5节1.2V就是6V优点是干净、无噪声缺点是重量大、充电慢。我的建议是桌面项目用开关电源移动项目用锂电池加降压模块。不管哪种方案都要在电源输出端并一个大电容1000uF以上用来吸收舵机启动时的电流冲击。另外多舵机协同的时候尽量避免所有舵机同时启动。可以在代码里加一个小的延时让舵机依次上电间隔50到100毫秒。这样能显著降低瞬间峰值电流对电源更友好。3. 从机械结构到控制逻辑完整项目实操记录3.1 机械臂项目四自由度舵机臂的搭建过程我拿一个最近做的四自由度机械臂项目来完整走一遍流程。这个机械臂有四个关节底座旋转、大臂抬升、小臂弯曲、夹爪开合。四个关节全部用MG996R驱动结构件是3D打印的控制器用ESP32。结构设计阶段要注意几个点。底座旋转关节承受的是整个机械臂的重量和力矩所以底座舵机要选扭矩最大的而且最好加一个推力轴承来分担轴向力否则舵机输出轴很快会磨损。大臂关节的力臂最长负载最大我算了一下小臂加腕部加夹爪大约300克力臂15厘米需要的扭矩是0.3kg × 15cm 4.5 kg·cm。加上安全余量MG996R的10 kg·cm完全够用。3D打印件设计的时候舵机安装位要留0.2到0.3毫米的间隙否则装配时太紧。舵机盘和结构件的连接用M3螺丝加螺母不要用自攻螺丝容易滑丝。另外每个关节的转轴最好用轴承支撑不要让舵机输出轴直接承受径向力这是延长舵机寿命的关键。装配顺序也有讲究。先装底座舵机再装大臂然后装小臂最后装夹爪。每装一个关节就通电测试一下角度范围确认没有机械干涉再继续。我见过有人全部装完才发现某个关节转不到位拆起来非常麻烦。3.2 控制程序从单关节测试到多关节联动程序开发我习惯分三步走先单关节测试再多关节顺序控制最后做联动和轨迹规划。单关节测试就是让每个舵机单独从0度转到180度再转回来观察运动是否平滑、有没有异响、角度范围是否准确。这一步能发现大部分机械和电气问题。多关节顺序控制是让多个舵机依次动作比如先底座旋转再大臂抬升再小臂弯曲。这一步主要测试电源能不能扛住以及舵机之间有没有信号干扰。联动和轨迹规划是最复杂的部分。如果直接让舵机从当前角度跳到目标角度运动会很生硬而且对机械结构冲击大。我一般用插值的方式把大角度变化分解成多个小步每步之间加延时实现平滑运动。// 平滑运动函数 void smoothMove(Servo servo, int fromAngle, int toAngle, int stepDelay) { int step (toAngle fromAngle) ? 1 : -1; for (int angle fromAngle; angle ! toAngle; angle step) { servo.write(angle); delay(stepDelay); } servo.write(toAngle); }stepDelay的大小决定了运动速度一般设10到20毫秒比较合适。太小了舵机响应不过来太大了运动太慢。对于更复杂的轨迹比如让夹爪走一条直线或者圆弧就需要做逆运动学计算了。不过对于入门项目来说用简单的角度插值就能满足大部分需求。3.3 加入传感器舵机与激光测距的串口数据回传给机械臂加上激光测距模块之后就能做简单的环境感知和自动抓取了。我用的是VL53L0X激光测距模块I2C接口量程2米精度毫米级。整个系统的逻辑是这样的ESP32控制四个舵机同时通过I2C读取激光测距数据然后把角度和距离信息通过串口发送到电脑电脑端用Python脚本接收并显示。如果距离小于设定阈值就触发抓取动作。#include Wire.h #include Adafruit_VL53L0X.h #include ESP32Servo.h Adafruit_VL53L0X lox Adafruit_VL53L0X(); Servo servoBase, servoArm, servoForearm, servoGripper; void setup() { Serial.begin(115200); Wire.begin(); lox.begin(); servoBase.attach(13); servoArm.attach(14); servoForearm.attach(25); servoGripper.attach(26); } void loop() { VL53L0X_RangingMeasurementData_t measure; lox.rangingTest(measure, false); if (measure.RangeStatus ! 4) { int distance measure.RangeMilliMeter; Serial.print(Distance: ); Serial.print(distance); Serial.println( mm); if (distance 100) { // 触发抓取 servoGripper.write(0); } else { servoGripper.write(90); } } delay(100); }电脑端用Python的pyserial库接收数据可以实时打印或者画图。这个框架可以扩展到更复杂的场景比如扫描周围环境生成点云、自动寻找目标物体等。3.4 用PCA9685扩展板驱动多路舵机的实操当舵机数量超过Arduino或ESP32的PWM通道数时PCA9685是最常用的扩展方案。这是一块16通道的PWM驱动板I2C接口一颗就能驱动16个舵机而且PWM频率和脉宽都可以精确设置。接线很简单PCA9685的VCC接3.3V或5V逻辑电源GND共地SCL和SDA接单片机的I2C引脚。舵机的电源单独接PCA9685的V端子这个端子要接独立的大电流电源。信号线接PCA9685的0到15通道。#include Wire.h #include Adafruit_PWMServoDriver.h Adafruit_PWMServoDriver pwm Adafruit_PWMServoDriver(0x40); void setup() { pwm.begin(); pwm.setPWMFreq(50); // 50Hz } void setServoAngle(uint8_t channel, uint8_t angle) { // 0.5ms - 102, 2.5ms - 512 (基于PCA9685的12位分辨率) int pulse map(angle, 0, 180, 102, 512); pwm.setPWM(channel, 0, pulse); }PCA9685的12位分辨率意味着每个周期有4096个计数50Hz下每个计数对应4.88微秒。0.5ms对应1022.5ms对应512。这个精度对舵机控制来说绰绰有余。提示PCA9685的V和GND要接粗线因为16个舵机同时动作时电流可能超过20A。板子上的走线比较细大电流下会发热建议在V端子上直接焊粗铜线。4. 踩坑实录MG995/MG996常见问题与排查技巧4.1 舵机抖动、复位、发热的根因分析舵机抖动是最常见的问题表现是舵机在目标角度附近来回小幅摆动发出“嗡嗡”声。原因通常有三个一是电源功率不足电压被拉低导致舵机内部电路工作不稳定二是PWM信号受到干扰比如信号线和电源线捆在一起走线三是舵机内部电位器磨损反馈信号不准确。排查方法先用万用表测舵机供电电压如果舵机动作时电压跌落超过0.5V那就是电源问题。再把信号线远离电源线最好用屏蔽线或者双绞线。如果换了新舵机还是抖那就是信号问题如果换了就不抖了那就是舵机老化。舵机复位指的是舵机突然自己转到某个固定角度不受控制。这通常是单片机复位导致的而单片机复位的原因多半是电源被舵机拉垮了。解决办法就是前面说的独立供电加大电容。舵机发热分正常发热和异常发热。轻微温热是正常的电机和齿轮摩擦会产生热量。但如果烫手说明舵机在堵转或者长时间大电流工作。检查机械结构有没有卡死角度范围有没有超出舵机极限负载是不是太大了。问题现象可能原因排查方法解决方案舵机抖动电源不足/信号干扰/电位器磨损测电压/换信号线/换舵机独立供电/屏蔽线/更换舵机复位单片机复位监测单片机电源独立供电大电容舵机发热堵转/过载/角度超限检查机械/测电流减轻负载/限制角度舵机不动信号线接错/舵机烧毁换通道测试重新接线/更换角度不准脉宽范围不匹配调整脉宽范围校准脉宽4.2 电源方案对比为什么你的舵机总是带不动我做过一个对比测试用同一颗MG996R分别用Arduino板载5V、LM2596降压模块、5V 10A开关电源供电测量舵机从0度转到180度时的电压和电流变化。Arduino板载5V的结果最差空载电压5.02V舵机启动瞬间跌到4.1V舵机抖动明显单片机偶尔复位。LM2596的结果中等空载6.0V启动瞬间跌到5.3V舵机动作正常但降压模块发热明显。开关电源的结果最好空载6.0V启动瞬间跌到5.8V舵机动作干脆利落没有任何抖动。结论很明确舵机供电功率至少留两倍余量。一颗MG996R按2A算四颗就按8A准备电源标称电流至少10A。别信那些标称5V 2A的小电源能带动多颗舵机都是虚标。另外电源线要够粗。我见过有人用杜邦线给舵机供电线径只有0.2平方毫米大电流下线材发热严重压降也大。建议用0.5平方毫米以上的硅胶线长度尽量短。4.3 舵机寿命延长与维护的独家经验MG995和MG996R的寿命官方标称是几万次转动但实际用下来如果负载合理、供电稳定用一两年没问题。如果经常堵转或者过载可能几个月就出现虚位或者抖动。几个延长寿命的经验第一避免长时间堵转。舵机转到极限位置时如果还在持续输出扭矩电机堵转电流很大发热严重。在代码里限制角度范围或者在机械结构上加限位块。第二定期检查齿轮间隙。金属齿轮用久了会有磨损表现为角度虚位变大。如果虚位超过5度就该考虑更换齿轮组了。第三保持舵机清洁。灰尘进入齿轮箱会加速磨损尤其是在多尘环境里使用的项目。还有一个容易被忽略的点舵机盘的安装。舵机盘和输出轴之间是花键连接如果螺丝拧得太紧或者太松都不好。太紧会压坏花键太松会有间隙。我一般拧到感觉有阻力后再拧半圈然后用螺纹胶固定。4.4 常见问题速查表与排查流程遇到舵机问题我一般按这个流程排查先看电源测舵机供电电压动作时跌落是否超过0.5V。是则换电源或加大电容。再看信号用示波器或者逻辑分析仪看PWM波形周期是否20ms脉宽是否在0.5-2.5ms范围内。然后看机械手动转动舵机盘感觉有没有卡顿或者异响。有则检查机械结构。最后换舵机如果以上都正常换一颗新舵机测试。新舵机正常说明旧舵机老化或损坏。这个流程能解决90%以上的舵机问题。剩下的10%可能是控制代码的bug比如定时器配置错误、中断优先级冲突等需要具体分析。提示如果你用STM32的HAL库配置PWM注意HAL_TIM_PWM_Start()之后才能输出波形。另外如果用了FreeRTOSPWM启动要在任务调度开始之前完成否则可能会有短暂的信号异常。5. 进阶方向从单舵机到机器人系统的扩展思路5.1 总线舵机与PWM舵机的取舍当你做的项目越来越复杂PWM舵机的局限性就显现出来了接线多、占用IO多、没有反馈、精度有限。这时候可以考虑总线舵机比如飞特系列。总线舵机通过串口通信一根线串联多个舵机每个舵机有唯一ID可以读取当前位置、温度、负载等参数。但总线舵机也不是万能的。价格比PWM舵机贵不少控制协议更复杂而且需要专门的驱动板。我的建议是入门项目用PWM舵机中高级项目用总线舵机。如果你只是做一个小机械臂或者云台MG996R完全够用。如果你要做六轴协作机械臂或者需要力控的场景那就上总线舵机。5.2 从舵机控制到机器人导航的跨越舵机控制是机器人运动控制的基础。当你掌握了多舵机协同之后就可以往更高层次扩展了。比如给四足机器人加上IMU和激光雷达用ROS2做导航和路径规划。舵机负责底层关节运动上层算法负责决策和规划。这个跨越的关键在于接口设计。底层舵机控制要封装成统一的接口比如setJointAngle(joint_id, angle)上层算法不需要关心底层是PWM舵机还是总线舵机。这样以后升级硬件时上层代码不用改。另外实时性是另一个关键点。舵机控制对实时性要求不高50Hz足够了。但导航算法可能需要更高的更新频率这时候就要考虑用RTOS或者多核处理器把舵机控制和导航算法分配到不同的核心上。5.3 仿真先行用三维模型验证舵机运动范围在动手搭建之前我强烈建议先在仿真环境里验证一下。用SolidWorks或者Fusion 360建一个三维模型把舵机的运动范围、关节的干涉情况都模拟一遍。这样能提前发现很多机械设计问题省得装好了再拆。如果要做更复杂的运动规划可以用Gazebo或者CoppeliaSim做动力学仿真。把舵机的扭矩、速度参数输入进去看看能不能完成预期的动作。仿真结果虽然不能完全替代实物测试但能帮你排除大部分明显的设计缺陷。我自己的习惯是仿真验证通过之后再打印零件、采购舵机。这样能避免很多“装到一半发现不对”的尴尬情况。尤其是3D打印件打一次要几个小时返工成本很高。5.4 项目扩展加上视觉和AI能做什么舵机加视觉能玩的东西就多了。最简单的用OpenMV或者树莓派加摄像头识别颜色块然后控制舵机云台跟踪目标。再复杂一点用YOLO做物体检测控制机械臂去抓取指定物体。这里的关键是坐标转换。摄像头看到的是像素坐标舵机需要的是角度。你需要做相机标定建立像素坐标到世界坐标的映射关系。然后根据目标位置反算出各个关节的角度这就是逆运动学。对于入门项目可以先用简单的比例控制目标在画面左边云台就往左转目标在右边就往右转。等熟悉了再做精确的坐标转换和逆运动学。视觉加舵机的方案在分拣、追踪、自动抓取等场景里都有实际应用。虽然MG995和MG996R的精度有限但做demo和原型验证完全够用。等方案跑通了再换更高精度的执行器也不迟。我个人在实际操作中的体会是MG995和MG996R最大的价值不在于性能有多强而在于它们足够便宜、足够简单、足够可靠让你能把精力集中在真正重要的地方——机械结构设计、控制逻辑、系统集成。等你把这些都跑通了换更好的舵机只是替换一个零件的事。所以别在选型上纠结太久先动手做起来遇到问题再解决问题这才是做机器人项目最快的成长路径。