文号
945272
阅读
8345
回复
20
收藏
31
所有教程由网友发布,仅供参考,请谨慎采纳。科创不对教程的科学性、准确性、可靠性负责。
开源RP2040飞控主板
2025/07/03
IP:北京
摘要:本文在一块RP2040单片机上,同时接人GPS、陀螺仪、气压高度计,控制多通道开关及PWM输出,可以实现火箭开伞控制、飞行姿态控制,还接人了LoRa实现飞行数据实时回传及远程定位。软件兼容Arduino开源生态,可按需增减模块、修改控制参数,代码经过优化,初学者友好。

概述,飞控传感器包括陀螺仪、GPS、气压高度计等,主要使用串口或I2C传输测量的飞行器姿态、位置数据。输出则主要采用PWM控制舵机或电机电调,也会使用数字接口做简单的通断控制。RP2040的接口可灵活设置为硬串口、软串口或I2C接口,也可以设置为PWM输出口,用作飞控主板是很适合的。本实例中,占用2个硬串口、1个软串口、1个I2C口,接人GPS、LoRa、陀螺仪、气压高度计,以50或100Hz的频率实时采集飞行器姿态数据,以18Hz速率采集GPS位置、速度及气压高度数据,并实时控制数字口或PWM输出,LoRa模块能传输飞行数据至地面站,以及远程定位和搜索飞行器。

1,主板硬件:

使用一块成本7块多的RP2040单片机

image.png

2,实例用外设模块:

GPS模块 深圳飞空M10 RC12-BO:18Hz高刷新率,支持UBX格式输出,有直接测速输出

image.png


陀螺仪GY95T:响应快,串口输出

image.png


气压高度计BMP390:高精度

image.png


远程通信LoRa 泽耀科技A39C-T900A30S1a:高传输率

image.png

舵机 NEEBRC 3.7G:数字舵机,响应速度较快,能低压3.7V工作

image.png

3,连线:

3.1 电源,所有模块及RP2040的Vcc并联接在一起,GND也连在一起,调试时由RP2040的Type-C插电脑供电,脱机使用时Vcc并联点与GND并联点分别接单节锂电池正负极,可串电源开关。如使用舵机,因其电流较大,其正负极应单独接线连锂电池正负极;

3.2 GPS模块,左数(按上图放置的情况下)第一根线红色为数据输出线,接RP2040第5脚(GP05),左数第2根黑线为数据输入线,接RP2040 GP05,左数第3黄线、4号绿线分别为Vcc和GND。对应由硬串口2代码Serial2控制。模块还剩2根线为磁罗盘数据线,悬空不用。程序都使用查询方式,因此接好这4根线后,即使还没有接好别的模块,也可以试着运行程序,应该可以在串口监视器里看到GPS数据,在室内无卫星信号的情况下,卫星数为0,其他数值也是0,程序能正常运行。放到窗户外或室外,等上二十几秒就能看见卫星数增加,获得当地经纬度等数据。

3.3 陀螺仪,TD、RC脚分别接RP2040 GP02、03脚,由程序setup中的软串口GYSerial控制。同样,接人陀螺仪模块后,重新插电就能看到测量的姿态数据。

3.4 LoRa,RXD、TXD分别接RP2040 GP0、1脚,由程序setup中的硬串口Serial1控制。

3.5 气压高度计,SDA及SCL分别接RP2040 GP08、09脚,对应setup的I2C接口。

3.6 舵机,黄色控制线接RP2040 GP14-17任意一脚,由代码analogWrite输出PWM信号控制。

3.7 数字输出,可接其余任意引脚,控制三极管、MOS开关模块等执行通断动作。

4,通信基础,串口通信使用Serial1、Serial2、XSerial这一类函数。RP2040有两个硬串口UART1和URAT2,由Serial1和Serial2函数控制,每个硬串口可以在给定的两组引脚中选定两个引脚,如串口1可以选0、1或12、13,如图

Screenshot_20250627_224428.jpg


设置串口包括指定串口引脚(RX、TX),设置通信速率(115200)等。使用时,在主循环loop中查询是否该串口有数据,如果有数据则依次每次读取一个8位二进制数据。不同设备或模块的串口数据有特定的数据头,比如陀螺仪GY95T的数据头是0xA4、0x03,而GPS的数据则总是以0xB5、0x62开头。对读取的前两个数据进行判断,符合该设备的数据头再依次读取后边的传感器值,通常每个测量值由读取的3个或4个8位二进制数据组成,经过简单8位移(或x256)加和得到测量值。

除这两个硬串口外,还可以使用软串口SoftwareSerial,可以选定任意两个引脚做软串口的数据收发脚RX和TX使用,具体使用方面与硬串口没什么差别,见附件代码。

