ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

空心杯飞控开源全解析:从硬件设计到PID调参实战

空心杯飞控开源全解析:从硬件设计到PID调参实战 粉丝在聊天框里只留了一句话“钱你收下飞控赶紧开源别让好东西烂在硬盘里。”紧接着就是一笔1000元的转账。说实话我在电脑前愣了好几秒。做了这么多年嵌入式开源过不少小玩意被这种“打赏式催更”还是头一回。这台空心杯飞控是我断断续续做了大半年的微型四轴项目。所谓空心杯飞控就是专门为空心杯电机这类小功率直流有刷电机设计的无人机飞行控制器通常只有两三厘米见方用1S锂电池供电主要用在室内穿越机tiny whoop、微型航模、教学实验平台这一类场景。它解决的问题很具体在几十克量级的机身里把姿态感知、控制算法、电机驱动、无线链路全部塞进一块小板子还能做到稳定悬停、敢翻敢滚。这篇文章我想把整个项目从头到尾讲一遍包括硬件选型逻辑、电机驱动的特殊之处、固件控制链路、PID调参的起点参数以及我打样实测踩过的各种坑。适合正在做微型四轴、想入门飞控开发、或者打算把自己项目好好开源出来的朋友。放心这份内容比开源仓库里的README要细得多。1. 从一次“打赏式催更”说起这个项目的初心与定位1.1 空心杯飞控到底是个什么东西先给新手说清楚一个容易混淆的概念无人机飞控和空心杯没有必然关系市面上大量穿越机用的是无刷电机飞控只是其中的控制和传感核心。但“空心杯飞控”指的是专门围绕空心杯电机特性设计的整套方案通常板子上直接集成四路电机驱动也就是“飞控四合一电调”一体化。空心杯电机是有刷直流电机里很特殊的一类转子做成杯状、没有铁芯所以转动惯量极小加减速响应极快。同样功率下它比普通有刷电机轻、响应快但也天生不擅长长时间大负载。微型四轴正是发挥它优势的舞台机身二三十克四个0802电机直径8mm、高2mm配上1.5英寸左右的小桨室内随便飞摔了也不心疼。这台项目的核心指标我一开始就定得很清楚整板面积不超过25×25mm重量控制在8g以内1S电池直驱三段式供电支持SBUS串口接收机主控跑自研固件姿态环做到2kHz频率。目标不是跟大疆比也不是跟Betaflight生态里的成熟飞控掰手腕而是做一个“原理完全开放、代码看得懂、坏了能自己修”的教学级开源飞控。1.2 为什么我最终选择把整个项目开源说实话最初这个项目是自用。我在调试过程中发现市面上的微型飞控要么闭源到连原理图都要签NDA要么代码被封装得像黑盒出了问题只能整板换新。对于一个想研究飞控原理的人来说这种感觉非常难受。那位粉丝转账之前我已经把代码重构了几轮文档也写了差不多。但开不开源这件事我一直犹豫怕代码烂、怕被人喷、怕维护麻烦。那一笔转账成了压垮犹豫的最后一根稻草既然有人愿意为一份“可能用得上”的开源付出真金白银说明这个需求是真实存在的。与其让它烂在硬盘里不如把原理图、PCB源文件、固件源码、调试记录全部摊开让后来者少走我走过的弯路。开源不是把代码丢到GitHub就完事。真正“能用”的开源至少要让人拿着BOM单能下单、照着文档能焊接、编译固件能烧录、遇到问题能找到排查路径。这一整套事情我后面会分章节细讲。2. 硬件设计全解从选型到打板的每一处心思2.1 主控与传感器为什么是STM32F411加MPU6500主控我选了STM32F411CEU6原因很简单这颗芯片在微型飞控领域几乎成了默认答案。Cortex-M4F内核、主频100MHz、512KB Flash、128KB RAM跑一个自研姿态估算加PID控制绰绰有余。最关键的是它货源稳定、封装是QFN48手工焊接和热风枪吹焊都还能操作。有人会问为什么不用更便宜的F103或者更先进的F722F103主频72MHz跑2kHz控制环外加姿态解算会非常紧张而且没有硬件浮点单元四元数运算要写大量定点代码徒增复杂度。F722性能过剩价格却翻了几倍对一颗教学向飞控来说没必要。F411的浮点加上100MHz主频刚好是“够用且留有余量”的甜点区。传感器我用的MPU6500走SPI总线。这里有个容易被新手忽略的细节六轴IMU加速度计陀螺仪是飞控的“眼睛”它的数据质量直接决定控制效果。MPU6500的SPI模式带宽比I2C高不少陀螺仪采样能稳定跑到4kHz以上配合F411的DMA可以把传感器数据搬运对CPU的占用压到最低。如果你手里正好有ICM42688也可以替换寄存器映射稍有区别但在固件里我加了驱动抽象层换传感器只需要改一个宏。注意选IMU不要只看型号还要看是否“原装”。市面上MPU6500拆机翻新片很多陀螺仪零偏和噪声表现参差不齐。我第一次打样贪便宜买了散新片结果十块板子里有三块陀螺仪零偏大得离谱静止状态下角速度漂移超过1.5°/s怎么校准都压不下去。后来全部换成正规渠道的原装片问题瞬间消失。飞控这种对传感器敏感的设备IMU千万别省这几块钱。2.2 电机驱动空心杯电机对功率级的特殊要求空心杯电机是有刷电机不能像无刷电机那样用三相逆变桥加换相逻辑驱动。它只需要一路PWM加一个低侧MOSFET或者一个H桥来实现正反转。微型四轴四个电机都是单向旋转所以用低侧N沟道MOSFET就够了每个电机一路一共四路。我选的是AO3400这颗N-MOSFETSOT-23封装Vds耐压30V连续漏极电流5.7A导通内阻典型值40毫欧左右。四颗电机同时满油门时1S电池端电流大概在6A到8A左右牧场这个余量对于单路1.5A左右的持续电流来说是安全的。这里必须提一个空心杯电机驱动的关键点PWM频率不能乱设。无刷电机电调动辄24kHz、48kHz但空心杯电机转子没有铁芯电感极小PWM频率太高会让电流纹波加剧反而增加电机发热和MOSFET开关损耗。我实测下来8kHz到16kHz是甜点区间默认用8kHz需要消除电机啸叫可以拉到16kHz但发热会明显上升。还要在电机端子两端并联一个0.1uF陶瓷电容加上在电机线靠近板子端套一个小磁环或者绕几圈磁珠。空心杯电机的电刷会产生大量高频火花噪声轻则让陀螺仪数据出现毛刺重则直接干扰无线接收机导致失控。这个问题我后面在避坑章节还会细说因为它真的坑了我整整一周。2.3 电源架构与PCB布局一块小板上的分电哲学25×25mm的板子要同时容纳主控、IMU、接收机接口、四个电机驱动和电源系统布局必须分优先级。我的分配原则是电源走外层、信号走内层、电机驱动尽量远离IMU。板子是四层板成本上比双层板贵一点点但因为有了完整的地平面和电源平面噪声水平低了不止一个数量级。电源架构上1S锂电池的电压范围是3.7V到4.35V高压锂电LiHv。主控和IMU需要3.3V我用了两颗稳压器分开供。一颗ME6211给数字部分一颗低压差LDO单独给IMU的模拟供电。为什么不直接用一组3.3V统一供电因为电机瞬态抽流时电池电压会跌落如果IMU和MCU共用一条3.3V轨陀螺仪数据会跟着电源抖动一起晃姿态解算直接废掉。电池电压检测我用了一个简单的电阻分压器两个1%精度的电阻把VBAT分压到ADC量程内。这个看似不起眼的电路是低电量保护和返航判断的基础。分压电阻一定要用1%精度5%的普通电阻分压误差达到0.1V多会让低电量保护提前或者滞后对整机寿命影响很大。3. 固件与算法让姿态真正“稳”下来3.1 核心控制链路陀螺仪 → 滤波 → PID → 油门整个固件最核心的一条链路是这样的IMU通过SPI把陀螺仪角速度和加速度数据送进MCU经过姿态解算得到当前姿态然后与遥控器目标姿态做差误差送入PID控制器PID输出经过电机混控矩阵换算成四个电机的油门值最后以8kHz的频率翻转MOSFET的PWM占空比。我主控制环跑在2kHz也就是每0.5毫秒执行一次完整的“采陀螺仪→算姿态→算PID→输出PWM”流程。为什么不用更高空心杯电机本身的机电响应带宽有限把控制环提到8kHz对悬停手感没有可感知的提升反而把CPU占用率从30%推到70%留给遥测和日志的空间就少了。F411这颗芯片跑2kHzCPU占用率大约30%还有充足的余量做无线通信和调试输出。电机混控矩阵值得展开说。四轴飞行器的基本控制量是三个横滚Roll、俯仰Pitch、偏航Yaw。这四个电机的油门输出不是简单地“四个值”而是“基础油门横滚修正俯仰修正偏航修正”的组合运算。每个电机的方向、位置不同修正量的正负号也不同。我在固件里用了一个静态混控表每个电机对应一组系数写死之前反复对着实物图核对了三遍因为“混控符号反了飞机会像喝醉一样乱窜”这种事我见过太多新手栽在里头。3.2 姿态解算互补滤波还是四元数微型飞控的姿态解算常用方案有两种互补滤波和基于四元数的Mahony滤波。我给新手解释一下两者的区别。互补滤波的思路很朴素陀螺仪短时间准但会漂移加速度计长时间准但震动下噪声大。那就让陀螺仪主导短期姿态加速度计慢慢拉回长期真值两者用一个比例系数融合。它运算量小、代码简单适合F103这类低端MCU。Mahony滤波则是把姿态用四元数表示通过修正陀螺仪漂移来保持姿态估计的一致性。它的优点是姿态表示没有欧拉角的万向锁问题适合大幅翻转动作而且算法成熟有大量现成实现可以抄。代价是代码稍微复杂一些需要理解四元数和坐标旋转。我在这个项目里用的是Mahony因为微型穿越机经常要做翻滚动作欧拉角描述大幅运动会有奇异点。系数kp、ki分别取0.5和0.05这个值在大多数1S微型机上都算稳定起点。如果你的飞机悬停时姿态轻微晃动可以把kp调大一点让加速度计更快拉回真值但如果震动太大kp过大反而会把震动引入姿态估计这时候应该先解决震动而不是调系数。3.3 PID调试实战微型机惯用的起点参数控制律的主体是三个通道的PID悬停状态下核心是角速率环Rate Loop。这一层先稳定飞机对“转动”的响应再往上看姿态环。微型穿越机最常见的调试目标是“指哪打哪、松手不飘”。我分享一套给空心杯微型机的起点参数用的单位是Betaflight社区的常见风格Rate P横滚/俯仰在42到55之间I在80到100之间D在18到25之间偏航通道P给60左右I给100D给小一点甚至给0。这个数值范围基于大量微型机实测不要直接抄因为电机推力、机架重量、桨叶尺寸都会改变最优值但它能保证你第一次起飞不至于失控乱晃。调试方法我只推荐一种先固定油门让飞机在手中半悬停观察它左右乱摆的“频率感”。高频抖动是P过高或者D过低低频左右摇摆是P不足或者I不足。每次只改一个参数幅度不要超过10%。一次改三个参数出了问题你根本不知道是谁干的。PID参数调完之后还有一件经常被忽略的事设置油门曲线。空心杯电机在小油门区间响应非线性明显油门低于30%几乎是虚位高于85%又会快速饱和。我实测发现线性油门在室内小范围悬停时手指需要极细微地调整油门新手根本控不住。我在固件里加了一条可配置的油门曲线默认把0到30%的区间映射到0到15%让低油门更细腻悬停时的手感立刻改善了一大截。4. 开源工程化的细节让代码真正属于社区4.1 开源协议怎么选才算“真开源”说到开源第一件事就是协议选择。很多人以为“把代码放上网”就是开源但协议不对别人想用都会犹豫。我固件用了MIT协议硬件部分用了CERN-OHL-S协议。为什么这样搭配MIT协议对代码几乎没有任何限制别人可以随意使用、修改、商用只需要保留版权声明。我选它是因为这个项目的定位是教学和基础平台我希望它能被尽可能多的人用到哪怕是拿去商业产品里也没有法律负担。硬件部分选CERN-OHL-S而不是更常见的CC-BY-SA是因为CERN协议是专门为硬件设计的它对原理图、PCB文件的修改和分享约束得更明确。CC-BY-SA虽然是文档类的常客但用在硬件上对“什么算修改”“什么算衍生作品”的界定比较模糊容易起争议。选协议前建议大家认真读一遍协议全文别嫌英文长这东西比代码逻辑重要得多——它决定了别人能不能合法地用你的心血。另外提醒一句如果你的固件是基于Betaflight二次开发的那Betaflight是GPL协议你的代码就必须也开源并采用GPL兼容协议这一点绕不开。我这个项目是从零写的自研固件所以才有选择MIT的自由。4.2 文档、BOM和Gerber复现的最后一公里真正让开源项目“活”起来的不是源码而是让别人能复现的资料。我在仓库里放了这些文件缺一不可KiCad 6完整的原理图和PCB工程文件别人能打开改板。Gerber文件加钻孔文件方便不想装KiCad的人直接拿去打样。BOM清单每颗料的位号、封装、型号、LCSC商城编号全部列清楚。这意味着别人可以一键生成PCB代工订单。3D打印的机架STL文件整机零件都能自己打印。固件构建环境说明用STM32CubeIDE加Makefile双方案。烧录教程分别讲了ST-Link SWD方式和DFU方式。我特别想强调的是BOM清单这件事。很多开源硬件项目只给原理图不给BOM导致新手零件凑不齐项目就烂在了“只差一步”上。我把每一颗料的供应商编号都查过、核对过连不同封装电容的温漂特性都写进了文档。看起来是琐事但这是决定“别人能不能真正做出来”的关键。4.3 社区协作如何收集有效反馈开源之后我很快收到了不少Issue和私信。这里踩过一个让我印象深刻的坑新手问“我的电机不转”我回了三条排查步骤结果对面回一句“什么是示波器”。那一刻我意识到文档和社区维护的深度决定了项目的生命力。后来我把Issue模板改成了强制填写的排查日志包括硬件版本、固件版本、供电电压测量值、SPI通信是否初始化成功、遥控器信号是否锁定。强制填写之后有效反馈率明显提升很多问题我自己看一眼日志就能定位到八成。这里给所有准备开源硬件项目的人一个建议不要期待用户都懂技术提供规范化的反馈模板是对你自己也是对用户的负责。5. 打样实测从炸机到稳定悬停的避坑记录5.1 焊接与装配微型化的代价25×25mm板子上最小的元件是0402封装的电容电阻间距0.5mm。第一次手工焊接时我用了普通烙铁头焊完一块板子花了将近四十分钟还掉了两个电容。后来换成J型刀头加放大镜台灯效率翻倍但依然比焊普通开发板费神得多。如果你也想复刻这块板子我给你三个实用建议。第一焊盘上锡不要贪多多余焊锡会造成桥连返工风险极大。第二IMU的朝向必须和固件里定义的坐标系一致焊反了姿态数据整个翻转飞控会认为自己倒着一上电就猛推油门往地上砸。第三焊接完先别急着上电机用万用表测一遍电源对地阻抗确认没有短路再上电。关于装配微型机的电机线是直接焊在板子上的线序要按混控表严格对应。我习惯用四种不同颜色的硅胶线红黑绿蓝分别对应右前、左前、左后、右后这样反复拆装时永远不需要回头查原理图。5.2 上电与电调校准的经典翻车现场这个坑我至少看到五个新手重复踩上电后电机不转。排查到最后往往是电调校准没做。空心杯电机虽然没有传统意义的“电调”但固件里依然需要做一次油门行程校准让固件知道遥控器的最小油门和最大油门对应什么PWM占空比。校准方法是先断开电池遥控器油门推到最大上电等待蜂鸣器或者LED提示三秒内把油门拉回最小等待确认信号完成。这个逻辑听起来简单但很多微飞控固件里如果没做掉电保持设计校准值存不住每次重新上电都需要重新校准。我的固件把校准值写进了Flash只在检测到新遥控器时才重新校准省去了很多重复劳动。还有一次特别奇葩校准完成后四个电机中有两个转速明显偏慢我用万用表量了驱动MOSFET栅极波形发现输出正常最后查到是电机本身的问题——两颗电机的电刷磨损程度不同内阻差了将近1欧姆导致同样电压下转速差异悬殊。解决方法很粗暴也很实用微调混控表里的电机输出比例给内阻大的电机多分配一点油门达到转速平衡。5.3 震动与滤波从根源而不是参数上解决问题悬停测试时我发现陀螺仪数据上有一层明显的高频毛刺机身轻微抖动PID怎么调都压不下去。一开始我以为是PID参数问题反复调了三天毫无改善。后来用串口把原始陀螺仪波形导出来对比发现毛刺频率和电机的电刷噪声频率完全一致这才意识到是电磁干扰而不是控制问题。解决手段有三个层级按优先级排第一硬件上给电机端加吸收电容、电机线套磁珠从源头抑制噪声第二PCB布局上让电机驱动走线远离IMU走线地平面完整第三固件里加一阶低通滤波或者陷波器针对性滤掉特定频率的噪声。我要强调的是滤波是最后一道防线不是第一选择。很多新手一上来就在固件里堆滤波参数把陀螺仪数据滤得又软又钝飞机响应迟钝得像进水了一样。正确的顺序永远是先物理降噪再用软件微调。把源头掐了滤波参数可以给得非常保守飞机手感才跟手。5.4 续航与电池选型续航是微型机的永恒痛点。我的整机重量大约32g含电池实测悬停电流在2.8A到3.5A之间波动。用300mAh、30C的1S电池理论悬停时间是300mAh除以3A等于0.1小时也就是6分钟但实际因为电压下降后电流会上升、电池放电效率并非100%最终稳定在四分钟左右。如果你想榨续航建议关注三个方向第一电机选型。同样尺寸下低KV电机电流小适合平稳飞行高KV电机爆发强但费电悬停场景选低KV更合适。第二桨叶。微型桨的螺距对电流影响极大高螺距桨推重比高但不省电室内悬停用平桨更优。第三重量每减掉1g悬停电流大约能降0.08A左右机身所有多余的塑料件都值得重新审视。另外强烈建议用LiHv高压锂电池标称3.8V、满电4.35V来替代普通LiPo。LiHv在相同体积下能量密度更高实测续航能提升10%到15%唯一的代价是充电器需要支持LiHv模式否则会过充。6. 开源后常见问题速查表我在社区里收集到的问题里有一批高度重复整理成表格方便大家按图索骥。现象可能原因排查动作上电后完全没有反应电源短路或5V/3.3V稳压异常万用表量电源对地阻抗再量3.3V输出IMU数据全是0xFFSPI通信失败或引脚虚焊检查IMU的CS、SCK、MOSI、MISO四个脚的焊接陀螺仪静止漂移超过1°/sIMU电源纹波大或传感器老化检查模拟供电LDO换原装传感器电机通电不转油门未校准、MOSFET损坏、混控表错误先校准油门再量栅极波形最后核对线序悬停时高频抖动P过高或D不足每次只降P的10%观察变化悬停时低频摇摆I不足或重心偏移加大I检查电池安装位置机身响但推力不足桨叶装反或电机内阻不均检查桨叶方向量电机内阻遥控距离极短接收机天线遮挡或电机干扰天线远离电机线加磁珠续航明显低于预期电池老化或螺旋桨变形换新电池换桨叶对比这些问题的根源大多数不是“高科技难题”而是基础工程细节。微飞控的调试思路从来不是一上来就调参而是先确认每一段链路是好的电源、传感器、输出、混控、遥控逐级排查问题不会超过五步就能定位。按我个人这几年的体会开源一个项目的真正门槛从来不是代码而是“你是否愿意把踩过的坑也一并交出去”。那台飞控我能飞起来靠的不是某个灵光一现的算法而是一次次炸机后记录下来的参数、波形和焊接细节。那位粉丝的1000元与其说是买源码不如说是买了一份“别人已经替你踩过坑”的确定性。我把这份确定性原原本本放进了仓库也希望更多人能在这个基础上把自己的飞行器做得比自己预期的更好。最后再顺手分享一个我后来才补上的小技巧在固件里加一个启动自检阶段的“电机顺序提示”——依次短促转动四个电机让你不用看原理图就能确认电机和机臂的对应关系。就这一个功能省掉了无数次因线序错误引发的炸机。这种小功能不会出现在任何教科书里但它恰恰是嵌入式项目里最值钱的部分。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进