69元DIY四旋翼:ESP32+MAVLink+手机Web遥控全链路实战
1. 项目缘起与整体方案拆解1.1 为什么我会盯上69元四旋翼这个方向先说结论这个项目的核心吸引力不在于便宜而在于用极低的成本把无人机最核心的几条技术链路完整跑通一遍——主控、姿态解算、无线通信、协议对接、闭环控制一个都不少。市面上几百上千的成品玩具飞机飞是能飞但你拆开看飞控是黑盒协议是私有改一行代码都无从下手。而自己搭一台哪怕只有巴掌大每一个环节都是透明的。我最初动这个念头是因为手头攒了一堆零碎件几片 ESP32 开发板、几个空心杯电机、几块小容量锂电池还有一堆从旧玩具上拆下来的桨叶。与其让它们吃灰不如凑一台能飞的东西出来。算下来真正需要新买的只有机架和几颗螺丝成本压到 69 元完全可行。这个项目适合谁我认为有三类人值得动手一是想入门嵌入式飞控但被 PX4、ArduPilot 那套庞大代码库吓退的初学者二是做过 ESP32 物联网项目、想把它从点灯联网推进到实时控制的进阶玩家三是纯粹想搞明白无人机到底怎么保持平衡这个问题的技术好奇者。你不需要会画 PCB不需要焊接 BGA 封装会基本的接线和烧录固件就够了。1.2 核心需求到底有哪些把标题拆开看需求其实非常明确我列了个清单主控选型乐鑫 ESP32。理由很直接——它自带 WiFi 和蓝牙双核 240MHz价格便宜到离谱社区资料多到看不完。做手机 Web 遥控WiFi 是现成的不用额外加通信模块。遥控方式手机 Web 页面。不写 App不做蓝牙配对手机浏览器打开一个网页就能操控跨平台、零安装。姿态感知IMU惯性测量单元需要做校准。这是飞控的内耳没有它飞机就是瞎子。协议适配MAVLink。这是无人机领域的事实标准协议适配它意味着你的小飞机能和地面站软件对话能看姿态数据、能发指令。飞行模式定高、定点。定高靠气压计或超声波定点靠光流或 GPS小飞机上通常用气压计做定高定点则要看传感器配置。这五条需求串起来就是一台完整飞控的最小可行系统。下面我逐条拆解背后的技术逻辑。1.3 整体架构是怎么搭起来的整机的信号流我画不出图这里也不方便用图但可以用文字描述清楚手机浏览器 → WiFi → ESP32 → 姿态解算 → PID 控制器 → 电机 PWM 输出 → 四旋翼产生升力。同时IMU 数据实时回传给 ESP32形成闭环。这里有个关键设计决策姿态解算和控制在 ESP32 上跑还是把数据传到手机算我选择前者。原因很简单——WiFi 有延迟把控制回路放在远端一旦网络抖动飞机直接失控。ESP32 双核一个核专门跑姿态解算和控制循环另一个核处理 WiFi 通信和 Web 服务分工明确。MAVLink 协议在这里扮演的是对外接口的角色。飞机内部用自己的轻量协议跑控制但对外暴露 MAVLink 格式的数据包这样地面站软件比如 QGroundControl 这类通用工具就能识别它。适配 MAVLink 不是为了炫技而是为了让这台小飞机能融入现有的无人机工具生态。2. 硬件选型与核心细节解析2.1 主控为什么是 ESP32 而不是 STM32很多人做飞控第一反应是 STM32毕竟 Pixhawk 那套就是 STM32 打底。但这个项目我坚决选 ESP32理由有三条每条都踩在成本和学习曲线上。第一WiFi 是刚需。手机 Web 遥控意味着必须有网络通信能力。STM32 要加 WiFi 得外挂 ESP8266 或类似模块多一颗芯片、多一套串口协议、多一份调试工作量。ESP32 直接内置省掉整条链路。第二双核适合分工。ESP32 有两个核心我可以把实时性要求高的控制循环绑在一个核上把 WiFi 协议栈和 Web 服务扔到另一个核。STM32 单核做这件事要么用 RTOS 精细调度要么忍受 WiFi 中断打断控制循环带来的抖动。第三开发体验友好。Arduino 框架对 ESP32 支持成熟WiFi.h、WebServer.h、Wire.h这些库开箱即用。对初学者来说从写第一行代码到看到飞机响应可能只需要一个下午。当然 ESP32 也有短板它的 ADC 精度一般PWM 通道数量有限浮点性能比不上带 FPU 的高端 STM32。但在这个量级的四旋翼上这些短板都不构成瓶颈。2.2 电机、桨叶与机架的搭配逻辑空心杯电机是这类迷你四旋翼的标配。我选的是 720 或 716 规格的空心杯转速高、重量轻、驱动简单——一个 MOS 管就能调速不需要电调。桨叶要和电机匹配。空心杯电机扭矩小桨叶直径太大转不动太小升力不够。我实测下来55mm 到 65mm 的桨叶比较合适具体看电机 KV 值和电池电压。这里有个经验公式升力大致和桨叶直径的平方成正比但扭矩需求和直径的三次方成正比。所以桨叶每大一圈电机负担增加得比升力快盲目加大桨叶反而飞不起来。机架我用的是 3D 打印的十字架结构轴距控制在 65mm 左右。轴距太短桨叶容易打架太长结构强度下降。65mm 这个尺寸四个 55mm 桨叶刚好互不干涉整机重量能压在 30 克以内。注意机架材料别用太软的 PLA炸机时容易断。PETG 或者加纤尼龙更耐摔虽然重一点点但省去了反复打印的麻烦。2.3 IMU 选型与校准的必要性IMU 我用的是一颗六轴传感器三轴加速度计 三轴陀螺仪通过 I2C 和 ESP32 通信。选它的原因是便宜、资料多、Arduino 库成熟。但这里有个必须讲清楚的问题为什么 IMU 一定要校准加速度计测的是比力静止时它感受到的是重力反作用力理论上应该输出一个方向朝上的 1g 向量。但实际芯片有零偏、有刻度误差、有安装倾斜。如果不校准飞控会误以为飞机是斜的然后拼命往一个方向修正结果就是一起飞就翻。陀螺仪测的是角速度静止时理论上应该输出零。但实际有零偏而且零偏随温度漂移。不校准的话姿态角会随时间缓慢漂移飞几十秒后飞机就以为自己歪了。校准分两步加速度计校准把飞机放在水平面上采集多组数据算出零偏和刻度因子和陀螺仪校准静止采集一段时间算出零偏。这两步做完姿态解算的输入才靠谱。2.4 电池与供电的坑迷你四旋翼一般用 1S 锂电池标称 3.7V满电 4.2V。容量选 300mAh 到 500mAh 之间再大就太重了。供电这里有个大坑ESP32 和电机不能共用一路电源。电机启动瞬间电流很大会把电压拉低导致 ESP32 复位。我的做法是电池出来分两路一路直接给电机驱动另一路经过 LDO 稳压到 3.3V 给 ESP32 和 IMU。LDO 要选压差小、瞬态响应好的否则电机一加速ESP32 还是可能重启。实操心得在 ESP32 的电源脚旁边并一个 100uF 以上的电解电容再并一个 0.1uF 陶瓷电容能显著改善电机启动时的电压跌落问题。这个细节很多教程不会讲但实测非常关键。3. 实操过程与核心环节实现3.1 硬件组装与接线顺序组装顺序我建议从下往上先固定电机到机架再装桨叶保护圈如果有然后固定主控板和 IMU最后接电池。接线要特别注意几点电机方向四旋翼对角线上的两个电机转向相同相邻两个转向相反。空心杯电机换向靠调换正负极接线时先别焊死用杜邦线试好方向再固定。IMU 安装方向IMU 的 X 轴要和机头方向一致安装时用记号笔在板子上标好方向装反了姿态解算全乱。电源走线电机线尽量短粗减少压降信号线远离电机线避免干扰。我第一版装机时把 IMU 装歪了 5 度结果飞机悬停时一直往一个方向飘排查了半天才发现是机械安装问题。所以装 IMU 时一定要用水平仪或者目测对齐别嫌麻烦。3.2 ESP32 固件框架搭建固件我分成几个模块IMU 驱动、姿态解算、PID 控制、电机输出、WiFi 通信、Web 服务、MAVLink 打包。用 Arduino 框架写主循环里跑控制WiFi 和 Web 用异步方式处理。核心控制循环的伪代码逻辑是这样的void controlLoop() { readIMU(); // 读取加速度和角速度 updateAttitude(); // 互补滤波或卡尔曼滤波解算姿态 computePID(); // 根据目标姿态和当前姿态算 PID 输出 mixMotors(); // 把 PID 输出混合成四个电机的 PWM writeMotors(); // 输出 PWM }这个循环要跑得足够快我实测至少 500Hz才能保证姿态稳定。ESP32 双核的话把这个循环绑到核心 1WiFi 任务绑到核心 0用xTaskCreatePinnedToCore实现。姿态解算我用的是互补滤波简单可靠。陀螺仪积分得到角度加速度计测得重力方向两者加权融合。权重系数我取 0.98 给陀螺仪、0.02 给加速度计这个比例能让姿态既响应快又不漂移。3.3 手机 Web 遥控页面实现Web 页面我做得极简两个虚拟摇杆左边控制油门和偏航右边控制俯仰和横滚。用 HTML5 的 touch 事件监听手指位置通过 WebSocket 把摇杆坐标发给 ESP32。为什么用 WebSocket 而不是 HTTP 轮询因为轮询延迟高、开销大。WebSocket 建立长连接后数据可以双向实时推送延迟能压到几十毫秒。ESP32 这边用WebSocketsServer库起一个 WebSocket 服务收到摇杆数据后解析成目标姿态角喂给 PID 控制器。这里要注意数据格式要紧凑我用的是简单的 CSV 格式比如0.5,0.3,0.0,0.0解析快、带宽省。注意手机浏览器在后台时会暂停 JavaScript 执行导致摇杆数据停发。所以飞行时手机屏幕要保持常亮别切到其他 App。这个坑我踩过飞机直接失控坠地。3.4 IMU 校准流程与代码实现校准我做成一个独立模式上电后如果检测到特定按键按下就进入校准流程。加速度计校准把飞机放在水平面上采集 500 组数据算出每个轴的均值和标准差均值作为零偏标准差用来判断数据是否稳定。如果标准差太大说明有振动提示重新校准。陀螺仪校准静止采集 1000 组数据算均值作为零偏。采集期间不能碰飞机否则零偏不准。校准结果存到 ESP32 的 NVS非易失存储里下次上电直接读取不用每次校准。// 陀螺仪零偏校准示例 float gyroBias[3] {0, 0, 0}; for (int i 0; i 1000; i) { gyroBias[0] readGyroX(); gyroBias[1] readGyroY(); gyroBias[2] readGyroZ(); delay(2); } gyroBias[0] / 1000; gyroBias[1] / 1000; gyroBias[2] / 1000;3.5 MAVLink 协议适配要点MAVLink 是一套二进制协议有固定的消息格式。我要做的是把飞机的姿态、电池电压、飞行模式等数据打包成 MAVLink 消息通过 UDP 发出去。最常用的几条消息消息名ID用途HEARTBEAT0心跳表明飞机在线ATTITUDE30姿态角roll/pitch/yawSYS_STATUS1系统状态含电压RC_CHANNELS65遥控通道值适配 MAVLink 的难点在于字节序和校验。MAVLink 用小端序每条消息末尾有 CRC 校验。我直接用现成的 MAVLink 库生成消息避免手写打包出错。发出去之后用地面站软件连接 ESP32 的 IP 和端口就能看到飞机的实时姿态了。这一步跑通的时候挺有成就感的——一台 69 元的小飞机居然能被专业地面站识别。3.6 定高与定点的实现思路定高我用的气压计。气压计测大气压换算成高度。但气压计噪声大直接用来控制会抖所以要做滤波——我用滑动平均加低通滤波把高频噪声滤掉。控制逻辑是目标高度和当前高度的差值经过 PID 算出油门修正量叠加到基础油门上。这样飞机就能悬停在设定高度附近。定点就麻烦一些。没有 GPS 和光流的情况下纯靠 IMU 做定点是不现实的——IMU 积分会漂移。我的做法是用 IMU 做短时定点也就是松杆回中时飞机尽量保持位置但时间长了还是会飘。真要稳定定点得加光流传感器或者下视摄像头那就超出 69 元的预算了。实操心得定高模式下气压计要远离桨叶气流。我把气压计用海绵包起来减少气流干扰高度稳定性明显提升。这个技巧是从老玩家那里学来的很管用。4. 常见问题与排查技巧实录4.1 起飞就翻的排查思路这是新手最常遇到的问题原因通常有这几类电机转向错四个电机转向不对升力方向乱。排查方法逐个电机单独给油用手感受风向确认转向符合四旋翼布局。桨叶装反正反桨装错位置。排查方法看桨叶上的标记或者对比升力方向。IMU 方向错姿态解算的坐标系和实际机体不一致。排查方法倾斜飞机看地面站显示的姿态角是否跟着动方向对不对。PID 参数太激进P 太大导致震荡I 太大导致积分饱和。排查方法先把 P 调小能飞起来再慢慢加。我建议的排查顺序是先确认电机转向再确认桨叶再确认 IMU 方向最后调 PID。这个顺序从硬件到软件能快速定位问题。4.2 姿态漂移与振动问题姿态漂移表现为飞机悬停时缓慢往一个方向偏。原因可能是陀螺仪零偏没校准好或者校准后温度变化导致零偏漂移。解决办法一是校准前让飞机静置几分钟等温度稳定二是飞行中如果发现漂移落地重新校准三是用更高级的滤波算法比如卡尔曼滤波能更好地估计零偏。振动问题表现为电机一转姿态数据就乱跳。原因通常是桨叶不平衡或者电机安装松动。解决办法做桨叶动平衡用胶带在轻的一侧配重检查电机螺丝是否拧紧IMU 用减震棉安装。4.3 WiFi 延迟与失控处理WiFi 延迟是这类方案的天生短板。我实测下来局域网内延迟大概 20 到 50 毫秒偶尔会跳到 100 毫秒以上。对于慢速飞行够用但快速机动时会有明显滞后感。失控处理我做了两层保护一是信号丢失自动降落如果 500 毫秒收不到遥控数据飞机自动降低油门缓慢降落二是低电压保护电池电压低于阈值时强制降落避免电池过放。注意WiFi 信道拥挤时延迟会明显增大。飞行前用手机看一下周围 WiFi 环境尽量选一个空闲信道。这个细节能显著提升操控手感。4.4 常见问题速查表现象可能原因排查方法解决措施起飞就翻电机转向错单独给油感受风向调换电机正负极起飞就翻桨叶装反检查桨叶标记正反桨对调姿态漂移陀螺仪零偏静止看角速度输出重新校准姿态抖动振动大摸机架感受振动桨叶动平衡、IMU减震高度不稳气压计受气流干扰观察高度数据波动海绵包裹气压计遥控延迟WiFi 信道拥挤测网络延迟换信道、靠近飞机ESP32 重启电源跌落示波器看电压加电容、分路供电4.5 几个容易被忽略的细节第一个细节是电机怠速。四旋翼解锁后电机应该以最低转速转动而不是完全停转。这样能保证姿态控制有足够的响应余量。怠速值我设的是油门范围的 5% 左右具体看电机和桨叶。第二个细节是PID 输出的限幅。PID 算出来的修正量要限制在合理范围内否则一旦积分饱和飞机会突然大幅动作。我给每个轴的 PID 输出都加了限幅横滚和俯仰限制在正负 30 度对应的输出偏航限制在正负 45 度。第三个细节是解锁逻辑。我做了个简单的解锁动作油门拉到最低方向舵打到最右保持两秒。这样能防止误触导致电机突然转动伤人。安全无小事这个逻辑一定要有。第四个细节是固件版本管理。调参过程中会反复烧录固件我建议每次改完参数在代码里记个注释写清楚改了什么、为什么改。不然调了十几版之后你自己都忘了哪版是什么状态。我用的是简单的版本号加日期比如v1.3_20240115配合注释回溯起来很方便。4.6 从能飞到飞好的进阶方向飞机能稳定悬停之后可以往几个方向继续折腾一是加光流传感器做真正的定点。光流模块能测地面移动配合高度数据能实现无 GPS 的定点悬停。成本会增加几十块但飞行体验提升明显。二是加超声波定高。气压计在低空精度不够超声波在 2 米以内精度能到厘米级。两者融合低空定高会更稳。三是做航线飞行。适配 MAVLink 之后可以发航点指令让飞机自动飞一条预设航线。这就从遥控玩具升级成自动驾驶平台了。四是优化控制算法。把互补滤波换成卡尔曼滤波把单环 PID 换成串级 PID角度环 角速度环飞行品质会有质的提升。我个人觉得这个项目最大的价值不是省了多少钱而是把无人机飞控的每一层都摊开给你看。从传感器读数到姿态解算从 PID 到电机输出从 WiFi 通信到协议适配每一环你都能改、能调、能理解。这种透明度是成品玩具永远给不了的。最后分享一个小技巧调试阶段先把桨叶拆掉只看电机响应和姿态数据。确认控制逻辑没问题了再装桨叶试飞。这样能避免很多因为控制逻辑错误导致的炸机。我前几次炸机都是因为急着装桨叶试飞结果一个参数错误就摔了。后来养成习惯先空转验证再实飞炸机率大幅下降。