串口输出应该是最简单的数据通信模式了,有的模块没有串口输出,只有I2C和SPI,I2C也是只占用2个管脚,与串口的区别在于使用的函数不一样,要使用到打包的库函数wire.h,每个模块有一个特定地址,所以可以多个模块并接到RP2040同样两个管脚上,单次只对某个地址的模块读数。本实例中气压高度计就没有串口输出,使用别人编好的开源代码(DFRobot_BMP3XX.h),经过简单设置后,可以用函数如sensor.readAltitudeM()读取数据,看起来比串口还简单,对初学者还是比较友好的。

5,代码解析

attachment iconGPS_GY_H_2040_LoRa_Sv.txt5.47KBTXT72次下载

5.1,首先#include各种库*.h,主要是RP2040兼容Arduino的库,也有气压高度计的库。别的模块也是可以用库的,也就是别人编好的代码函数,不过在本实例看来必要性不大,串口模式的话直接读就很简单了,如果使用多个串口模块,其代码都是一样的。

5.2,设置,包括气压高度计函数定义,地址设定。还有测量数据名、类型定义,SoftwareSerial GYSerial(2,3)定义了一个软串口的名称及管脚,用于陀螺仪数据连接。进入setup设置函数,设置12-17为数字输出口,定义PWM频率和分辨率。然后设置了两个硬串口管脚,注意GPS的硬串口还要设置一个较大的FIFO,否则数据偶尔会出错,然后启动几个串口。setup中还设置了I2C引脚(8,9),并设置初始海拔高度。

5.3,主循环,陀螺仪软串口GYSerial和GPS硬串口Serial1都采用查询方式,如果数据没准备好就跳过,因此陀螺仪将会以50Hz速率读GY串口,因为它的初始设置是50Hz发一次数据,这个速率也是可以根据说明书来设置的。而GPS速率只有18Hz,气压高度计在高精度读取时差不多也是20几Hz,本实例中把气压高度计的读取放到了GPS串口读取中,因此GPS和气压高度计会以18Hz速率读出。串口打印Serial输出数据到电脑,会看到每2-3次GY数据后会跳出一个GPS和高度数据,因为50Hz差不多就是18Hz的2-3倍。注意每个读数都要加一个100us左右延迟,以匹配串口速率,不然数据会出错。

5.4,串口读数,如上述第4节所述,串口读数首先查询是否有数据,然后读取两个数据看看是不是正确的数据头,然后再用一个for循环批量读取数据到buf数组。

5.5,测量数据生成,根据GY95T模块说明书及GPS的UBX数据协议,不同测量数据在串口数据不同位,找到这些位对应的数组索引,就可以通过位移将高8位、低8位,甚至4个8位二进制数合成一个测量数据。

5.6,PWM控制输出,对于姿态控制,可以设置简单的PD反馈,也就是将姿态陀螺仪的角度和角速度各自乘反馈系数,转换成整型数后放到analogWrite值,不同飞行器用途需要线性组合姿态角进行控制,都是需要自己根据用途设置及调参的。对于开伞这一类简单控制,只需要设置开伞条件,如下降速度大于5m/s,启动给定管脚数字输出即可。

5.7,LoRa远程数据传输,基本原理见之前的帖子,在本实例中不是直接传送GPS所有原始数据,而是选取几个关键数据传输,这样可以减少数据量。在飞行器落地后,还可以在主循环中加delay,设置成每1秒甚至10秒采集和传输一次数据,以达到节能的目的。

IMG_20250703_204137.jpgIMG_20250703_204018.jpgIMG_20250703_204045.jpg

本实例是打算应用在火箭上,对体积重量均有限制要求,因此采用了立体布线,将陀螺仪和气压高度计用2.54插针焊在了RP2040上。最上图左边为飞控系统,右边为地面接收站,屏幕显示实时传回的数据。调试时天线打了两个圈,不然无线电发射功率有点大,数据传输会受到干扰出错。

最终火箭应用实例的成品如下图,从上至下依次为GPS(要放在最上面接收卫星信号),陀螺仪、气压高度计、RP2040飞控主板、LoRa、锂电池。含电池重量29.5g,可以装入内径40mm长度40mm的箭体电子仓内。

IMG_20250703_212814.jpg

[ 修改于1年4个月前 - 2025/07/03 21:51:32 ]
+1
科创币
过氧化氢
2025/10/14
内容好
1年4个月前IP:广东
945275
1楼

少侠好手艺

引用
评论
1
1年4个月前IP:广东
945276
2楼

使用树莓派的目的是降低制作门槛,但纯手工焊接又抵消了这一点,还是建议打一块pcb板把成品电路焊上去。

其他东西问题不大,但天线不是找根线焊上去就“能用”的东西。

引用
评论
3
Tangshm作者
1年4个月前IP:北京
945285
3楼

