
ArduPilot 中使用 SmartAudio Lua 脚本通过 RC 遥控器控制 VTX 图传功率【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilotSmartAudio 是 FPV 图传VTX厂商广泛采用的一种串行控制协议。ArduPilot 官方在 libraries/AP_Scripting/applets/SmartAudio.md 中提供了一款开箱即用的 Lua 脚本让飞手无需地面站即可通过 RC 遥控器通道在飞行中切换 SmartAudio 2.0 图传的发射功率Pit Mode / 低 / 中 / 高 / 最大五档并可在系统上电时自动设定初始功率。阅读完本文你将掌握该脚本的接线方式、飞控端串口与 RC 通道的完整参数配置、功率档位与 PWM 的映射关系以及脚本内部的实现原理与协议细节。脚本能做什么SmartAudio Lua 脚本SmartAudio.lua实现了两大功能RC 实时调功率通过一个 RC 通道RCx_OPTION设为 300的摇杆位置或拨杆开关实时把 VTX 切换到 Pit Mode、LOW、MED、HIGH、MAX 五档功率之一。功率只在该通道的取值跨越到新档位区间时才会被激活。开机设定初始功率通过参数SCR_USER1设定上电后的初始功率可以选择保持原样-1或直接进入上述五档之一。脚本通过 UART 串口以 SmartAudio 2.0 协议与 VTX 通信同时通过 GCS地面站文本消息确认开机功率值与后续每一次功率变更方便调试与确认。从源码结构看脚本依赖 ArduPilot 的 Lua 脚本绑定param、rc、serial、gcs接口因此需要飞行控制器固件启用 Lua 脚本功能通常要求 ArduPilot 4.1 或更新版本并具备足够 Flash 空间运行时它会注册到脚本调度器循环执行。硬件连接与串口配置接线在飞控上找一个空闲的 UART 串口。将该串口的TX引脚接到 VTX 的SmartAudio输入引脚。该 UART 在飞控参数中以SERIALx_PROTOCOL 28脚本串口启用SERIALx_OPTIONS 4半双工。文档明确指出SmartAudio 信号是半双工串行通信因此SERIALx_OPTIONS必须设为 4半双工模式否则 VTX 返回的状态信息将无法正常接收。脚本源码中对应的初始化代码为port:begin(4800)SmartAudio.lua即以 4800 波特率打开该串口——这正是 SmartAudio 协议的标准波特率。相关参数汇总参数取值作用SERIALx_PROTOCOL28将该串口指定为 Lua 脚本串口SERIALx_OPTIONS4半双工模式SmartAudio 通信必需RCx_OPTION300指定用于切换功率的 RC 通道对应 Scripting1 辅助功能SCR_USER1-1 / 0 / 1 / 2 / 3 / 4上电初始功率-1 保持原样0Pit Mode1LOW2MED3HIGH4MAXRC 通道辅助功能 300 的官方定义为300:Scripting1参见 RC_Channel.cpp 中的取值注释脚本通过rc:find_channel_for_option(300)SmartAudio.lua来查找该通道。SCR_USER1是脚本通用用户参数之一脚本通过param:get(SCR_USER1)SmartAudio.lua读取。功率档位与 PWM 映射脚本把 RC 通道的归一化输入norm_input()范围为 -1 到 1映射为 1 到 5 的档位整数function get_power() input scripting_rc:norm_input() -- - 1 to 1 input (input 1) * 2 -- 0 to 4 return math.floor(input0.5) 1 -- integer 1 to 5 endSmartAudio.lua即以通道 PWM 的中间值 1500 为中心将全量程线性切分成 5 等份。文档给出了RCx_MIN 1000、RCx_MAX 2000时的完整映射表PWM 范围功率档位1000 – 1124Pit Mode1125 – 1374LOW1375 – 1624MED1625 – 1874HIGH1875 – 2000MAX注意实际输出的物理功率取决于所使用图传的具体型号与固件——同一档位在不同 VTX 上可能对应不同的毫瓦mW功率值Pit Mode坑道模式/低功率维修模式亦然。若RCx_MIN/RCx_MAX不是 1000/2000档位边界会按比例线性平移。档位切换的内部流程脚本的主循环非常简洁由调度器每 500ms 调用一次function update() setPower(get_power()) return update, 500 endSmartAudio.luasetPower(power)会先与内部保存的_current_power比较只有档位真正变化时才发送串口指令并上报 GCS从而避免反复发送相同指令function setPower(power) if power _current_power then return end updateSerial(power_commands[power][1]) gcs:send_text(4, power_commands[power][2]) _current_power power endSmartAudio.lua发送的指令是预置的 SmartAudio 2.0 十六进制命令帧保存在power_commands表中power_commands[1] { {0x00,0x00,0xAA,0x55,0x0B,0x01,0x01,0xF8,0x00}, VTX Pit Mode } power_commands[2] { {0x00,0x00,0xAA,0x55,0x05,0x01,0x00,0x6B,0x00}, VTX PWR LOW } power_commands[3] { {0x00,0x00,0xAA,0x55,0x05,0x01,0x01,0xBE,0x00}, VTX PWR MED } power_commands[4] { {0x00,0x00,0xAA,0x55,0x05,0x01,0x02,0x14,0x00}, VTX PWR HIGH } power_commands[5] { {0x00,0x00,0xAA,0x55,0x05,0x01,0x03,0xC1,0x00}, VTX PWR MAX }SmartAudio.lua这些帧符合 SmartAudio 帧结构同步字节0xAA 头字节0x55随后是命令字与载荷。对照 ArduPilot 原生 SmartAudio 驱动 AP_SmartAudio.h 中的协议定义可以看到0x05是SMARTAUDIO_CMD_SET_POWER设置功率0x0B是SMARTAUDIO_CMD_SET_MODE设置模式用于 Pit Mode同步字节与头字节的宏定义为SMARTAUDIO_SYNC_BYTE 0xAA与SMARTAUDIO_HEADER_BYTE 0x55AP_SmartAudio.h脚本与原生驱动对协议的理解完全一致。上电初始功率SCR_USER1脚本初始化init()时读取SCR_USER1并据此设置开机功率if startup_pwr then -- make sure we found the param if startup_pwr 0 and startup_pwr 5 then setPower(math.floor(startup_pwr) 1) -- set the current power local to that requested by the rc in -- this prevents instantly changing the power from the startup value _current_power get_power() end endSmartAudio.lua要点解读SCR_USER1 -1默认保持不变即不主动发送任何功率指令VTX 维持断电前自身记忆的功率。SCR_USER1 0到4分别对应 Pit Mode、LOW、MED、HIGH、MAX上电后立即设置。设置完初始功率后脚本把_current_power强制赋值为当前 RC 通道所代表的档位。这是一个精心设计的细节防止 RC 通道当前停留的档位与开机功率不一致时脚本在第一次update()中立刻把功率改回去。换句话说开机初始功率只生效一次随后的功率完全由 RC 通道决定。脚本初始化前会延迟 2 秒return init, 2000见 SmartAudio.lua给 RC 接收机上电稳定留出时间也让错误消息更容易被看到。初始化自检与故障排查init()中内置了两项自检失败时会在 GCS 显示明确提示if not port then gcs:send_text(0, SmartAudio: No Scripting Serial Port) return end if not scripting_rc then gcs:send_text(0, SmartAudio: No RC option for scripting) return endSmartAudio.lua即找不到脚本串口或找不到设置为 300 的 RC 通道时脚本都会在 GCS 打印SmartAudio: ...错误消息并中止初始化。正常工作时上电后与每次档位变化GCS 都会收到VTX Pit Mode、VTX PWR LOW、VTX PWR MED、VTX PWR HIGH、VTX PWR MAX之类的确认文本通过gcs:send_text发送。常见排查思路确认固件版本与板卡支持 Lua 脚本ArduPilot 4.1 及以后且SCR_ENABLE相关脚本功能已开启、脚本文件已上传到飞控 SD 卡的APM/scripts目录。确认SERIALx_PROTOCOL 28、SERIALx_OPTIONS 4且 UART 的 TX 确实接到了 VTX 的 SmartAudio 引脚。确认RCx_OPTION 300并在SCR_USER1中设置了期望的开机功率。上电后观察 GCS 是否出现SmartAudio:开头的错误消息或功率确认消息。关于 Pit Mode 的兼容性说明文档特别提醒了一个重要兼容性差异部分SmartAudio 2.0图传无法通过远程指令进入 Pit Mode但可以通过本脚本退出 Pit Mode 并切换功率。SmartAudio 2.1图传具备被远程指令置入 Pit Mode 的能力。也就是说即使你的 VTX 不支持远程进入 Pit Mode脚本的其他四档功率控制依然可用。此外ArduPilot 的 SmartAudio 协议驱动将协议分为 v1 / v2 / v2.1 三个版本见 AP_SmartAudio.h 中的ProtocolVersion枚举不同版本的命令响应帧结构存在差异v2.1 响应中会额外包含当前功率 dBm、功率档位数与各档 dBm 值见 AP_SmartAudio.h 的注释本 Lua 脚本按 v2 规范发送命令帧。与原生 SmartAudio 驱动的对比需要说明的是ArduPilot 本身已经内置了完整的 SmartAudio 图传控制支持AP_VideoTX.cpp AP_SmartAudio.cpp原生驱动通过VTX_*参数组如VTX_POWER、VTX_FREQ、VTX_OPTIONS中的VTX_PITMODE等位标志见 AP_VideoTX.h进行配置并支持change_power()等 APIAP_VideoTX.cpp。本 Lua 脚本的价值在于当飞手更希望纯脚本 RC 通道方式控制功率、或者板载固件未启用原生 VTX 驱动时提供了一种完全通过 Lua 脚本实现同等控制的轻量方案——其五档划分、上电功率设定与 GCS 反馈均独立实现不依赖VTX_*参数且 RC 通道映射逻辑清晰每 500ms 轮询一次档位变化才发指令易于二次修改。快速配置清单按以下顺序操作即可完成部署将 SmartAudio.lua 上传到飞控的APM/scripts目录板卡需支持 Lua 脚本。选择一个空闲 UART 串口设置SERIALx_PROTOCOL 28、SERIALx_OPTIONS 4。将该串口 TX 引脚连接到 VTX 的 SmartAudio 输入。选择一个 RC 通道设置RCx_OPTION 300作为功率切换通道。按需设置SCR_USER1-1保持原功率0Pit Mode1LOW2MED3HIGH4MAX。上电后观察 GCS 文本消息确认开机功率拨动 RC 通道确认VTX PWR ...消息随档位切换出现。配置完成后功率档位与 PWM 的对应关系、SCR_USER1的含义以及脚本的初始化逻辑都可以随时回到 SmartAudio.md 与 SmartAudio.lua 中核对ArduPilot 内置的 SmartAudio 协议定义AP_SmartAudio.h则为理解底层通信提供了完整的参考。【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考