Skip to content

Arduino - 舵机

一个业余舵机是一个紧凑的设备,包含直流电机、齿轮、位置反馈电位器和控制电子设备。它允许您高精度地控制其输出轴的角位置。舵机是机器人技术、无线电遥控模型和电动玩具中的基本组件。

舵机主要有两种类型:标准(位置)舵机,它们在有限范围内旋转(通常是 0-180 度);以及连续旋转舵机,它们被修改为像普通电机一样连续旋转,但易于进行速度和方向控制。

舵机工作原理:脉冲宽度调制 (PWM)

Section titled “舵机工作原理:脉冲宽度调制 (PWM)”

舵机的位置不是通过稳定电压设定的,而是通过发送到其信号线上的重复电脉冲的持续时间(宽度)来设定的。这种控制方法称为脉冲宽度调制(PWM)。舵机期望每 20 毫秒接收一个脉冲(频率为 50 Hz)。

  • 持续约 **1 毫秒(1000 µs)**的脉冲通常对应于 0 度位置。
  • 持续约 **1.5 毫秒(1500 µs)**的脉冲对应于 90 度(中间)位置。
  • 持续约 **2 毫秒(2000 µs)**的脉冲对应于 180 度位置。

Arduino 的 Servo.h 库会为您处理这些精确脉冲的生成,使控制变得非常简单。

  • 1 × Arduino 开发板(例如 UNO、Nano、MKR)
  • 1 × 标准业余舵机(例如 SG90、MG996R)
  • 1 × 10kΩ 电位器
  • 跳线
  • **(推荐)**一个外部 5V-6V 电源(例如,一个 4 节 AA 电池组或一个 5V/2A 壁式适配器)

⚠️ 关于电源的重要说明: 舵机可能会消耗大量电流,尤其是在负载下。直接从 Arduino 的 5V 引脚为舵机供电可能会导致 Arduino 重置或变得不稳定。虽然对于单个、小型舵机(如空载的 SG90)可能有效,但最佳实践是从单独的外部电源为舵机供电。

  • 舵机电源:将舵机的**红色线(+V)连接到外部 5V/6V 电源的正极(+)**端子。
  • 舵机接地:将舵机的**棕色/黑色线(GND)连接到外部电源的负极(-)**端子。
  • 共地:将外部电源的负极(-)端子也连接到 Arduino 上的 GND 引脚。这对于信号被正确解释至关重要。
  • 舵机信号:将舵机的**橙色/黄色线(信号)**连接到 Arduino 上具有 PWM 功能的引脚(例如,引脚 9,标有 ~)。
  • 电位器:将其中间引脚连接到 Arduino A0。将两个外侧引脚连接到 Arduino 的 5V 和 GND 引脚。

Servo 库将控制简化为几个关键函数:

  • #include <Servo.h>:将库包含到您的草图中。
  • Servo myServo;:创建一个舵机对象。
  • myServo.attach(pin):将舵机对象与 Arduino 上的物理引脚关联。这必须是一个 PWM 引脚。
  • myServo.write(angle):命令舵机移动到特定角度,从 0 到 180。
  • myServo.writeMicroseconds(us):通过直接以微秒为单位指定脉冲宽度(例如,1000 到 2000)来提供更精细的控制。
  • myServo.detach():停止向舵机发送脉冲,使其可以自由移动并节省电源。
/*
使用电位器控制舵机 - 现代化
此草图读取电位器的模拟值并用它来控制舵机的位置。
- 电位器连接到引脚 A0
- 舵机信号线连接到引脚 9
- 舵机由外部 5V 电源供电,并与 Arduino 共地
*/
#include <Servo.h>
// 创建一个舵机对象来控制舵机
Servo myServo;
// 定义引脚常量以提高可读性
const int potPin = A0;
const int servoPin = 9;
void setup() {
// 将引脚 9 上的舵机连接到舵机对象
myServo.attach(servoPin);
Serial.begin(9600);
Serial.println("舵机控制已初始化。请转动电位器。");
}
void loop() {
// 读取电位器的原始值(0 到 1023)
int potValue = analogRead(potPin);
// 将电位器的范围(0-1023)缩放到舵机的角度范围(0-180)
int servoAngle = map(potValue, 0, 1023, 0, 180);
// 根据缩放值设置舵机位置
myServo.write(servoAngle);
// 将角度打印到串口监视器进行调试
Serial.print("Potentiometer Value: ");
Serial.print(potValue);
Serial.print(", Servo Angle: ");
Serial.println(servoAngle);
// 短暂延迟以允许舵机到达其位置
delay(15);
}
  • 舵机抽搐、抖动或重置 Arduino:这几乎总是电源问题。舵机正在从 Arduino 的稳压器汲取过多电流。请使用合适的外部电源。
  • 舵机无法转动完整的 180 度:Servo 库中的默认脉冲宽度范围(通常为 544µs 到 2400µs)可能与您特定舵机的物理限制不匹配。您可以通过使用 myServo.writeMicroseconds() 来校准它,以找到对应您舵机 0 度和 180 度的精确脉冲宽度。
  • analogWrite() 在某些引脚上停止工作:在某些 Arduino 开发板(如 UNO)上,连接舵机会禁用引脚 9 和 10 上的 PWM(analogWrite())。这是由于内部定时器冲突造成的。在设计涉及多个舵机和 PWM 输出的项目时请注意这一点。

既然您现在可以控制一个舵机,下一步就是控制多个舵机。一个很棒的小项目是构建一个简单的 2 轴或 3 轴机械臂。您可以为每个舵机(例如,底部、肩部、肘部)使用一个电位器来独立控制每个关节。这会教您如何管理多个舵机,并且是对机器人技术的一个极好的介绍。