这个还是起于Arduino生态,只是RP2040确实性能碾压同价位arduino单片机,arduino编程环境对初学者是比较友好的。

做PCB的话可能直接上芯片布线,如果已经全是现在这种模块,画PCB板还是有点尴尬,就是几个插座插针。具体到我目前需求,还考虑过焊插座

IMG_20250704_073846_edit_520572631247128.jpg

都焊好了,可以插线连接,后来还是觉得直接焊线简洁。我焊工好觉得就几根线还挺简单的,做PCB就有点啰嗦,也许有其他爱好者可以贡献PCB版的。

天线也是比较局限,需要窝在伞仓和头锥里的,可以实测优化一下。

引用
评论
1年3个月前IP:广西
945756
4楼

Screenshot_20250722_211916.jpg

这里似乎有一个字的错误


引用
评论(1)
Tangshm作者
1年3个月前IP:北京
946016
5楼

没地方放火箭,今天测试了土办法抛射,用橡皮筋能将模块抛至45米高下落(气压计实测),陀螺仪加速度计实测最大加速度20g(时间0.1s)。GPS没有锁死,不过上升段GPS速度数据延迟了0.5s以上,下降段速度数据延迟小一些。高度数据更是延迟得厉害,也不准确,几乎没法看。推测大机动下这种民用GPS信号需要较长时间重新锁定,另外测试时两面都靠着墙,只有5颗星,也是个不利因素。至少短时大过载下GPS没有锁死,长时间加速的情况只能等有机会上箭测试了。

引用
评论
11个月6天前IP:江苏
947873
6楼

论坛里的飞控还停留在大锅熬大药阶段,,,居然那么多人还在用arduino,令人咋舌


引用
评论
11个月6天前IP:江苏
947874
7楼

有点好笑了,,虽然两年前我也在造这种shit,不过现在一看到论坛里这种一个.txt就把整个工程复制过来了就有点想笑


引用
评论
Tangshm作者
11个月6天前IP:北京
947886
8楼
引用小叮当0312发表于7楼的内容
有点好笑了,,虽然两年前我也在造这种shit,不过现在一看到论坛里这种一个.txt就把整个工程复制过来了就有点想笑

啥情况?是Arduino还是单片机让你觉得好笑?你觉得不好笑的飞控是stm32做板子还是直接用现成飞控板?

引用
评论
11个月2天前IP:江苏
947924
9楼
引用Tangshm发表于8楼的内容
啥情况?是Arduino还是单片机让你觉得好笑?你觉得不好笑的飞控是stm32做板子还是直接用现成飞控板?

在我看来,arduino开发环境连嵌入式的门槛也没有够到

引用
评论
Tangshm作者
11个月1天前IP:北京
947933
10楼
引用小叮当0312发表于9楼的内容
在我看来,arduino开发环境连嵌入式的门槛也没有够到

你这属于是显摆心态了吧,网上有不少讨论arduino、树莓派、stm32各自适用场合的,即使不考虑学习成本,也要根据技术需求理性选择。另外,RP2040在性能有很大提升,兼容arduino,可以覆盖更多的应用,像这种飞控用传统arduino跑起来是很吃力,RP2040就很轻松。

再说个例子,呐我30年前就会8051、8098,就会画PCB,但是后边20年虽然经常做电路却再没画过PCB,高温导线直接在实验板上搭,调试灵活、效率高。因为我现在的工作是搞研究啊,又不是搞研发的,更不是搞产品开发的,关键都挺忙的,怎么顺手怎么来呗。

引用
评论(1)
3
10个月21天前IP:广东
948052
11楼

天线最好还是建议修改一下,随意拉条导线对通信的影响还是比较大的。可以试试使用成品的fpc天线,重量不大,而且方便布置

引用
评论
Tangshm作者
10个月16天前IP:北京
948112
12楼

够呛,小弹簧小辣椒天线反正很差,FPC就是个压扁的小弹簧

引用
评论
10个月13天前IP:四川
948129
13楼

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

那条白色的线线是信号线吗?

引用
评论
Tangshm作者
10个月11天前IP:北京
948151
14楼
引用zx-109633发表于13楼的内容
https://img.kechuang.org:81/r/372931?c=resource那条白色的线线是信号线吗?

天线吧,长长的那根

引用
评论
10个月6天前IP:中国
948248
15楼
引用Tangshm发表于10楼的内容
你这属于是显摆心态了吧,网上有不少讨论arduino、树莓派、stm32各自适用场合的,即使不考虑学习成本,也要根据技术需求理性选择。另外,RP2040在性能有很大提升,兼容arduino,可以覆盖更...

仅仅是拿“学习成本”来支持用arduino来开发,不觉得显著拉低论坛的嵌入式技术等级吗,我看这科创也是世风日下,连这种毫无技术等级的东西都能够被纳入精选文章列表


