16| 0
|
[知识点] 舵机的介绍和如何使用Arduino控制舵机的详细概述 |
[backcolor=var(--chat-bg-color,transparent)][color=var(--s-color-text-secondary)][color=var(--color-text-primary)]舵机(Servo)全面介绍与 Arduino 控制详解[color=var(--md-box-samantha-normal-text-color) !important]舵机是一种[color=var(--md-box-samantha-deep-text-color) !important]闭环控制的高精度执行元件,核心优势是能精确控制旋转角度(或连续旋转时的转速 / 方向),广泛应用于机器人关节、无人机云台、RC 模型(车 / 船 / 飞机)、智能小车转向等场景。本文将从舵机的基础原理、分类入手,逐步讲解 Arduino 控制舵机的硬件连接、软件实现及常见问题解决方案。 一、舵机基础介绍1. 舵机的核心结构[color=var(--md-box-samantha-normal-text-color) !important]舵机本质是 “电机 + 减速机构 + 位置反馈 + 控制电路” 的集成体,各组件功能如下:
2. 舵机的工作原理(核心:PWM 信号控制)[color=var(--md-box-samantha-normal-text-color) !important]舵机通过[color=var(--md-box-samantha-deep-text-color) !important]特定频率的 PWM(脉冲宽度调制)信号确定目标角度,标准控制逻辑如下:
[color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]闭环控制过程示例: 当外部发送 “1.5ms 高电平” 的 PWM 信号时,控制电路会:
分类维度 常见类型 特点与应用场景[color=var(--md-box-samantha-deep-text-color) !important]旋转角度 1. 有限角度舵机(90°/180°/270°) 1. 精准控角(如机器人关节、云台)2. 连续旋转舵机(360°) 2. 控速 / 控方向(如小车驱动轮) [color=var(--md-box-samantha-deep-text-color) !important]输出扭矩 1. 微型舵机(1~5kg・cm,如 SG90) 1. 轻负载(小型机器人)2. 标准舵机(5~20kg・cm,如 MG995) 3. 大扭矩舵机(>20kg・cm,如 MG996R) 2. 中负载(RC 模型) 3. 重负载(机械臂) [color=var(--md-box-samantha-deep-text-color) !important]供电电压 1. 5V 舵机(如 SG90) 电压越高,扭矩 / 转速通常越大(需匹配电源)2. 6V 舵机(如 MG995) 3. 7.4~12V 高压舵机 [color=var(--md-box-samantha-deep-text-color) !important]齿轮材质 1. 塑料齿轮(低成本、轻负载) 1. 入门场景(SG90)2. 金属齿轮(高耐磨、高扭矩) 2. 高负载 / 长期使用(MG996R) 4. 舵机的关键参数(选型参考)[color=var(--md-box-samantha-normal-text-color) !important]选型时需关注以下参数,避免 “力不足” 或 “性能过剩”:
1. 硬件准备 组件名称 规格 / 型号 作用说明Arduino 主板 Arduino UNO/Nano 核心控制单元,发送 PWM 信号舵机 SG90(180°,5V,2.5kg·cm) 执行元件,接收信号并旋转到指定角度杜邦线 公对母(3 根) 连接 Arduino 与舵机外接电源(可选) 5V/2A 直流电源(如充电宝) 若舵机负载大(如带机械臂),需外接电源(避免 Arduino USB 供电不足)2. 舵机与 Arduino 的硬件连接[color=var(--md-box-samantha-normal-text-color) !important]首先明确舵机的 3 根线定义(不同品牌颜色可能略有差异,以 datasheet 为准):
舵机引脚(颜色) Arduino UNO 引脚 外接电源(若使用)红色(VCC) 5V 5V 输出棕色(GND) GND GND橙色(Signal) 9(数字引脚) -[color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]关键注意事项:
示例 1:舵机从 0° 转到 180°,再转回 0°(循环)[backcolor=var(--chat-bg-color,#fff)][color=var(--code-header-icon-color)][color=var(--code-header-text-color)]cpp [color=var(--code-header-icon-color)]运行 [color=var(--code-doc_v3)]// 1. 包含Servo库#include <Servo.h>[color=var(--code-doc_v3)]// 2. 创建Servo对象(命名为myServo,可自定义)Servo myServo[color=var(--code-text_v3)];[color=var(--code-doc_v3)]// 3. 定义舵机信号线连接的Arduino引脚const int servoPin [color=var(--code-variable_v3) !important]= [color=var(--code-number_v3)]9[color=var(--code-text_v3)];void [color=var(--code-function_v3)]setup[color=var(--code-text_v3)]([color=var(--code-text_v3)]) [color=var(--code-text_v3)]{ [color=var(--code-doc_v3)]// 4. 将舵机信号线引脚与Servo对象绑定(初始化舵机) myServo[color=var(--code-text_v3)].[color=var(--code-function_v3)]attach[color=var(--code-text_v3)](servoPin[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// (可选)设置舵机初始角度(如90°) myServo[color=var(--code-text_v3)].[color=var(--code-function_v3)]write[color=var(--code-text_v3)]([color=var(--code-number_v3)]90[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-function_v3)]delay[color=var(--code-text_v3)]([color=var(--code-number_v3)]1000[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 等待舵机转到初始位置[color=var(--code-text_v3)]}void [color=var(--code-function_v3)]loop[color=var(--code-text_v3)]([color=var(--code-text_v3)]) [color=var(--code-text_v3)]{ [color=var(--code-doc_v3)]// 5. 控制舵机转到0°(write(角度):角度范围0~180) myServo[color=var(--code-text_v3)].[color=var(--code-function_v3)]write[color=var(--code-text_v3)]([color=var(--code-number_v3)]0[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-function_v3)]delay[color=var(--code-text_v3)]([color=var(--code-number_v3)]1500[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 等待1.5秒,让舵机稳定到位 [color=var(--code-doc_v3)]// 控制舵机转到90° myServo[color=var(--code-text_v3)].[color=var(--code-function_v3)]write[color=var(--code-text_v3)]([color=var(--code-number_v3)]90[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-function_v3)]delay[color=var(--code-text_v3)]([color=var(--code-number_v3)]1500[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 控制舵机转到180° myServo[color=var(--code-text_v3)].[color=var(--code-function_v3)]write[color=var(--code-text_v3)]([color=var(--code-number_v3)]180[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-function_v3)]delay[color=var(--code-text_v3)]([color=var(--code-number_v3)]1500[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 控制舵机转回0° myServo[color=var(--code-text_v3)].[color=var(--code-function_v3)]write[color=var(--code-text_v3)]([color=var(--code-number_v3)]0[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-function_v3)]delay[color=var(--code-text_v3)]([color=var(--code-number_v3)]1500[color=var(--code-text_v3)])[color=var(--code-text_v3)];[color=var(--code-text_v3)]} 示例 2:通过串口控制舵机角度(手动输入角度)[color=var(--md-box-samantha-normal-text-color) !important]通过串口监视器输入 0~180 的数字,舵机实时转到对应角度,适合调试: [backcolor=var(--chat-bg-color,#fff)][color=var(--code-header-icon-color)][color=var(--code-header-text-color)]cpp [color=var(--code-header-icon-color)]运行 #include <Servo.h>Servo myServo[color=var(--code-text_v3)];const int servoPin [color=var(--code-variable_v3) !important]= [color=var(--code-number_v3)]9[color=var(--code-text_v3)];int targetAngle [color=var(--code-variable_v3) !important]= [color=var(--code-number_v3)]90[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 初始角度void [color=var(--code-function_v3)]setup[color=var(--code-text_v3)]([color=var(--code-text_v3)]) [color=var(--code-text_v3)]{ myServo[color=var(--code-text_v3)].[color=var(--code-function_v3)]attach[color=var(--code-text_v3)](servoPin[color=var(--code-text_v3)])[color=var(--code-text_v3)]; myServo[color=var(--code-text_v3)].[color=var(--code-function_v3)]write[color=var(--code-text_v3)](targetAngle[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 初始化串口通信(波特率9600,与串口监视器一致) Serial[color=var(--code-text_v3)].[color=var(--code-function_v3)]begin[color=var(--code-text_v3)]([color=var(--code-number_v3)]9600[color=var(--code-text_v3)])[color=var(--code-text_v3)]; Serial[color=var(--code-text_v3)].[color=var(--code-function_v3)]println[color=var(--code-text_v3)]([color=var(--code-parameter_v3)]"请输入0~180的角度:"[color=var(--code-text_v3)])[color=var(--code-text_v3)];[color=var(--code-text_v3)]}void [color=var(--code-function_v3)]loop[color=var(--code-text_v3)]([color=var(--code-text_v3)]) [color=var(--code-text_v3)]{ [color=var(--code-doc_v3)]// 若串口接收到数据 if [color=var(--code-text_v3)](Serial[color=var(--code-text_v3)].[color=var(--code-function_v3)]available[color=var(--code-text_v3)]([color=var(--code-text_v3)]) [color=var(--code-variable_v3) !important]> [color=var(--code-number_v3)]0[color=var(--code-text_v3)]) [color=var(--code-text_v3)]{ [color=var(--code-doc_v3)]// 读取串口输入的数字(转换为整数) targetAngle [color=var(--code-variable_v3) !important]= Serial[color=var(--code-text_v3)].[color=var(--code-function_v3)]parseInt[color=var(--code-text_v3)]([color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 限制角度在0~180(避免舵机超量程损坏) targetAngle [color=var(--code-variable_v3) !important]= [color=var(--code-function_v3)]constrain[color=var(--code-text_v3)](targetAngle[color=var(--code-text_v3)], [color=var(--code-number_v3)]0[color=var(--code-text_v3)], [color=var(--code-number_v3)]180[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 控制舵机转到目标角度 myServo[color=var(--code-text_v3)].[color=var(--code-function_v3)]write[color=var(--code-text_v3)](targetAngle[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 串口反馈当前角度 Serial[color=var(--code-text_v3)].[color=var(--code-function_v3)]print[color=var(--code-text_v3)]([color=var(--code-parameter_v3)]"当前舵机角度:"[color=var(--code-text_v3)])[color=var(--code-text_v3)]; Serial[color=var(--code-text_v3)].[color=var(--code-function_v3)]println[color=var(--code-text_v3)](targetAngle[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-text_v3)]} [color=var(--code-function_v3)]delay[color=var(--code-text_v3)]([color=var(--code-number_v3)]50[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 小幅延时,稳定串口读取[color=var(--code-text_v3)]} Servo 库核心函数说明: 函数 功能描述Servo 对象名.attach(引脚) 绑定舵机信号线引脚,初始化舵机(必须在 setup () 中调用)Servo 对象名.write(角度) 设置舵机目标角度(0~180°,连续旋转舵机需特殊处理)Servo 对象名.read() 读取舵机当前的角度(返回 0~180 的整数,用于反馈检测)Servo 对象名.detach() 解除舵机与引脚的绑定(释放引脚资源,后续需重新 attach 才能控制)方法 2:手动生成 PWM 信号(进阶,灵活可控)[color=var(--md-box-samantha-normal-text-color) !important]若 Servo 库与其他库(如电机驱动库)存在定时器冲突,或需更精确控制 PWM 参数(如调整周期),可手动通过digitalWrite()和delayMicroseconds()生成 PWM 信号。 [color=var(--md-box-samantha-normal-text-color) !important]核心逻辑:按 “20ms 周期” 循环,在每个周期内输出 “0.5~2.5ms 高电平”(对应 0~180°),其余时间为低电平。 示例:手动控制舵机转到 90°(1.5ms 高电平)[backcolor=var(--chat-bg-color,#fff)][color=var(--code-header-icon-color)][color=var(--code-header-text-color)]cpp [color=var(--code-header-icon-color)]运行 [color=var(--code-doc_v3)]// 定义舵机信号线引脚const int servoPin [color=var(--code-variable_v3) !important]= [color=var(--code-number_v3)]9[color=var(--code-text_v3)];void [color=var(--code-function_v3)]setup[color=var(--code-text_v3)]([color=var(--code-text_v3)]) [color=var(--code-text_v3)]{ [color=var(--code-doc_v3)]// 设置舵机引脚为输出模式 [color=var(--code-function_v3)]pinMode[color=var(--code-text_v3)](servoPin[color=var(--code-text_v3)], OUTPUT[color=var(--code-text_v3)])[color=var(--code-text_v3)];[color=var(--code-text_v3)]}void [color=var(--code-function_v3)]loop[color=var(--code-text_v3)]([color=var(--code-text_v3)]) [color=var(--code-text_v3)]{ [color=var(--code-doc_v3)]// 1. 输出高电平(1.5ms,对应90°) [color=var(--code-function_v3)]digitalWrite[color=var(--code-text_v3)](servoPin[color=var(--code-text_v3)], HIGH[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-function_v3)]delayMicroseconds[color=var(--code-text_v3)]([color=var(--code-number_v3)]1500[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 高电平时间(单位:微秒) [color=var(--code-doc_v3)]// 2. 输出低电平(20ms - 1.5ms = 18.5ms,凑整为18ms,误差可忽略) [color=var(--code-function_v3)]digitalWrite[color=var(--code-text_v3)](servoPin[color=var(--code-text_v3)], LOW[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-function_v3)]delay[color=var(--code-text_v3)]([color=var(--code-number_v3)]18[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 低电平时间(单位:毫秒) [color=var(--code-doc_v3)]// 若需调整角度,修改delayMicroseconds的参数: [color=var(--code-doc_v3)]// 0° → 500us,90°→1500us,180°→2500us[color=var(--code-text_v3)]} [color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]手动控制的优缺点:
[color=var(--code-header-icon-color)]运行 #include <Servo.h>Servo my360Servo[color=var(--code-text_v3)];const int servoPin [color=var(--code-variable_v3) !important]= [color=var(--code-number_v3)]9[color=var(--code-text_v3)];void [color=var(--code-function_v3)]setup[color=var(--code-text_v3)]([color=var(--code-text_v3)]) [color=var(--code-text_v3)]{ my360Servo[color=var(--code-text_v3)].[color=var(--code-function_v3)]attach[color=var(--code-text_v3)](servoPin[color=var(--code-text_v3)])[color=var(--code-text_v3)];[color=var(--code-text_v3)]}void [color=var(--code-function_v3)]loop[color=var(--code-text_v3)]([color=var(--code-text_v3)]) [color=var(--code-text_v3)]{ [color=var(--code-doc_v3)]// 正转(1.0ms高电平,转速较快) my360Servo[color=var(--code-text_v3)].[color=var(--code-function_v3)]writeMicroseconds[color=var(--code-text_v3)]([color=var(--code-number_v3)]1000[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-function_v3)]delay[color=var(--code-text_v3)]([color=var(--code-number_v3)]3000[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 正转3秒 [color=var(--code-doc_v3)]// 停止(1.5ms高电平) my360Servo[color=var(--code-text_v3)].[color=var(--code-function_v3)]writeMicroseconds[color=var(--code-text_v3)]([color=var(--code-number_v3)]1500[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-function_v3)]delay[color=var(--code-text_v3)]([color=var(--code-number_v3)]2000[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 停止2秒 [color=var(--code-doc_v3)]// 反转(2.0ms高电平,转速较快) my360Servo[color=var(--code-text_v3)].[color=var(--code-function_v3)]writeMicroseconds[color=var(--code-text_v3)]([color=var(--code-number_v3)]2000[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-function_v3)]delay[color=var(--code-text_v3)]([color=var(--code-number_v3)]3000[color=var(--code-text_v3)])[color=var(--code-text_v3)]; [color=var(--code-doc_v3)]// 反转3秒[color=var(--code-text_v3)]} [color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]注意:360° 舵机的write()函数无效,需用writeMicroseconds()直接控制高电平时间。 三、常见问题与解决方案 问题现象 可能原因 解决方案舵机无反应,完全不转 1. 接线错误(如信号线接 GND) 1. 重新核对接线(VCC→5V,GND→GND,Signal→数字引脚)2. 供电不足 3. 舵机损坏 2. 外接 5V/2A 电源 3. 更换舵机测试 舵机抖动严重,角度不稳定 1. 电源电压波动(如 USB 供电不足) 1. 外接稳定电源,确保共地2. 信号线受干扰(如与电机线并行) 3. 角度超出舵机量程 2. 用屏蔽线或远离电机线 3. 用constrain()限制角度 0~180 Arduino 重启或报错 1. 舵机启动电流过大,导致 USB 供电过载 1. 舵机独立供电,禁止舵机 VCC 接 Arduino 5V2. 引脚短路(如 Signal 接 VCC) 2. 检查引脚是否短路,更换损坏引脚 舵机角度与指令偏差大 1. 舵机本身精度低(如廉价塑料齿轮舵机) 1. 更换高精度舵机(如金属齿轮舵机)2. 未校准初始角度 2. 手动调整write()参数(如目标 90° 实际 85°,则写 85) 四、总结[color=var(--md-box-samantha-normal-text-color) !important]舵机的核心是 “PWM 信号 + 闭环反馈”,Arduino 控制的关键在于:
[color=var(--md-box-samantha-normal-text-color) !important]通过本文的介绍,你可以实现从 “舵机选型” 到 “Arduino 控制” 的完整流程,后续可结合传感器(如超声波、红外)实现更复杂的功能(如自动跟踪云台、避障机器人关节控制)。 编辑 分享 [color=var(--s-color-text-secondary,rgba(0,0,0,.8))][color=var(--s-color-text-secondary,rgba(0,0,0,.7))]用Arduino控制舵机时,如何计算PWM信号的高电平时间? [color=var(--s-color-text-secondary,rgba(0,0,0,.8))][color=var(--s-color-text-secondary,rgba(0,0,0,.7))]介绍一下Arduino控制舵机的代码示例。 [color=var(--s-color-text-secondary,rgba(0,0,0,.8))][color=var(--s-color-text-secondary,rgba(0,0,0,.7))]推荐一些关于舵机和Arduino控制的教程或学习资源。 |
© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed