控制FPV舵机云台到特定角度

Tutorial: 卓越工程师 Category: 嵌入式 Published: 2026-10-23 11:05:29 Views: 1 Likes: 0 Comments: 0

312.7、控制 FPV 舵机云台到特定角度

#include <Servo.h>                       // 引入 Arduino Servo 库,供两个舵机对象使用

Servo myservo;                           // 创建第一个舵机对象,对应 D9 上的左右旋转轴
Servo myservo2;                          // 创建第二个舵机对象,对应 D10 上的上下俯仰轴

int pos = 0;                             // 保留上一版扫描程序的角度变量;当前活动代码没有使用它

void setup() {                           // 开发板上电或复位后执行一次
  myservo.attach(9);                     // 将左右轴舵机对象关联到数字引脚 D9
  myservo2.attach(10);                   // 将俯仰轴舵机对象关联到数字引脚 D10
}                                        // setup() 初始化结束

void loop() {                            // 主循环会不断重复执行
  myservo2.write(90);                    // 将俯仰轴的目标角度反复设为 90°;这是视频最后保留的测试值
  delay(1000);                           // 每次写入相同目标后等待 1000 ms

  /*                                     下面是被视频用块注释禁用的旧往返扫描代码
  for (pos = 0; pos <= 180; pos += 1) {  // 旧代码:让 pos 从 0 逐次增加到 180
    myservo.write(pos);                  // 旧代码:向左右轴写入递增角度
    myservo2.write(pos);                 // 旧代码:向俯仰轴写入递增角度
    delay(15);                           // 旧代码:每增加 1°等待 15 ms
  }                                      // 旧代码:递增循环结束
  for (pos = 180; pos >= 0; pos -= 1) {  // 旧代码:让 pos 从 180 逐次减小到 0
    myservo.write(pos);                  // 旧代码:向左右轴写入递减角度
    myservo2.write(pos);                 // 旧代码:向俯仰轴写入递减角度
    delay(15);                           // 旧代码:每减小 1°等待 15 ms
  }                                      // 旧代码:递减循环结束
  */                                     // 块注释到此结束,上述旧扫描代码不会编译或运行
}                                        // loop() 本轮结束,随后回到开头继续执行

一、控制舵机转动到指定角度

本节不再让云台连续往返扫描,而是依次给 D9、D10 两个舵机写入 0°、90°或 180°,观察真实姿态,再重新安装舵盘,使“程序角度”和“机构方向”建立明确对应关系。页首代码是视频末段最终可见的草图状态:活动代码只让 myservo2 保持 90°,原扫描程序仍留在文件中但已被 /* ... */ 禁用。

这是一节机械零位与方向校准课,不是自动追光课。视频没有读取光敏传感器,也没有根据光照误差计算目标角度;太阳能板和追光控制只是后续用途。

1.1 上节内容回顾

上一节把下方左右轴信号接到 D9,把上方俯仰轴信号接到 D10。本节最终采用的视频观察方向和角度约定为:

舵机对象与引脚机械作用本节最终约定
myservo / D9左右旋转(pan)左侧约为 0°,中间约为 90°,右侧约为 180°
myservo2 / D10上下俯仰(tilt)课件方向图为 0°朝上、90°水平、180°朝下

视频开头的课件一度把下轴画成“左 180°、右 0°”,讲解也先按这个方向描述;实际上传 180°、0°并观察机构后,教师在草图顶部重新备注为“左边 0 度极限值,右边 180 度极限值”。因此本节应记录实物测试后确定的最终约定,不能同时把两组互相矛盾的左右关系都当成结论。

同样,口述中曾把俯仰轴 0°与“平行”连在一起,但课件方向图和末段实测把 90°描述为“平”的位置。本节按最终演示记录为 0°朝上、90°水平、180°朝下;这只是该套支架在当前观察方向和舵盘齿位下的项目坐标,不是 SG90 的通用空间方向。

所谓“0°、90°、180°”首先是 Servo.write() 的目标值。Arduino 只知道自己最后写了什么,并不知道支架是否真的到位;Servo 官方 API 也明确说明,读取接口返回的是最后的设定值,不是舵机反馈的真实物理方向。安装方向、花键齿位、个体误差、负载和机械限位都会改变最终姿态。

1.2 转动舵机代码

视频先把上一版的两个往返循环包在多行注释中,再在 loop() 顶部逐个写入固定角度。

  • // 是单行注释标记,从它开始直到该行末尾都不参与编译。
  • /* 开始块注释,直到后面的 */ 才结束,可以跨越多行。
  • 被块注释包住的 for、write() 和 delay() 都只是留在编辑器里的旧文本,不会进入可执行逻辑。
  • C/C++ 块注释不能依靠另一组嵌套的 /* ... */ 来分层;修改大段代码时应核对起止位置,避免误把后续业务代码一起禁用。

