舵机控制——让 Arduino 精确转动角度
前面我们学了 PWM 输出,用 analogWrite() 控制 LED 亮度和蜂鸣器音调。但你可能好奇:PWM 除了调亮度、调音调,还能干什么?
答案是:精确控制角度。
今天这篇,我们要用 PWM 信号驱动舵机(Servo),让它精确转到任意角度。舵机是机器人、机械臂、云台的核心执行器,掌握了它,你就打开了"让东西动起来"的大门。
学完这篇,你会完成两个项目:
- 旋钮控制舵机:转动电位器,舵机角度实时跟随
- 自动扫描舵机:舵机从 0° 到 180° 来回扫描,像雷达一样
一、舵机是什么?
舵机(Servo Motor)是一种可以精确控制转动角度的电机。和普通电机不同,舵机不是"一直转圈",而是转到指定角度就停住。
常见舵机(如 SG90、MG90S)的角度范围是 0° ~ 180°。
舵机的三根线
| 线色 | 接到 |
|---|---|
| 棕色/黑色 | GND |
| 红色 | 5V(注意:大扭矩舵机可能需要外部供电) |
| 橙色/黄色 | 信号线 → Arduino 的数字引脚 |
⚠️ SG90 这种小舵机可以直接用 Arduino 的 5V 供电。但如果用 MG996R 等大舵机,电流需求较大,必须用外部电源,否则会烧坏 Arduino。
二、舵机的工作原理——PWM 控制角度
舵机内部有一个直流电机 + 电位器 + 控制电路。它通过接收 PWM 信号来确定目标角度:
- 信号周期:20ms(即频率 50Hz)
- 高电平脉宽:0.5ms ~ 2.5ms,对应 0° ~ 180°
| 高电平脉宽 | 对应角度 |
|---|---|
| 0.5ms | 0° |
| 1.0ms | 45° |
| 1.5ms | 90°(中间位置) |
| 2.0ms | 135° |
| 2.5ms | 180° |
Arduino 的 Servo 库会自动帮你生成这些精确的 PWM 信号,你只需要告诉它"转到多少度"就行。
三、硬件清单
| 元件 | 数量 | 作用 |
|---|---|---|
| Arduino Uno | 1块 | 主控板 |
| 面包板 | 1块 | 搭建电路 |
| SG90 舵机 | 1个 | 角度控制执行器 |
| 电位器(10kΩ) | 1个 | 模拟输入,控制角度 |
| 杜邦线 | 若干 | 连接元件 |
四、电路接线
舵机接线
舵机有三根线(棕/红/橙):
- 棕色线 → 接 GND
- 红色线 → 接 5V
- 橙色线(信号) → 接 Arduino 的 D9
电位器接线
- 左引脚 → 接 GND
- 中间引脚 → 接 Arduino 的 A0
- 右引脚 → 接 5V
五、实验一:旋钮控制舵机
转动电位器,舵机角度实时跟随变化。
#include <Servo.h>
Servo myServo; // 创建舵机对象
const int potPin = A0; // 电位器接 A0
const int servoPin = 9; // 舵机信号线接 D9
void setup() {
Serial.begin(9600);
myServo.attach(servoPin); // 绑定舵机引脚
Serial.println("=== 旋钮控制舵机 ===");
}
void loop() {
// 读取电位器值(0~1023)
int potValue = analogRead(potPin);
// 映射到舵机角度(0~180)
int angle = map(potValue, 0, 1023, 0, 180);
// 控制舵机转到指定角度
myServo.write(angle);
// 串口打印调试信息
Serial.print("电位器: ");
Serial.print(potValue);
Serial.print(" → 角度: ");
Serial.print(angle);
Serial.println("°");
delay(20);
}
核心函数
Servo.attach(pin):将舵机绑定到指定引脚Servo.write(angle):让舵机转到指定角度(0~180)map():把电位器的 0~1023 映射到舵机的 0~180
转动电位器,你会看到舵机的摇臂平滑地跟着转动,非常直观。
六、实验二:雷达扫描模式
舵机自动从 0° 扫到 180°,再扫回来,像雷达天线一样来回扫描。
#include <Servo.h>
Servo myServo;
const int servoPin = 9;
void setup() {
Serial.begin(9600);
myServo.attach(servoPin);
Serial.println("=== 雷达扫描模式 ===");
}
void loop() {
// 正向扫描:0° → 180°
Serial.println("--- 正向扫描 ---");
for (int angle = 0; angle <= 180; angle += 1) {
myServo.write(angle);
Serial.print("角度: ");
Serial.print(angle);
Serial.println("°");
delay(15); // 每步延迟 15ms,控制扫描速度
}
delay(500); // 到达 180° 后暂停 0.5 秒
// 反向扫描:180° → 0°
Serial.println("--- 反向扫描 ---");
for (int angle = 180; angle >= 0; angle -= 1) {
myServo.write(angle);
Serial.print("角度: ");
Serial.print(angle);
Serial.println("°");
delay(15);
}
delay(500); // 到达 0° 后暂停 0.5 秒
}
效果
舵机摇臂从最左扫到最右,停顿半秒,再扫回来,循环往复。配合超声波传感器,就是一台简易的"雷达扫描仪"。
七、进阶:用串口直接输入角度
除了电位器,你还可以通过串口监视器直接输入角度,让舵机转到指定位置。
#include <Servo.h>
Servo myServo;
const int servoPin = 9;
void setup() {
Serial.begin(9600);
myServo.attach(servoPin);
myServo.write(90); // 初始位置:中间
Serial.println("=== 串口控制舵机 ===");
Serial.println("输入角度 (0~180),按回车发送:");
}
void loop() {
if (Serial.available() > 0) {
int angle = Serial.parseInt(); // 读取串口输入的整数
// 限制角度范围
if (angle >= 0 && angle <= 180) {
myServo.write(angle);
Serial.print("舵机转到: ");
Serial.print(angle);
Serial.println("°");
} else {
Serial.println("⚠️ 角度超出范围!请输入 0~180 之间的值。");
}
}
}
使用方法
- 上传代码,打开串口监视器(波特率 9600)
- 在输入框中输入一个数字(如
45),按回车 - 舵机会立即转到 45° 位置
八、深入理解:舵机的"抖动"问题
新手常遇到的一个问题:舵机到位后轻微抖动。原因有几个:
- 电源不稳定:舵机启动瞬间电流较大,拉低了 5V 电压。解决方案:给舵机单独供电,并共地。
- 信号线干扰:杜邦线太长或接触不良。解决方案:缩短信号线,确保连接牢固。
- 更新频率过高:
Servo.write()被过于频繁地调用。解决方案:只在角度变化时才调用write()。
优化技巧:只在角度变化时更新
int lastAngle = -1; // 记录上次的角度
void loop() {
int angle = map(analogRead(potPin), 0, 1023, 0, 180);
if (angle != lastAngle) { // 角度变化了才更新
myServo.write(angle);
lastAngle = angle;
}
}
九、舵机的应用场景
掌握了舵机控制,你可以做很多有趣的项目:
- 机械臂:用 3~6 个舵机搭建多自由度机械臂
- 云台:两个舵机组合,实现水平 + 垂直方向的角度控制
- 智能小车转向:用舵机控制前轮转向角度
- 雷达扫描:舵机 + 超声波传感器,扫描前方障碍物
- 开关控制:用舵机推拉物理开关(如灯开关、门把手)
十、本篇小结
回顾一下今天学到的核心知识:
- 舵机原理:通过 PWM 脉宽(0.5ms~2.5ms)控制 0°~180° 角度
Servo库:attach()绑定引脚,write()设置角度- 旋钮控制舵机:
analogRead()+map()+Servo.write()的组合 - 雷达扫描:用
for循环实现角度递增/递减 - 串口控制:
Serial.parseInt()读取用户输入的角度 - 抖动排查:电源、信号线、更新频率三个方向
舵机是"让 Arduino 产生物理运动"的第一步。下一篇,我们学习超声波传感器——让 Arduino 能够"看见"前方的障碍物,测量距离,为做避障小车打基础。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)