少侠好手艺
概述,飞控传感器包括陀螺仪、GPS、气压高度计等,主要使用串口或I2C传输测量的飞行器姿态、位置数据。输出则主要采用PWM控制舵机或电机电调,也会使用数字接口做简单的通断控制。RP2040的接口可灵活设置为硬串口、软串口或I2C接口,也可以设置为PWM输出口,用作飞控主板是很适合的。本实例中,占用2个硬串口、1个软串口、1个I2C口,接人GPS、LoRa、陀螺仪、气压高度计,以50或100Hz的频率实时采集飞行器姿态数据,以18Hz速率采集GPS位置、速度及气压高度数据,并实时控制数字口或PWM输出,LoRa模块能传输飞行数据至地面站,以及远程定位和搜索飞行器。
1,主板硬件:
使用一块成本7块多的RP2040单片机
2,实例用外设模块:
GPS模块 深圳飞空M10 RC12-BO:18Hz高刷新率,支持UBX格式输出,有直接测速输出
陀螺仪GY95T:响应快,串口输出
气压高度计BMP390:高精度
远程通信LoRa 泽耀科技A39C-T900A30S1a:高传输率
舵机 NEEBRC 3.7G:数字舵机,响应速度较快,能低压3.7V工作
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,如图
设置串口包括指定串口引脚(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),经过简单设置后,可以用函数如XXXXXXXXXadAltitudeM()读取数据,看起来比串口还简单,对初学者还是比较友好的。
5,代码解析
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秒采集和传输一次数据,以达到节能的目的。
本实例是打算应用在火箭上,对体积重量均有限制要求,因此采用了立体布线,将陀螺仪和气压高度计用2.54插针焊在了RP2040上。最上图左边为飞控系统,右边为地面接收站,屏幕显示实时传回的数据。调试时天线打了两个圈,不然无线电发射功率有点大,数据传输会受到干扰出错。
最终火箭应用实例的成品如下图,从上至下依次为GPS(要放在最上面接收卫星信号),陀螺仪、气压高度计、RP2040飞控主板、LoRa、锂电池。含电池重量29.5g,可以装入内径40mm长度40mm的箭体电子仓内。
[修改于 9天2时前 - 2025/07/03 21:51:32]
使用树莓派的目的是降低制作门槛,但纯手工焊接又抵消了这一点,还是建议打一块pcb板把成品电路焊上去。
其他东西问题不大,但天线不是找根线焊上去就“能用”的东西。
这个还是起于Arduino生态,只是RP2040确实性能碾压同价位arduino单片机,arduino编程环境对初学者是比较友好的。
做PCB的话可能直接上芯片布线,如果已经全是现在这种模块,画PCB板还是有点尴尬,就是几个插座插针。具体到我目前需求,还考虑过焊插座
都焊好了,可以插线连接,后来还是觉得直接焊线简洁。我焊工好觉得就几根线还挺简单的,做PCB就有点啰嗦,也许有其他爱好者可以贡献PCB版的。
天线也是比较局限,需要窝在伞仓和头锥里的,可以实测优化一下。
200字以内,仅用于支线交流,主线讨论请采用回复功能。