树莓派连接Pixhawk飞控,这个组合在无人机圈子里算是经典搭配了。最近后台好几个人问我,说飞控和树莓派之间到底怎么接、怎么配、怎么才能让数据真正跑起来。其实这事本身不复杂,但坑不少——串口配置、电平匹配、TX/RX交叉、飞控参数设置,哪一步没弄对,结果就是心跳包收不到、地面站连不上,折腾一晚上最后发现是线接反了。这篇就把我从硬件选型到软件配置再到实测通信的完整过程写出来,每一步都会解释为什么这么做,方便你照着操作,也能真正理解背后的原理。
这套组合能做的事非常多。树莓派作为机载计算机,可以接摄像头做视觉识别,可以跑Python脚本做任务控制,可以接4G/数传模块把无人机状态远程传回地面站,还能在上面跑MAVSDK或者ROS2做更复杂的自主飞行逻辑。Pixhawk负责底层姿态控制和飞行稳定,树莓派负责需要算力的上层任务,两个配合起来就是一台面向开发的无人机原型机。这篇文章适合手里有Pixhawk级飞控、想给它加个“大脑”的开发者,也适合刚入门无人机开发、想搞清机载电脑和飞控之间通信原理的新手。
1. 树莓派与Pixhawk:为什么这对组合值得折腾
1.1 这套组合能做什么
先说说把树莓派接到Pixhawk上到底能解锁哪些玩法,这决定了你后面配置的方向。
最基础的应用是当数传中继。飞控自带的遥控器图传距离有限,但把树莓派接上去,通过WiFi或者4G模块,就能实现超远距离的上下行通信。我在户外测试时,地面站用一台普通笔记本连树莓派的WiFi热点,稳定跑过两三公里,这是原厂数传很难做到的。
再往上走就是机载计算。Pixhawk那颗STM32芯片用来跑姿态解算和控制算法没问题,但你要让它做视觉避障、目标识别、实时路径规划就力不从心了。树莓派这边装好OpenCV和MAVSDK,从摄像头读画面、跑模型、再把控制指令通过MAVLink协议发给飞控执行,整个流程非常流畅。我之前做过一个简单的“线跟着小车”原型,就是树莓派识别地面线条方向,通过MAVLink的SET_POSITION_TARGET_LOCAL_NED指令控制无人机跟随,效果还不错。
第三个用途是传感器融合与数据记录。树莓派可以挂Lidar、RTK模块、工业相机这些外设,把数据打上时间戳存到SD卡里,后期做SLAM建图或者飞行回放分析。Pixhawk原生的日志存储容量有限,长时间飞行记录高频数据很容易写满,树莓派作为外置记录仪就没有这个烦恼。
最后是开发调试层面的便利。树莓派上可以直接跑MAVProxy或者QGroundControl,接一块小屏幕就能当便携地面站用;配合SSH,你在电脑上就能远程改飞控参数、查看实时状态、烧录固件,不用每次拔线连电脑。
1.2 硬件选型与准备工作
硬件选型方面,先说树莓派。树莓派4B是性价比最高的选择,2GB版本跑MAVProxy加摄像头推流都够用;4GB或8GB版本如果你要跑YOLO这种轻量视觉模型会更从容。树莓派3B+也能用,但GPIO串口和USB同时工作时的性能会有点吃紧。树莓派5我在PX4固件的飞控上试过,性能没问题,但要注意它的GPIO串口设备名和旧款略有差异,后面会单独讲。
飞控这边,任何能刷ArduPilot或PX4固件的Pixhawk系列都可以,我用的是Pixhawk 4,另外在朋友的Cube Orange上也验证过同样的接法。关键是要搞清楚你飞控的TELEM口支持什么电平。绝大多数Pixhawk系飞控的TELEM口是3.3V UART电平,和树莓派GPIO的3.3V电平是兼容的,可以直接连。但部分早期飞控或者带5V电平的扩展板需要做电平转换,稳妥起见最好查一下硬件的原理图。
准备材料清单给你列一下:
- 树莓派4B/3B+(含SD卡、电源),我建议用5V/3A的官方电源,后面说为什么
- Pixhawk系飞控(含对应固件,本文以ArduPilot 4.3为例)
- 杜邦线母对母若干,或者直接买一块JST-GH 4pin转杜邦的转接线板(大概十几块钱,比手工焊接省事很多)
- USB-TTL转接模块(可选,调试备用)
- 电烙铁和热缩管(如果你打算把线做成正式接头,而不是就用杜邦线裸奔)
提示:别用那种劣质杜邦线接串口,无人机飞行时震动大,接触不良会造成通信中断。我后来是买了一块转接板,把飞控的JST-GH插座转成带锁扣的杜邦母座,稳定很多。
2. 连线前的底层原理:串口、电平、MAVLink
2.1 串口通信与TX/RX交叉原理
树莓派和Pixhawk之间最常用的通信方式不是USB,而是UART串口。用串口的好处有几个:占用的IO资源少,GPIO口同时还能控制舵机、读取传感器;适合长时间稳定运行,出问题后排查链路也简单。USB连接虽然即插即用更省事,但飞控固件升级、设备枚举出错时,不如串口来得直接可控。
串口通信的核心是一个“发”和一个“收”。树莓派的GPIO 14是TX(发送),GPIO 15是RX(接收)。飞控的TELEM口也有自己的TX和RX。这里最容易踩的坑就是交叉连接:树的TX接飞的RX,树的RX接飞的TX,然后地线互相连起来。你如果把两边TX对TX、RX对RX接上,数据就全堵在路上了,开始端各自等着接收,谁都发不出去。
为什么必须共地?因为串口信号的电平是相对参考点来读的,树莓派发3.3V高电平,飞控要判断这个信号是0还是1,参照的就是两边共同的GND。如果两边地线没连,参考点漂移,收到的数据十有八九是乱码,甚至完全没反应。共地这个细节,我见过太多人忽略,结果排查半天发现地线没接。
真正的通信内容走的是MAVLink协议。MAVLink是无人机领域的事实标准协议,特点是每个数据包都很小,采用消息ID和分组的方式,可以理解为“无人机的TCP/IP”——只不过它更多是轻量化的,直接用二进制帧结构封装飞行姿态、GPS坐标、飞行模式这些数据。树莓派上的程序通过串口读取MAVLink包、解析字段,就能知道飞控当前的各种状态;反过来,也可以向飞控发送MAVLink指令,让它执行动作,这就是整个系统通信的底层机制。
2.2 电平匹配与供电方案
电平匹配是很多人忽略但其实很容易出问题的地方。树莓派GPIO是3.3V逻辑,绝大多数Pixhawk飞控的TELEM口也是3.3V逻辑,两者直连没问题。但如果你用的飞控板子设计上没有做电平转换、直接暴露5V逻辑(这在一些兼容板、或者自己接的串口扩展上常见),那么树莓派的3.3V信号给它发数据没问题,但飞控的5V信号回传到树莓派GPIO上就可能烧IO口。
怎么判断?翻硬件原理图或者说明书,去官方仓库搜“TELEM”,看电平部分标识。如果你手头没有资料,稳妥做法是在TX线路上串联一颗1kΩ左右的电阻做限流保护,或者用一颗电平转换模块,双向转换也就十几块钱,坏了也不心疼树莓派。
供电这块更需要仔细。树莓派和飞控各用各的电源是原则,至少不要让树莓派的5V直接灌到飞控的5V引脚上。我给树莓派用的是独立5V/3A电源,飞控由动力电池的BEC或者单独BEC供电,两者只共地、不共源。为什么?因为飞控的电源来自动力电池的稳压模块,电压波动大;树莓派电源如果跟它共用,容易被拉低或者受到开关噪声干扰,轻则自媒体飘忽不定,重则树莓派重启。
还有一个细节:TELEM口上通常有一根5V输出(第1脚),这个脚千万别接到树莓派任何引脚上。它本身是给外部数传模块供电用的,接到树莓派上可能造成两边电源互灌,异常发热甚至烧板。只接TXD、RXD、GND三根线就好。
2.3 飞控端参数需要改什么
飞控的TELEM口默认工作状态不一定适合连接树莓派。以ArduPilot固件为例,假设你用的是TELEM2口,需要在飞控参数里做如下设置(通过Mission Planner或者QGC连接飞控后在参数列表里改):
- SERIAL2_PROTOCOL = 1 或 2,其中1表示MAVLink1,2表示MAVLink2。一般建议用MAVLink2,因为支持签名和更强的消息扩展
- SERIAL2_BAUD = 57,表示波特率57600,如果是921就表示921600
注意SERIAL2_BAUD这个参数的单位是“千波特率”,所以57就是57600。波特率是通信速率,两边必须设成一致,否则收到的全是乱码。我通常用57600,稳定可靠;如果你后面传输数据量大,改成921600也完全可以,但两边要同步修改。
PX4固件下的参数名会不一样,大约是MAV_1_CONFIG、MAV_1_MODE、SER_TEL2_BAUD这种命名方式。核心思路是:选一个空闲的UART口,使能MAVLink协议,设置和树莓派一致的波特率。具体参数名随着固件版本会变,建议查阅对应版本的官方参数文档。
3. 树莓派端一步步配置串口
3.1 关闭系统串口登录占用
树莓派默认情况下,GPIO串口是被系统控制台登录占用的,你必须先把它释放出来,否则你插上飞控只能看到一堆启动日志,轮不到你自己的程序收发数据。
先用sudo raspi-config打开配置界面,找到Interface Options,进入Serial Port,两个选项都选No,然后重启。这一步做了两件事:禁用串口作为登录控制台,同时启用GPIO硬件串口功能。如果你懒得进菜单,也可以直接改配置文件,但raspi-config最直观,不容易遗漏。
重启后可以检查一下当前系统占用情况:
ls -l /dev/serial0正常情况下会显示一个软链接,指向真正的串口设备。在树莓派3B/4B上通常是指向ttyAMA0(PL011串口);在树莓派5上可能是ttyAMA0或ttySCSI0,以实际输出为准。如果你看到了ttyS0,说明用的是mini UART,那个时钟不稳定,容易导致串口丢数据,后面我细说。
另外检查一下/boot/cmdline.txt文件里是否还写着console=serial0之类的字样,有的话要删掉,否则系统还是会往串口打印日志。
提示:修改系统配置前先备份原文件。改错还能还原,省得重装系统。
3.2 启用GPIO硬件串口并排查冲突
如果你用的是树莓派3B、3B+、4B,GPIO14/15这个硬件串口默认被蓝牙占用了——准确说,蓝牙占用了PL011串口,GPIO上退而求其次用的mini UART(ttyS0)。mini UART的波特率跟随核心时钟变化,在树莓派上表现为负载高时串口通信容易出错,这是很不推荐的。
解决办法是在/boot/config.txt末尾加一行:
dtoverlay=disable-bt加上后重启,蓝牙就被禁用,GPIO14/15用的就是PL011这个高质量硬件串口。这条配置释放出来的串口确实稳,我做长时间数据记录时没有掉包。如果你必须要用蓝牙,也可以改成dtoverlay=miniuart-bt把mini UART留给蓝牙、PL011留给GPIO,但能不用蓝牙就不用,稳定第一。
树莓派4B还有个额外要点:config.txt里要有enable_uart=1,这个参数在部分官方镜像里默认是1,但如果你在兼容镜像上遇到串口完全没反应,先检查这一项。
树莓派5的情况稍微特殊,它的GPIO串口设备名和旧版不同,而且官方对串口的默认策略也有调整。如果你在5上遇到/dev/serial0指向不对、或者没有这个设备,建议直接查树莓派5专用串口文档,按最新的方式启用。总体流程跟4B类似,但别生搬硬套。
3.3 树莓派端与飞控端参数对照表
两边配置完成之后,你需要确保它们完全对得上。这是我常用的对照表:
| 配置项 | 树莓派端 | 飞控端(ArduPilot) |
|---|---|---|
| 通信接口 | /dev/ttyAMA0(或/dev/serial0) | TELEM2口 |
| 波特率 | 57600 | SERIAL2_BAUD = 57 |
| 协议 | MAVLink2 | SERIAL2_PROTOCOL = 2 |
| 电平标准 | 3.3V UART | TELEM口3.3V UART |
| 接线方式 | GPIO14(TX)接飞控RX,GPIO15(RX)接飞控TX,GND共地 | 同左 |
如果你用的是PX4固件,表格里的飞控端参数就替换成前面说的MAV_1_*系列,确保协议和波特率一致就行。两边有任何一个参数没对上,后面测试都会出乱子,所以这一步值得反复确认。
4. 实际接线与通信测试
4.1 接线对照表与操作细节
接线这一步照表走就行,但心态要细心。我用的是Pixhawk 4的TELEM2口,它的引脚定义是:
- 第1脚:5V(不要接树莓派)
- 第2脚:TXD(飞控发送端,接树莓派GPIO15/RX)
- 第3脚:RXD(飞控接收端,接树莓派GPIO14/TX)
- 第4脚:GND(接树莓派GND,比如GPIO 6或GPIO 9)
如果是TELEM1口,定义类似,但注意对应的飞控参数要改成SERIAL1_*系列。不同飞控板的JST-GH接口引脚序基本一致,但保险起见核对一下你手头板子的引脚图。
连接时避免飞控通电状态下插拔线缆,规范的顺序是:先把树莓派和飞控连线接好,再上电。热插拔不仅可能造成通信异常,极端情况还会损坏串口引脚。另外,连线尽量保持短,串口在长线上抗干扰能力弱,超过20cm就有风险,尤其在电机转动时干扰更明显。
我自己的经验是:杜邦线只是调试阶段用,长期用建议做成固定线束,用热缩管封好接头,减少震动松脱的风险。无人机上任何一处连接都可能在飞行中被放大成事故。
4.2 串口数据检查与心跳测试
接线完成后先别急着跑地面站,先用最简单的命令验证硬件链路通不通。在树莓派终端执行:
sudo apt install screen sudo screen /dev/ttyAMA0 57600如果一切正常,你会看到一堆二进制乱码,但注意观察:这些乱码有没有规律?MAVLink报文有固定的帧头(0xFE或0xFD),在乱码中会周期性出现特征字节。看到这个特征,基本可以说明飞控在正常发送数据,串口链路是通的。
如果屏幕上一片空白,可能是飞控没在给这个串口发数据;如果全是均匀的、没有结构的乱码,可能是波特率不匹配。按Ctrl+A然后按K退出screen。
更严谨的测试是用Python直接读取串口数据。装上pyserial后,运行下面这个小脚本:
sudo pip3 install pyserialimport serial import time ser = serial.Serial('/dev/ttyAMA0', 57600, timeout=1) start = time.time() while time.time() - start < 5: data = ser.read(ser.in_waiting or 1) if data: print(data.hex()) ser.close()如果输出中出现类似fe开头的可变长度包,或者是fd开头的MAVLink2包,就说明通信链路已经打通。FE开头和FD开头都能接受,代表MAVLink1或MAVLink2的帧头,具体是哪种取决于你在飞控端设的协议。
验证通过后,这个命令窗口就可以关掉了。接下来用正式的工具建立数据链路。
4.3 用MAVProxy建立树莓派端地面站链路
MAVProxy是运行在Linux平台上的轻量级MAVLink地面站,比QGroundControl更适合树莓派这种资源受限的设备。安装命令:
sudo apt update sudo apt install python3-dev libxml2-dev libxslt1-dev sudo pip3 install pymavlink MAVProxy然后启动MAVProxy,连接串口:
mavproxy.py --master=/dev/ttyAMA0 --baudrate 57600启动后如果看到类似Link 1 OK和心跳信息,就说明链路通了。这时候你可以在MAVProxy命令行里敲命令:
status可以看到飞控的飞行模式、GPS状态、电池电压等实时信息。要手动解锁起飞,可以输入arm throttle,但建议先在没有桨叶的状态下测试,确保一切正常再装桨。
MAVProxy还有很多实用子命令,比如module load console可以打开一个简易图形界面,module load map可以加载地图显示飞机位置。如果你打算在树莓派上跑一个简单的地面站,MAVProxy是很不错的选择。
5. 从串口到Python控制:让树莓派真正“读懂”飞控
5.1 用pymavlink读取飞控状态
链路通了以后,下一步就是让树莓派上的程序能主动和飞控对话。pymavlink是最常用的Python库,它帮你完成了MAVLink协议的编解码工作,你只需要写几行代码就能拿到飞控数据。
from pymavlink import mavutil # 连接串口 master = mavutil.mavlink_connection('/dev/ttyAMA0', baud=57600) # 等待飞控发送心跳包 print("等待心跳包...") master.wait_heartbeat() print("已连接飞控,系统ID:", master.target_system, "组件ID:", master.target_component) # 请求数据流,频率10Hz master.mav.request_data_stream_send( master.target_system, master.target_component, mavutil.mavlink.MAV_DATA_STREAM_ALL, 10, 1 ) # 持续读取并打印GPS状态 while True: msg = master.recv_match(type='GLOBAL_POSITION_INT', blocking=True) if msg: print(f"纬度: {msg.lat / 1e7}, 经度: {msg.lon / 1e7}, 相对高度: {msg.relative_alt / 1000:.2f}m")这段代码的关键在于wait_heartbeat(),它不但验证了链路,还拿到了飞控的系统ID和组件ID,这两个ID是后续发送指令必须使用的。
如果要发送控制指令,比如切换飞行模式到“Loiter”(悬停):
master.set_mode_apm('LOITER')或者直接发送自定义MAVLink指令,比如设置目标位置。这些操作在开发自主飞行任务时非常常用,树莓派相当于一个“会写代码的遥控器”,你可以把复杂的任务逻辑全部放进Python脚本。
5.2 树莓派做机载电脑的扩展场景
链路稳定之后,你可以把树莓派的能力真正发挥出来。这里说三个我实际跑过的方案。
第一个是远程视频加数传整合。树莓派挂一个摄像头(USB摄像头或者CSI接口的OV5647都行),摄像头画面通过GStreamer推流,MAVLink数据通过WiFi转发,这样地面站既能看实时图传,又能获取完整的飞行参数。我在地面站用QGC,图传画面用VLC播放器拉流,两个软件各干各的,互不干扰。
第二个是结合OpenCV做视觉任务。比如起降标签识别,树莓派用ArUco码识别降落点坐标,然后通过MAVLink把相对位置发送给飞控,实现自动降落。这个方向是目前树莓派在无人机上最有价值的应用之一,算力刚好够用,而且Python生态成熟。
第三个是远程维护。给树莓派装上SSH服务,你人在家里就能登录飞机上的树莓派,远程查看飞控日志、修改启动参数、甚至重启飞行程序。配合Todesk这类远程桌面工具,还能在树莓派上直接操作图形界面的地面站软件,调试体验和在现场差不多。
5.3 摄像头接入与图传方案
热词里提到的luvcview和OV5647都是树莓派摄像头相关的关键词。luvcview是一个轻量级的USB摄像头查看工具,安装后一条命令就能看到画面:
sudo apt install luvcview luvcview -d /dev/video0 -i 640x480如果你用CSI接口的OV5647摄像头模块,树莓派官方工具是libcamera,树莓派5上更是彻底转向了libcamera体系。拍一张测试照片:
libcamera-still -o test.jpg拍完照片,下一步是推流。我常用的方式是GStreamer加UDP推流,画面延迟大概在200毫秒左右,地面站看到的画面基本可用:
gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! x264enc tune=zerolatency bitrate=1000 ! rtph264pay config-interval=1 ! udpsink host=192.168.1.100 port=5000结合前面说的MAVLink链路,画面和数据都在同一个WiFi链路里传输,效果很好。注意带宽分配,如果图传占满了WiFi带宽,MAVLink数据可能会延迟。我先跑通数传、再开图传,逐步增加负载,这样排查问题的时候能区分是网络还是串口的问题。
6. 高频踩坑记录与排查建议
6.1 典型问题现象速查表
这些是我在树莓派连接Pixhawk过程中实际遇到的高频问题,整理成一个速查表:
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| screen里完全没数据 | 飞控串口协议没开,或TX/RX接反 | 确认SERIAL2_PROTOCOL=2,检查TXD接RX、RXD接TX |
| 满屏乱码但没有帧头 | 波特率不一致 | 统一波特率,重新核对SERIAL2_BAUD |
| 启动树莓派后飞控收到一堆垃圾数据 | 串口被login shell占用 | 执行raspi-config关闭串口登录 |
| 连接时树莓派不断重启 | 供电不足 | 换独立5V/3A电源,去掉TELEM的5V接线 |
| MAVProxy提示No link | 串口权限问题或设备名不对 | 用sudo运行,检查/dev/serial0是否正确 |
| 蓝牙功能没了 | 你加了disable-bt | 这是正常的,若需蓝牙改用miniuart-bt方案 |
| 数据偶尔丢包 | 杜邦线接触不良或干扰 | 换转接板,缩短线长,加磁环或用双绞线 |
6.2 三个我最想强调的细节
第一个细节:树莓派启动瞬间,如果GPIO串口上还残留系统启动日志,这些数据会被飞控当成MAVLink消息处理。即使你已经用raspi-config关闭了串口登录,某些镜像的固件更新、或者你手动改过config/user.txt,都可能让启动阶段往串口吐东西。检查一下/boot/cmdline.txt,确保没有console=ttyAMA0或console=serial0字样。这一步没做干净,飞控可能频繁触发“unknow message”报错,影响后续任务执行。
第二个细节:千万别用飞控的TELEM口5V电源给树莓派供电。TELEM口的5V通常是飞控板上电源模块直接输出的,电流能力有限,接树莓派这种动辄1A以上的设备,电压会被拉低,飞控自己的传感器也会工作异常。我见过有人为省一个电源把钱省出大麻烦——飞控和树莓派同时不稳定,查问题查到怀疑人生。分开供电、共地,是底线。
第三个细节:调试阶段先别上桨。我用树莓派控制飞控做自动起飞测试时,第一遍就遇到了加速度计数据跳变,如果当时带着桨,大概率会出事。树莓派的高频信号、USB设备干扰都可能导致飞控传感器噪声变大。先把螺旋桨拆掉,把树莓派放在远离IMU的位置,做好屏蔽再实测,否则你很难分清是软件问题还是硬件干扰。
6.3 串口还是USB连接怎么选
我看到不少人直接拿USB线把树莓派和飞控连起来,简单是简单,但我不推荐作为长期方案。原因有三:
第一,USB连接时飞控枚举为/dev/ttyACM0,它依赖USB驱动稳定,而树莓派供电不稳时最先出问题的就是USB设备。串口直连则少一层USB协议,稳定很多。
第二,USB口数量有限。树莓派4B一共四个USB口,接摄像头、数传模块、U盘之后基本没剩多少,串口连接则完全释放这些USB口。
第三,USB连接导致树莓派和飞控的电源地通过USB的屏蔽层连在一起,更容易引入电源噪声,飞控的IMU数据都可能受影响。
所以我的建议是:调试初期可以用USB快速验证,正式装机用GPIO串口。两者切换时记得把飞控参数和树莓派程序里的端口名一起改掉,我因为忘了改端口名白折腾过半小时。
7. 总结我的实操心得
树莓派连接Pixhawk这个项目,真正做完之后你会发现,90%的时间都花在排查“为什么没通”上,而不是“怎么连”。
我最开始以为买回来插上就能用,结果卡在串口被登录占用这一步,连了两天没通;后来搞清楚了raspi-config和disable-bt的关系,才顺利看到心跳包。串口这类底层通信,出问题的时候不像Web开发那样有清晰的报错信息,而是“没反应”“乱码”“断断续续”,所以排查思路必须一步一步来:先确认物理连接,再确认协议参数,最后才考虑软件配置。
如果你按照这篇文章一步步走下来,到最后看到MAVProxy里稳定的心跳输出,说明你已经打通了机载电脑和飞控之间的大动脉。接下来无论是做视觉识别、自主飞行,还是远程数传图传,都有了可靠的基础。这个项目的延展空间很大,一套配置搞定后,后面加功能只是往这棵树上添枝叶而已。
最后分享一个我的小习惯:每次改动配置后,在树莓派上把飞控的关键参数和当前配置文件都备份一份,命名带上日期。调试到后面,你可能会忘记哪些参数改过、哪些配置是能用的,有备份就能随时回滚,省下大量重复劳动。