舵机与电机
让作品动起来:精确控制舵机角度、用 L298N 驱动直流电机、认识步进电机,以及供电避坑。
让作品动起来:精确控制舵机角度、用 L298N 驱动直流电机、认识步进电机,以及供电避坑。
servo.attach(pin) 绑定引脚、servo.write(角度) 设角度。它在后台生成 50Hz(20ms 周期)的位置脉冲,你只管写角度。注意:用了 Servo 库会占用某些定时器,可能影响部分引脚的 analogWrite。write(角度) 帮你换算,也可用 writeMicroseconds() 直接给微秒做微调。analogWrite 输出到驱动模块的使能脚(ENA),占空比越大电机平均电压越高、转得越快。这就是"用 PWM 调速"——比串电阻降压高效得多(几乎不发热)。SG90 舵机三线:红=VCC(5V)、棕/黑=GND、橙/黄=信号(接 D9)。单个小舵机可短暂由 Uno 5V 供电,多个或大舵机务必外部 5V 供电。
#include <Servo.h> Servo myServo; // 创建舵机对象 void setup() { myServo.attach(9); // 信号线接 D9 } void loop() { // 0° → 180° 缓慢扫过 for (int angle = 0; angle <= 180; angle++) { myServo.write(angle); // 设角度 delay(15); // 给舵机转动时间 } // 180° → 0° 扫回 for (int angle = 180; angle >= 0; angle--) { myServo.write(angle); delay(15); } }
结合第 4 章:读 A0 电位器 0~1023,用 map(v, 0,1023, 0,180) 映射成角度,再 myServo.write(angle),就做出了旋钮控制的云台。这是理解"输入→映射→输出"链路的好练习。
直流电机必须用驱动模块。L298N 接线:电机电源(如 6~12V 电池)接 L298N 的 VCC/GND,Arduino 的 IN1/IN2/ENA 接控制信号,OUT1/OUT2 接电机。
// L298N 控制直流电机:正转、反转、调速 const int ENA = 5; // PWM 调速(~ 引脚) const int IN1 = 6; const int IN2 = 7; void setup() { pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); } // 正转,speed 0~255 void forward(int speed) { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); analogWrite(ENA, speed); } // 反转 void backward(int speed) { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); analogWrite(ENA, speed); } void stopMotor() { analogWrite(ENA, 0); } void loop() { forward(200); delay(2000); // 正转 2 秒 stopMotor(); delay(1000); backward(150); delay(2000); // 反转 2 秒(慢一点) stopMotor(); delay(1000); }
① 电机绝不能直接接 Arduino 引脚(电流会烧引脚甚至烧板);② 电机必须用独立外部电源(电池/适配器)供电,别指望 USB 那点电流;③ 外部电源 GND 与 Arduino GND 必须相连(共地),否则控制信号无效。电机启停的反向电动势还建议加续流二极管保护。
步进电机能精确定位。28BYJ-48 配套 ULN2003 驱动板,用 Arduino 自带 Stepper 库:
#include <Stepper.h> // 28BYJ-48 内部 32 步,减速后约 2048 步/圈 const int STEPS_PER_REV = 2048; // ULN2003 的 IN1~IN4 接 D8,D10,D9,D11(注意顺序 1-3-2-4) Stepper stepper(STEPS_PER_REV, 8, 10, 9, 11); void setup() { stepper.setSpeed(10); // 10 RPM } void loop() { stepper.step(STEPS_PER_REV); // 顺时针转一整圈 delay(1000); stepper.step(-STEPS_PER_REV); // 逆时针转一整圈 delay(1000); }
自带 Stepper 库的 step() 在转动期间会卡住程序。若需边转边做别的事、或要加减速控制,改用社区的 AccelStepper 库(非阻塞、支持加速度)。步进电机同样需要外部供电+共地。
| 类型 | 控制量 | 能否精确定位 | 驱动 | 典型用途 |
|---|---|---|---|---|
| 舵机 | 角度(0~180°) | 能(有反馈) | Servo 库直连 | 机械臂、云台 |
| 直流电机 | 转速+方向 | 不能(开环) | L298N/H桥 | 小车轮子、风扇 |
| 步进电机 | 步数(角度) | 能(开环计步) | ULN2003/A4988 | 3D打印、CNC |
三类执行器让作品动起来。舵机能转到并保持指定角度,靠 20ms 周期的 PWM 脉宽决定角度(0.5/1.5/2.5ms 约对应 0/90/180°),用官方 Servo 库 attach(pin)+write(角度) 即可,库在后台维持脉冲流;结合电位器+map 可做旋钮云台。直流电机电流大、通电即转,必须经 L298N 这类 H 桥驱动模块:IN1/IN2 控正反转、ENA 接 PWM 调速。步进电机(28BYJ-48+ULN2003)每脉冲精确转一步、可开环定位,用 Stepper 库(阻塞)或 AccelStepper 库(非阻塞带加速)。贯穿全章的三条铁律:电机绝不直连引脚、必须用独立外部电源、外部电源 GND 与 Arduino GND 必须共地——共地缺失是电机项目最常见的失败原因。PWM 调速(调使能脚占空比)比串电阻降压高效且不发热。