☰
从ESP32到OpenMV:复刻开源微型四轴无人机Buzz
2026/11/3 22:29:23 网站建设 项目流程

前些日子整理柜子,翻出一台炸过的小四轴,又让我想起那台嗡嗡叫的小东西。我管它叫Buzz,它不是大厂旗舰,也不是昂贵的开发平台,只是一只用ESP32、OpenMV和几颗超声波传感器攒出来的开源微型四轴无人机。飞行时四个空心杯电机转动的声音很像蜜蜂振翅,所以名字就叫Buzz。玩开源硬件的朋友应该见过Rui放出的这个项目,代码和图纸完全公开,整机成本能压到几百块钱,用来学飞控原理、玩视觉跟随、做仿生小作品都很合适。我前后折腾了两周,炸了三回,最后总算能让它在客厅里稳稳悬停,跟着一个AprilTag标签慢慢移动。这篇文章就把整个复刻过程记录下来,从硬件选型到飞控调参,再到避障与视觉跟随,能帮后来的人少走不少弯路。

1. “Buzz”到底是什么:一台会悬停的电子蜜蜂

1.1 开源项目Buzz的来龙去脉

Buzz这个项目很有意思,名字起得很直白,飞行时那阵恼人又可爱的嗡嗡声就是它最大的特征。项目主控用了ESP32,这是一颗带WiFi和蓝牙的双核芯片,跑飞控的同时还预留了无线通信能力;姿态传感器是MPU6050,六轴IMU,体积小、资料多,几乎所有入门飞控都会用它。视觉部分用OpenMV,一个跑MicroPython的嵌入式摄像头模块,专门做人脸识别、AprilTag定位、颜色追踪这类轻量级视觉任务。再加上两颗HC-SR04超声波传感器,一颗朝下负责定高,一颗朝前负责避障,整个系统就齐了。

市面上同类的小型无人机开发板很多,但Buzz最难得的是“全链路开源”。Rui把飞控代码、接线图、3D打印机架文件、调参建议都放了出来,复刻者不用从零猜原理。实际复刻时我发现,资料的完整性直接决定项目成功率,很多开源项目只给个Demo和几行代码,跟着做很容易卡在某个细节上。Buzz的项目资料里把PID初始参数、传感器安装方向、电机顺序都写得很清楚,照着搭一套框架,再根据自己的硬件微调,两三天就能通电试转。

它的设计定位也不是做一台能航拍的无人机,而是一个低成本教学平台。你可以通过它理解四轴怎么自稳、怎么定高、怎么识别目标,这些能力拆开来看都不复杂,但组合在一起就是一个完整的“电子蜜蜂”系统。对学生、硬件爱好者、刚接触飞控的工程师来说,这比直接上一台大疆或PX4开发套件更容易上手,成本也低一个数量级。

1.2 我为什么花几百块钱自己复刻

最初想复刻Buzz,是因为我想弄明白一个问题:四轴无人机到底是怎么知道自己“歪了”的?MPU6050能测角速度和加速度,但把原始数据变成稳定的姿态角就需要滤波;有了姿态角,怎么让电机输出差异把机身拉平,又需要PID。这些知识在书本上看过很多遍,但只有真正写在代码里、看着波形调参,才会有那种“通了”的感觉。Buzz把这些问题压缩在一个几百块钱的项目里,没有多余的外设干扰,非常契合学习需求。

第二个原因比较私人。家里小朋友对昆虫很感兴趣,我告诉他无人机可以像蜜蜂一样飞起来,还能跟着人走。Buzz做了视觉跟随之后,贴上一个小标签就能让飞机亦步亦趋地跟着移动,演示起来特别直观。客厅里飞低速模式,声音嗡嗡的,孩子兴奋得不行,这种把技术变成可感知体验的过程,比任何概念解释都有说服力。

第三是社区效应。GitHub和Hackaday上复刻Buzz的人不少,有人魔改成了扑翼结构,有人换成了更大的机架,有人把OpenMV换成了K210。这种开源文化让人很有分享欲。我把自己调通的参数和踩坑记录发回社区后,还有人顺着我的方案改出了一版用手机摄像头做视觉的简化版。所以这篇文章也算是给后来复刻者的一份回馈。

2. 硬件选型与成本核算:哪些钱能省,哪些钱不能省

2.1 整机BOM清单与成本预算

复刻Buzz之前,我先把所有零件列了一张表。核心原则是:主控和传感器选主流常见型号,电机和机架按项目推荐来,电源系统宁可靠不省钱。下面是我最终使用的配置和实际花费,单位是人民币,参考2024年前后的行情。