第 312 节开头显示的旧扫描块,在正向和反向循环中都已经含有 myservo2.write(pos)。这与第 311 节视频最终画面“第二只舵机只在正向循环被写入”不同,说明两节之间发生过未展示的代码修改。页首按第 312 节实际画面保留该块,但不能据此倒推或改写第 311 节源码。

视频各阶段实际测试的活动语句如下:

阶段活动角度语句用途与画面结论
下轴测试 1myservo.write(180)观察 D9 舵机的一端姿态,并调整未锁紧的下部连接
下轴测试 2myservo.write(0)观察另一端,最终确认当前观察方向为左 0°、右 180°
下轴测试 3myservo.write(90)验证下轴是否大致停在左右中间
上轴测试 1myservo2.write(0)找到 D10 舵机的命令零位,并重新安装舵盘校准支架姿态
上轴测试 2myservo2.write(90)校准后验证平台的水平姿态;这是视频最后可见并保留的代码
上轴 180°视频只口述“180 就往下”没有看到把活动语句改成 180 并重新上传,不能写成已完成的烧录测试

delay(1000) 只让 loop() 每隔约 1 秒再次写入同一个目标,不表示“舵机一定用 1 秒转完”,也不是保持角度所必需。Servo 库会在后台继续输出最近一次设定所对应的控制脉冲;即使程序正停在 delay() 中,舵机信号也不会因此消失。

最终草图虽然还执行 myservo.attach(9),但活动循环没有再调用 myservo.write(...)。AVR 版 Servo 库在对象创建时保存默认的 1500 µs 脉宽,attach() 后即按该默认值输出,所以重新上传或复位后,D9 舵机不会“记住上一份程序写过的 90°”;它只是接收到接近中位的默认脉宽。默认 1500 µs 与 write(90) 的内部映射也不必恰好完全相同,更不能据此认定下轴已经精确校准。

1.3 控制舵机转动示例

1.3.1 校准下方左右轴(D9)

视频中的操作顺序是:

  1. 保留 myservo.attach(9),把旧往返扫描整块注释掉。
  2. 写入 myservo.write(180) 和 delay(1000),选择当时的串口并上传。
  3. 观察 180°命令下的下轴位置。由于底部连接此前没有完全锁紧,视频转动并放置底部机构,使它与预期的一端方向对齐。
  4. 把目标值改为 0°并再次上传,观察机构转到另一端。
  5. 依据实物方向,最终在代码顶部备注“左 0°、右 180°”。
  6. 再写入 90°并上传,确认下轴大致位于左右行程的中间。

原始笔记中的“控制九号银角”是“控制 9 号引脚舵机”的识别错误。D9 是信号脚编号;180、0、90 是写给 myservo 的目标角度值,两者不能混为一谈。

1.3.2 这里校准的究竟是什么

舵机输出轴和舵盘通过细小花键啮合。把舵盘拔起、旋转若干齿再压回去,相当于改变“程序角度”与“支架机械方向”之间的固定偏移:

程序写入角度 → Servo 库产生脉冲 → 舵机输出轴到达目标附近
                                      ↓
                           舵盘安装齿位决定支架朝向
                                      ↓
                         云台最终呈现左/中/右或上/平/下

这种操作不会改变 Servo 库的 0~180 映射,也不会改变舵机内部电位器的电气零点;它只是重新选择舵盘装在输出轴上的机械齿位。花键只能按离散齿距调整,因此不一定能让平台达到完全精确的几何水平,后续还可能需要在软件中使用安全的角度偏移或范围限制,但本节没有展示相应代码,不能在页首源码中擅自补写。

1.4 内容修改

本节最终确定下轴以 D9 控制,并在当前观察方向采用“左 0°、中 90°、右 180°”的项目约定。0°和 180°本身并不天然代表左或右:把舵机翻转安装、把移动件与固定件互换,或者从机构另一面观察,肉眼方向都可能反过来。

教师说“反过来也可以”,应理解为项目可以重新定义方向或在后续控制逻辑中做反向映射,而不是同一套机械安装下 write(0) 和 write(180) 会任意互换。为了让传感器误差计算和后续调试一致,方向一旦确定,就应在整个项目中保持同一坐标约定。

另外,0°和 180°是 Servo 库允许写入的端点命令,不等于云台一定拥有完整、安全的 180°机械行程。Arduino 官方文档提醒,驱动舵机越过真实端点会出现持续低吼/嗡鸣和高电流状态。若支架在到达命令端点前已经碰撞,应立即断电,把项目可用范围收窄;不能为了让标注“对上”而让舵机长期顶住机械限位。

