发布时间: 2026-04-20
在机器人里、智能小车当中以及机械臂这类项目内伟创动力,舵机被用来把电信号转变为精准的角度转动。许多初次接触单片机的用户会碰到一个问题,那就是明明代码写好了,舵机却要不就是没动静、要不就是产生抖动,或者转到错误的位置上去。这一般是由于没弄明白舵机的核心控制原理,也就是PWM信号的高电平脉宽,不是占空比,直接决定了舵机的转角。
本文系依据舵机内部闭环控制系统的标准技术规范,于信号格式、角度对应关系、接线方法以及代码实现给予完整可验证的操作指南。所有数据皆契合工业级舵机(诸如SG90、MG995等常见型号)的通用标准,你只要依步骤操作,就能在30分钟内使舵机精准转到任一指定角度。
舵机内部有三个核心部件,分别是直流电机,减速齿轮组,角度反馈电位器,还有一块控制电路板,控制电路会实时读取电位器反馈的当前角度,将其与信号线输入的“目标角度”作比较,要是当前角度小于目标角度,电机就正转,大于目标角度电机就反转,相等则停止,这个闭环控制系统能让舵机自行锁定位置,不需要你编写PID。
于是乎,管控舵机唯一所要进行的事项便是,给信号线输送一个具备标准样式的 PWM 信号,于此当中,高电平所占的持续时长,也就是脉宽,向舵机表明“我渴望转向哪一个角度”。
每个标准舵机,均依照下述信号规范,你能够借助示波器或者逻辑分析仪去进行验证。
最为关键的结论是,舵机的角度跟高电平脉宽呈现出线性关系,每增添1°角度,脉宽就会增加(2.5ms 0.5ms)/180°,约等于0.,也就是11.1μs。
例如:
45度,转变为,0.5毫秒加上,45乘以0.0111毫秒,结果约为,1.0毫秒。
一百三十五度,转变为,零点五毫秒,加上,一百三十五乘以,零点零一一一毫秒,约等于,二点零毫秒。
注意,舵机并非依据PWM信号的“占空比”来运行(鉴于其周期固定为20ms,占空比会随着脉宽而产生变化),而是仅仅关注高电平的绝对时间长度。这属于新手极易犯下的错误,倘若你对PWM周期做出更改,即便占空比保持不变,舵机也会转动至不同的位置哦。
请按照以下先后顺序进行连接,连接地线,接着连接电源,连接信号线,借由如此这般的操作流程来防止电流出现冲击状况:
重要警告:
当单个舵机处于堵转状态时,其电流能够达到500mA至1A的范围,而单片机通过USB进行供电一般而言是不足够的情形。要是舵机出现了抖动、无力或者重启的状况,那么就一定要使用独立的5V电源,像是4节AA电池或者稳压模块这类,并且要把电源的GND和单片机的GND进行共地操作。
不准私自把舵机电源直接连接于单片机板载5V的引脚上以驱动多个舵机,倘若如此做事那就会致使板载稳压芯片被烧毁,这是绝对不行的。
![]()
以下这些步骤,适用于所有那些支持PWM输出的开发平台,像、ESP32、STM32等等,我们拿最常见的类平台作为例子,给出能够直接去使用的代码。
步骤1:包含Servo库(该库基于硬件定时器生成精确20ms周期PWM,无需手动计算)
#
Servo ;
步骤2:在setup()中附加舵机对象到引脚,并写入初始角度
void setup() {
.(9); // 信号线接数字引脚9
.write(90); // 转到90度中位
delay(500); // 给舵机足够时间到达位置
}
步骤3:在loop()中实现角度变化
void loop() {
.write(0); // 转到0度
delay(1000);
.write(90);
delay(1000);
.write(180);
delay(1000);
}
要是不想去使用库,那也能够直接对外输出PWM波形,这要求手动来设定周期为 20ms:
int = 9;
void setup() {
(, );
}
void (int angle) {
// 角度限制0~180
angle = (angle, 0, 180);
// 脉宽计算:0.5ms + angle (2.0ms/180°) = 0.5 + angle/90.0 (ms)
float = 0.5 + angle / 90.0; // 单位ms
(, HIGH);
( 1000);
(, LOW);
delay(20 ); // 剩余时间凑足20ms周期
}
若是采用手动延时的方式,那么便会致使程序出现阻塞的情况,另外其精度将受到中断这一因素所影响,在此强烈建议使用Servo库。
现象1:舵机完全不转,或发出滋滋声但不动作
原因:电源功率不足。
要进行验证,需使用万用表去测量舵机红色线跟棕色线之间的电压,要是该电压低于4.5V,那么就表明供电不足。
解决:使用独立5V/2A以上电源,并共地。
现象2:舵机抖动、来回摆动
原由之一:PWM信号处于不稳定状态,(引脚并未输出真正的PWM信号)而且在运用软件延时进行模拟的时候,被中断打断了。
达成解决办法:将其更换为硬件PWM引脚,也就是开发板上标注着~的那些引脚,并且运用Servo库。
原因2:电位器内部脏污(老旧舵机)。
解决:更换舵机。
![]()
现象3:转到指定角度后,用手轻转输出轴能转动(锁不紧)
原因:舵机内部减速齿轮损坏或电机碳刷磨损。
采取的办法是:对舵机进行更换,以此来防止在强行施加外力的情况下,出现超过其极限角度(即0°以及180°)的状况。
现象4:代码中写write(90),但实际转到了80°或100°
由于不同品牌的舵机,其在0.5毫秒至2.5毫秒时间间隔内所对应的角度范围,有可能存在正负5度的偏差。
加以解决:运用.(us)函数,开启手动校准操作,可以先去测量得出,实际0°所对应的微秒数值,此数值通常处于500至600μs这个范围之内,再测点180°所对应的数值,该对应值通常处于2400至2500μs这个范围之中,之后开展线性插值操作。
校准示例:
// 假设实测0°对应550μs,180°对应2450μs
.(9, 550, 2450);
.write(90); // 此时内部按线性映射输出精确脉宽
核心观点重申:
本质上来说,控制舵机就是要给信号线发送周期为20ms的PWM信号,借由改变处于0.5ms至2.5ms范围的高电平脉宽度数,从而线性控制在0°到180°之间的角度,这和控制平常常见的普通直流电机或者步进电机是万万全都不尽然相像的,千万可一定不要弄混淆了,要注意到这一点,千万不可搞混。
立即执行的行动清单:
1. 验证电源:用独立5V/2A电源为舵机供电,并与开发板共地。
2. 正确接线:棕/黑→GND,红→5V,橙/黄→PWM引脚。
3. 为了使用Servo库伟创动力舵机,来进行相关操作,需要先包含头文件# ,接着使用方式关联引脚pin ,运用write方法写入角度angle。
4. 校正舵机,要是角度偏差超出5°,运用()去测量实际0°以及180°所对应的脉宽值,并且进行修正。
5. 防止出现过载情况,不可以让舵机于极限角度上,也就是0°或者是180°的时候,去承受超出其标称扭矩的外力作用,不然的话就会致使齿轮遭到损坏。
依照上述所提及的步骤去进行操作,你能够在十分钟这个时间段之中,令舵机达成稳定状态,并且精确无误地去响应你所下达的每一个角度方面的指令。要是依旧处于异常状况的话,那么要去检查电源以及共地情况——有超过百分之八十的舵机出现失控问题的根源在于供电方面,而并非是代码或者原理理解存在错误。