模块型号/规格作用参考价格
主控ESP32 DevKitC V4飞控、通信、逻辑控制30-50元
姿态传感器MPU6050模块陀螺仪+加速度计8-15元
视觉模块OpenMV Cam H7AprilTag识别、目标跟随250-350元
超声波传感器HC-SR04 x2定高+前向避障15-25元
电机720空心杯电机 x4提供升力,配45mm桨40-80元
电机驱动SI2302 MOS管 x4PWM调速10-20元
机架3D打印中心板+碳杆承载所有部件30-80元
电池2S 450mAh锂电整机供电30-50元
降压模块5V/3A BEC给主控和视觉供电10-20元
遥控/上位机手机App或PS2手柄手动油门与方向控制0-60元

总成本大约在450到750元之间。里面最大头的往往是OpenMV,如果你手上刚好有废旧安卓手机,也可以用手机摄像头做视觉识别,再用串口或WiFi把结果发给ESP32,成本能再压一两百元,但开发复杂度会上去。其余部件几乎没有降级空间,ESP32和MPU6050已经是最低成本方案,再便宜就得换STM32F103加蓝牙模块,增加接线难度,反而不划算。

2.2 三个关键替代方案:主控、视觉、电机

复刻过程中我认真考虑过三个替换方向,先说结论:项目推荐什么就用什么,不要轻易换。

主控方面,很多人问能不能用STM32替代ESP32。能用,但不推荐。STM32F103性能足够跑飞控,可它没有板载WiFi,后续想做手机遥控或无线调参就得另接模块。ESP32自带双核240MHz,一个核跑姿态解算和PID,另一个核处理通信和超声波数据,资源分配很舒服。更关键的是Arduino环境下ESP32的外设库非常成熟,读I2C、输出LEDC PWM、串口收发都是现成函数,新手不容易被底层寄存器困住。

视觉模块方面,OpenMX确实贵,但它和ESP32的配合是最顺的。Jetson Nano性能强,但功耗和体积完全不适合这种微型四轴;K210或MaixCam便宜一些,可适配器代码需要重写,而且MicroPython版本的API和OpenMV不完全兼容。我的建议是,如果预算吃紧,先用OpenMV模拟器或电脑摄像头把视觉算法跑通,再决定要不要买真模块。视觉是整个项目里唯一不建议省钱的部件,AprilTag定位精度直接决定了跟随效果。

电机方面,Buzz用的是720空心杯电机。空心杯电机的特点是响应极快、重量轻、价格便宜,非常适合微型四轴。有人想换成无刷电机,觉得寿命长噪音小,但无刷电机需要电调,四个电调的价格和重量都会让这个项目失去“便宜轻巧”的初衷。我的实际经验是,空心杯电机虽然容易磨损,但一块钱到两块钱一个,坏了就换,维护成本极低,对学习用平台来说反而是优点。

2.3 供电与接线的隐藏知识点

接线是复刻时最容易翻车的地方,特别是电源部分。Buzz采用2S锂电,满电电压8.4V,标称7.4V。电机可以直接从电池取电,但ESP32、MPU6050、OpenMV都需要稳定的5V或3.3V,所以一定要在电池后面加一个5V降压模块,再由ESP32板载稳压给MPU6050供3.3V。这里有个关键细节:所有模块的地线必须共地,否则I2C和串口通信会出现莫名其妙的数据错乱,表现起来就是陀螺仪数值跳动、OpenMV偶尔丢包。

我遇到过一个问题:电池电压从8.4V掉到7.0V后,同样的悬停油门会让飞机明显下沉。这是因为空心杯电机转速对电压非常敏感,电压降低,升力跟着降。解决思路有两种:一是用电压监测脚实时读取电池电压,电压每下降0.1V就给基础油门补偿一点;二是干脆用3S电池配稳压,但重量增加不划算。Rui的代码里用的是第一种思路,我也照着做了,实测能明显延长有效飞行时间。

另外,MOS管驱动电路要留意逻辑电平。ESP32的GPIO输出是3.3V,SI2302的栅极阈值电压比较低,可以直接驱动,但如果换用IRLZ44N这类大功率MOS管,就未必能完全导通。我一开始图省事用了一颗手头剩下的大功率MOS,结果电机转速上不去,后来换回SI2302才恢复正常,这也是选型时容易被忽略的坑。

3. 飞控、视觉与避障逻辑:从零调通一台自稳小四轴

3.1 ESP32飞控的姿态解算与控制循环

飞控的核心是循环:读传感器、算姿态、算PID、输出PWM。在ESP32上,我用Arduino框架写了一个简单的定时器中断,控制频率设为200Hz,也就是每5毫秒跑一次主循环。为什么是200Hz?太慢了飞控反应不过来,姿态会明显漂;太快了ESP32忙于中断,串口和WiFi容易卡顿,而且MPU6050的I2C读取速度也跟不上。200Hz是微型四轴里很常见的平衡点。

姿态解算我用了互补滤波,公式不复杂:

// 简化示意,实际需要根据采样时间dt做调用 float dt = 0.005f; gyro_angle += gyro_rate * dt; accel_angle = atan2(accel_y, accel_z) * 180 / PI; // 互补滤波:陀螺仪负责动态,加速度计负责修正漂移 bias = 0.98f; angle = bias * gyro_angle + (1 - bias) * accel_angle;

这个思路可以理解为:陀螺仪的短时数据非常稳,但时间久了会积分漂移;加速度计正好相反,短时间噪声大,但长时间不会偏离真实。互补滤波让两者取长补短,0.98和0.02的分配比例是经验值,根据传感器噪声情况可以微调。如果你的代码里姿态角明显漂移,先检查这个比例,而不是急着改PID。

粒度和数据对齐也很重要。MPU6050有两个数据源:陀螺仪是角速度,加速度计是线加速度。读取时要用相同的I2C总线,并且顺序读取,避免两次读取之间传感器数据已经更新。I2C时钟我设置为400kHz,这是MPU6050支持的快速模式,比默认的100kHz更快,能减少主循环耗时。

3.2 内环角速度、外环角度的两级PID

比姿态解算更重要的是PID结构。Buzz的飞控代码里用了经典的两级PID:外环是角度环,输入期望角度和当前角度,输出目标角速度;内环是角速度环,输入目标角速度和当前角速度,输出电机修正量。为什么要两个环?因为角速度环响应快,能抑制扰动;角度环负责消除误差,让飞机回到目标角度。如果只用一个角度环,飞机会摆动得很厉害,就像用手背托着一根棍子,你只能看到棍子倒了再去扶,永远慢半拍。

调参顺序也有讲究。先把内环角速度环调稳,再调外环角度环。我上手先给了两组大概的初始值:Kp相关参数先给小的,比如内环Kp=0.8,Ki=0.01,外环Kp=2.0,Ki=0.05,然后根据现象微调。如果飞机高频抖动,说明Kp太大;如果缓慢来回晃,说明Ki太大或Kp太小。这个规律我现在已经刻在脑子里了,每次调参都从“不抖”开始,慢慢往上加。

四个电机的输出分配同样关键。X型四轴里,每个电机的输出由三部分叠加:基本悬停油门、俯仰修正、横滚修正、偏航修正。代码里大致是这样:

motor[0] = throttle + pitch_pid + roll_pid - yaw_pid; motor[1] = throttle - pitch_pid + roll_pid + yaw_pid; motor[2] = throttle - pitch_pid - roll_pid - yaw_pid; motor[3] = throttle + pitch_pid - roll_pid + yaw_pid;

具体符号取决于电机布局和安装方向,我当时按Rui的默认脚位接线,飞起来发现横滚方向反了,最后把roll_pid的符号取反才解决。这个细节如果没有意识到,你会以为是PID参数问题,调了半天还是乱飞。

3.3 OpenMV识别AprilTag并让无人机跟随

视觉跟随是Buzz最吸引人的功能。OpenMV跑的是MicroPython,代码逻辑比飞控简单,核心就两步:识别AprilTag得到目标位置,然后通过串口发给ESP32。AprilTag是一种二维码风格的视觉基准标签,OpenMV库函数里直接有支持,识别稳定性和抗干扰能力都比颜色追踪强很多。

我在OpenMV里用的是36h11字典的AprilTag,标签大小为5厘米。为什么不用颜色追踪?颜色追踪太依赖光照,客厅灯光一变,阈值就失效了。AprilTag是黑白图形,只要曝光不过曝或欠曝,识别率非常高。给OpenMV代码做个框架注释,实际使用中还需要根据摄像头角度调节tag_size:

import sensor, image, time, ustruct from machine import UART sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QQVGA) sensor.set_vflip(True) # 根据安装方向调整 sensor.skip_frames(time=2000) uart = UART(3, 9600) # 串口连接ESP32 while True: img = sensor.snapshot() tags = img.find_apriltag() if tags: tag = tags[0] # 返回目标的中心坐标cx、cy,以及距离z(单位cm) cx = tag.cx(); cy = tag.cy() z = tag.z_translation() # 距OpenMV的距离 data = ustruct.pack("<Bhhh", 0xA5, int(cx), int(cy), int(z)) uart.write(data)

关键点是标签在画面中的位置如何转成飞控指令。如果标签中心比画面中心靠左,就说明目标在飞机左前方,此时飞控需要左移或偏航。我把cx和cy映射成期望姿态角,cx偏离越大,期望横滚角就越大;z值决定前向速度,z比期望距离大,说明目标远了,飞机前推;z比期望距离小,飞机后退或悬停。这套逻辑处理完,无人机就能像蜜蜂追花一样跟着标签移动。

OpenMV和ESP32的通信用串口最稳。OpenMV的UART3接到ESP32的RX/TX,注意波特率不要设太高,9600或115200都行,但两边必须一致。我试过用WiFi传数据,延迟大且不稳定,串口实测下来最可靠。另外,OpenMV安装方向会影响坐标轴,安装时让镜头上方朝前,并做一次翻转设置,否则左右会颠倒。

3.4 双超声波协同:定高与避障二合一

超声波模块在这个项目里承担两个角色:朝下的那颗负责定高,朝前的负责避障。HC-SR04的工作原理是发射超声波,记录回波时间,根据声速算出距离。它便宜、方向性弱、响应速度够用,唯一的缺点是容易受到近距离物体和倾斜地面的干扰。

定高逻辑是这样:下超声波每隔50毫秒测一次高度,高度大于75厘米就增加油门,小于65厘米就减小油门,让飞机保持在我们设定的70厘米左右。高度控制不能直接给到油门,最好也走一个单独的PID环,P项负责把高度拉回目标,D项抑制上下振荡。没有D项的话,飞机会像蹦床一样上下晃。

前向避障逻辑就更直白了。超声波测到前方障碍物距离小于40厘米时,飞控把前向速度目标清零,同时给一个后退量,并停止水平跟随动作。这个阈值不是随便定的,太大会导致飞机在空旷房间频繁刹车,太小又可能撞上。我一开始设成50厘米,结果家里客厅里走到窗帘边就自动后退,看着傻乎乎的,改成35厘米后舒服多了。

两个超声波共用一个I2C?不是,HC-SR04是独立触发/回波引脚,所以要用ESP32的GPIO分别控制。避障代码里要小心超声波模块的回波信号是5V电平,ESP32引脚是3.3V耐压,有些模块需要分压或加电平转换。我买的模块宣称兼容3.3V,但为了安全还是加了两个电阻分压,这点经常被忽略。

3.5 联调顺序:桌面、绑绳、脱绳

整个项目里最危险的操作是直接上电飞行。我的调试顺序固定为三阶段,每一阶段都解决一类问题。

第一阶段是桌面测试。四轴不装桨,或者装上桨但压在桌面上,先检查电机转向是否正确、PWM信号是否正常、飞控有没有输出。此时把ESP32接上串口,可以实时看姿态角和PID输出值。我会用手转动机体,观察姿态角是否跟随,如果方向反了就改符号,这是最安全也最容易定位问题的方式。

第二阶段是绑绳试飞。找一根结实的绳子绑在机架中心,另一端固定在地面的重物上,不要太短,让飞机能在半径30厘米的范围内飞起来。这一阶段用来调悬停油门和PID方向。第一次绑绳试飞时,飞机一起飞就往一边猛拉,问题不是PID而是四个电机有一个装反了,换了电机线之后立刻稳住。没有这根绳子,那次可能就直接撞墙了。

第三阶段是脱绳飞行。选择一个至少2米见方的空旷区域,打开低速模式,先只做悬停。确认悬停稳定后再逐步测试超声波定高、前向避障和视觉跟随。切记不要在同一天把新调高的PID参数和新写的视觉逻辑一起测试,变量太多时出了问题很难定位。我习惯一天只改一个变量,宁可多花几天,也不要炸机浪费时间。

4. 常见问题与避坑实录:我炸过的机和修过的板

4.1 高频问题速查表

复刻过程中遇到的绝大多数问题都可以归纳成下面这张表。如果你照着Rui的项目资料搭建,出现了类似现象,可以先对照排查,再考虑改代码。