1.5 控制舵机转动示例

1.5.1 校准上方俯仰轴(D10)

视频先把活动语句改为 myservo2.write(0) 并上传,观察上方平台在命令零位时的实际姿态。随后用一次“错误位置”演示说明如何重新安装舵盘,使零位与项目需要的机械方向一致。结合画面和必要的安全修正,可靠步骤应理解为:

  1. 在平台无太阳能板负载、周围无遮挡时写入待校准角度,并让舵机到达该目标。
  2. 断开舵机电源;视频也明确提醒“电要下掉”。不能带电强扭输出轴。
  3. 用合适的十字螺丝刀卸下舵盘中心的短螺钉,收好螺钉。
  4. 让舵盘完全脱离舵机输出轴花键。需要调整的是舵盘/支架相对齿位,不是用手硬拧舵机轴和内部齿轮。
  5. 在输出轴保持已知命令位置的前提下,把平台移动到希望定义的机械姿态,再把舵盘以最接近的齿位压回花键。
  6. 用原来的匹配短螺钉固定舵盘;不要用过长安装螺钉替代,以免拧入过深损坏舵机。
  7. 手和工具退出运动范围后重新上电,先验证该校准角度,再小范围测试附近角度。

视频末段把活动语句改为 myservo2.write(90),上传后把此姿态描述为“平”。随后口头说明 180°应继续向下,但没有显示改成 180°并重新烧录,因此验收结论只能写到 90°实测。若要测试 180°,仍须先确认平台、支架、舵机线和未来太阳能板都不会在途中碰撞或拉紧。

1.5.2 固定与后续应用
  • 舵盘必须靠正确花键啮合和中心短螺钉固定,不能用胶水代替中心螺钉,也不能让胶进入输出轴或转动关节。
  • 教师所说的打胶或拧螺丝,是在方向校准完成后把云台底座固定到项目结构上的可选做法。固定前要再次确认底座哪一侧应保持不动。
  • 使用热熔胶枪时应断电,避开舵机外壳接缝、导线、连接器和活动轴;热胶也不适合承担长期反复摆动的精密定位。
  • 安装太阳能板后负载和重心都会变化。空载时不碰撞、不抖动,并不能证明负载后仍安全;应重新检查供电压降、保持力、线缆余量和角度范围。
  • 真正追光还需要两个方向的光照误差输入和限位逻辑。本节只建立角度坐标与机械姿态的对应关系。

1.6 校准完成后的验收

检查项合格表现异常时处理
下轴中位写入 90°后大致位于左右行程中间断电后重新选择舵盘齿位,不带电硬扭
上轴水平写入 90°后平台符合本项目定义的水平姿态重新校准舵盘;小误差留给后续软件偏移处理
两端安全接近项目允许端点时无碰撞、无持续嗡鸣、线缆不绷紧立即断电并缩小可用角度范围
紧固可靠舵盘中心短螺钉和底座紧固件到位,机构无明显空转使用匹配紧固件重装,不用胶堵住转轴
上电行为机构只小幅回到目标,没有突然撞击支架检查初始目标、舵盘齿位和启动时的默认位置
负载复测加装太阳能板后仍能稳定到位,UNO 不复位检查重心、供电能力、共地和机械阻力

核对依据

  • 本地 videos/312.7、控制FPV舵机云台到特定角度.mp4:逐段核对旧扫描代码的块注释、D9 的 180°/0°/90°测试、最终“左 0°/右 180°”备注、D10 的 0°校准、舵盘拆装以及末段 myservo2.write(90);确认视频没有显示把俯仰轴改为 180°并再次上传。
  • 本地 transcripts/312.7、控制FPV舵机云台到特定角度.txt 与 .srt:核对讲解顺序、D9/D10 分工、1 秒延时、断电提醒、平台姿态和后续安装太阳能板的用途;结合画面纠正“九号银角”“干信号”等识别错误及前后方向冲突。
  • Arduino Servo 库官方 API:核对 attach()、write()、设定值与真实物理方向的区别,以及超过真实机械端点会形成高电流状态的警告。
  • Arduino Servo 库头文件与AVR 实现:核对 Servo 对象保存最近脉宽并在后台持续产生脉冲、默认 1500 µs 初值,以及 delay(1000) 不会停止舵机控制信号。
  • Adafruit《Mini Pan-Tilt Kit Assembly》官方装配说明:其双轴支架结构与本课程相近,用于交叉核对舵盘齿位校准、中心短螺钉、俯仰行程检查和“行程不合适时脱开舵盘后旋转重装”的机械处理原则;课程套件未标明品牌,本文不把它认定为同一产品。