引用
评论
Tangshm作者
10个月5天前IP:中国
948257
16楼
引用小叮当0312发表于15楼的内容
仅仅是拿“学习成本”来支持用arduino来开发,不觉得显著拉低论坛的嵌入式技术等级吗,我看这科创也是世风日下,连这种毫无技术等级的东西都能够被纳入精选文章列表

哦,你是希望大家要么就是专业板正的“嵌入式”,要么就别碰单片机。这想法,嗯不太想去评论了~

引用
评论
9个月29天前修改于 9个月29天前IP:四川
948417
17楼
引用小叮当0312发表于15楼的内容
仅仅是拿“学习成本”来支持用arduino来开发,不觉得显著拉低论坛的嵌入式技术等级吗,我看这科创也是世风日下,连这种毫无技术等级的东西都能够被纳入精选文章列表

精选是因为该方案能解决实际问题,有较为彻底的开源,并且文章写得足够细,有可操作性。

这并不是一个探讨嵌入式开发的文章,因此不适用于从嵌入式开发技术方面去评判。同时,作者选取专业分类时是有错误的,将电子学专业作为主分类,被鄙视也十分正常,现已调整到火箭相关专业。

arduino长期以来总是被“正统的”嵌入式群体所鄙视,但不妨碍它在商业和普及上的成功。实际上高通的收购即便在arduino圈子内部也引起了不小的争议。

KC曾为爱好者开发过正经的遥控点火器,投入研发成本十几万,截至停产下架,产品总营业额一万多点,这就是正经的代价。

如果您有什么解决办法,不妨做出自己的贡献。

引用
评论
9
Tangshm作者
6个月5天前IP:北京
949827
18楼

GPS串口通讯代码有更新,使用标准GPIO串口通讯函数uart及中断。单片机主频降至66.5MHz,在集成度高的情况下减少对GPS干扰。下面是读取日期时间及卫星数的例程:

#include <hardware/clocks.h>

#include "hardware/uart.h"

#include "hardware/irq.h"

uint16_t Yr;

uint8_t SA,Mt,Dy,Hr,Mn,Sd;

unsigned char GPS_buf[75];


void setup() {

set_sys_clock_khz(66500,true);

//使用Uart0串口及中断读GPS

uart_init(uart0, 115200); // 初始化 UART

gpio_set_function(12, GPIO_FUNC_UART); // 设置 GPIO 引脚为 UART 功能(例如 GP12 作为 TX,GP13作为 RX)

gpio_set_function(13, GPIO_FUNC_UART);

gpio_pull_up(13); // 确保 RX 引脚上拉,避免悬空输入

uart_set_irqs_enabled(uart0, true, false); // 启用 UART 中断,读数中断,写数不中断

irq_set_exclusive_handler(UART0_IRQ, GPS_Read); // 设置GPS读数中断处理函数

irq_set_enabled(UART0_IRQ, true); // 启用串口中断

delay(1000);

}

// GPS读数中断函数

void GPS_Read() {

while (uart_is_readable(uart0)) {

uint8_t ch = uart_getc(uart0); // 读取一个字

if (ch==0xB5){

ch = uart_getc(uart0); // 读取一个字

if (ch==0x62){

uint8_t msgClass = uart_getc(uart0);

uint8_t msgId = uart_getc(uart0);

uint8_t length = (uart_getc(uart0));

if (msgClass 0x01 && msgId 0x07) { // NAV-POSLLH消息

for(uint8_t i=0;i<73;i++){

GPS_buf[i] = uart_getc(uart0);

}

Yr = (GPS_buf[6]<<8)|GPS_buf[5];

Mt = GPS_buf[7];

Dy = GPS_buf[8];

Hr = GPS_buf[9]+8;

Mn = GPS_buf[10];

Sd = GPS_buf[11];

SA = GPS_buf[24];

}

}

}

}

}

引用
评论
6个月4天前IP:广东
949834
19楼
引用小叮当0312发表于6楼的内容
论坛里的飞控还停留在大锅熬大药阶段,,,居然那么多人还在用arduino,令人咋舌

最新的公版betaflight加入了对RP2350的支持,老的RP2040也有个madflight的项目支持

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

rp2350a才6块钱一片,成本优势很大,不过不清楚这6块钱一片的是博通原厂原版的还是晶圆厂偷偷封装出来卖的


别小看arduino,俄乌战场上那些花天价按照正规军标MIL-STD流程开发的武器被开源项目+华强北物料+3D打印机+嘉立创的制造的东西吊着打,科技已经换代了

引用
评论
Tangshm作者
6个月4天前IP:北京
949838
20楼

芯片就是很便宜,RP2040两块多钱一片!低成本、模块化、可移植性,确实可以产生决定性优势

引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的