故障现象可能原因解决方法
上电后电机不转MOS管接线错误或GPIO没输出PWM检查MOS管G极接的引角和LEDC通道设置
单个电机反向电机线焊反对调该电机两根线
起飞后猛往一边跑电机顺序/方向错误,或PID符号反了再次核对电机旋转方向与roll/pitch符号
飞机高频抖动内环Kp过大降低内环Kp,或检查机架是否松动
姿态角缓慢漂移互补滤波系数或陀螺仪零点漂移上电时做陀螺仪零点校准,bias调到0.98以上
视觉偶尔丢目标曝光变化、标签反光、OpenMV安装松动固定标签,调整曝光,检查串口线
超声波数值跳动没加共地、模块朝向倾斜、反射面不平检查GND,安装牢固,设定合理滤波窗口
悬停两三分钟就无力电池电压下降未补偿加电压补偿逻辑,或换容量更大的电池
飞着飞着ESP32重启供电不足或降压模块过热换大电流BEC,检查电源线线径

4.2 三个特别值得反复说的坑

第一个坑是电机和MOS管的接线。空心杯电机没有正负标识,接反了只会反转,不会烧毁,但如果你用颜色线区分,很可能手一抖全焊反。我当时想着电机反正都要转,先把四个焊好,上电后才发现两个正转两个反转。更麻烦的是,反转电机的PWM修正方向也反了,飞控越修正飞机越失控。后来我学乖了,先给每个电机单独接2S电池剪一小段胶带标好转动方向,再统一焊到MOS管输出端。花十分钟做标记,能省下一晚上的排错时间。

第二个坑是PID参数调得太猛。第一次调试时我照着别人的参数直接套用,飞机一通电就像抽风一样乱甩,差点打翻桌上的水杯。后来才知道,别人的机架、螺旋桨、电池电压都和我不同,PID参数不能直接照搬。正确的做法是把所有PID设成很小的初始值,比如内环Kp=0.2,外环Kp=1.0,然后慢慢往上加。每次加20%,直到飞机开始轻微晃动,再退回到上一个稳定值。整个过程无聊但有效,所谓调参高手,只是比别人更愿意做这种重复劳动。

第三个坑是OpenMV的曝光问题。开始我用颜色追踪识别标签,暖光下一切正常;到了傍晚自然光,目标识别率暴跌,飞行器乱转。排查半天发现是OpenMV自动曝光导致标签边缘发白,AprilTag解码失败。最后把OpenMV的曝光模式改成手动,固定曝光值,同时把目标标签打印在哑光纸上,避免反光,问题立刻消失。如果你的视觉项目“前一天好用第二天不好用”,先怀疑光照,再怀疑代码。

4.3 安全起飞前检查清单

写这部分不是因为流程感,是真的差点吃过亏。绑绳试飞阶段我图省事没装桨保护罩,飞机侧翻时螺旋桨直接打到手背,留下一道红印。从那以后,每次起飞前我都按下面这个清单过一遍。

  • 检查四个螺旋桨安装方向是否正确,桨叶有没有明显破损。
  • 确认桨保护罩已经装好,这东西不贵,但能挡住绝大多数意外接触。
  • 在室内或小空间测试时,切换到低速模式,限制最大倾角。
  • 确保周围1.5米内没有人和易碎物品,最好拉起一个小围栏。
  • 戴护目镜,四轴炸机时碎片飞溅,眼睛是最脆弱的部位。
  • 检查电池电量,低于30%就不要飞了,降压会让飞控状态变得极其不稳定。
  • 第一次脱绳飞行前,先重新拧一遍所有螺丝和连接件。

我平时还会在电池输出端串联一个自恢复保险丝,电流异常时自动断开,保护飞控和OpenMV不被烧毁。这个小改动成本不到两块钱,复刻兼职飞控的朋友可以考虑加一个。

把Buzz调通之后,我最大的感受是:看起来炫酷的视觉跟随和避障,拆到底都是传感器数据经过滤波、映射成控制量的过程。ESP32负责猜姿态,PID负责稳定,OpenMV负责认目标,超声波负责量距离,每个模块单独拎出来都是教科书级别的基础知识,但合起来就是一台能嗡嗡飞、能跟着标签跑的电子蜜蜂。复刻过程里我学到最多的不是哪条代码更高级,而是“调参要耐心、验证要逐步、安全要紧记”这三件事。如果后面对外观做魔改,我想给Buzz加上一圈LED呼吸灯,让它更像一只发光的小昆虫。扩展空间还很大,结构不变的话,你还可以在OpenMV上跑更多视觉算法,让它的跟随对象从标签变成人脸。希望这篇记录能帮你把自己的Buzz飞起来。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询