STM32小四轴超低成本方案开源项目

2023-05-16

先分享几个小四轴无人机项目

新唐M452飞控开源项目,虽然完全开源但是还不够成熟,PID调节感觉还有些问题

 助你轻松DIY四轴飞行器——新唐M452飞控套件评测 - 电路城

MWC 飞控,采用arduino编程,方案比较成熟,对创客教育很友好,以后做scratch也方便,但是成本比较高

MWC(1) Multiwii 飞控程序初学者概要_明年暑假升初中的博客-CSDN博客_mwc飞控

Crazepony 采用STM32成本比较低,方案也比较成熟,下面的方案基本上是基于Crazepony修改的

Crazepony四轴飞行器

此项目定位是低成本,只作为玩具或课堂教学使用,下面是正题

硬件组成

  • 主控:STM32f103T8U6
  • 姿态传感器:MPU6050(3加速度+3角速度)
  • 无线通信协议:XN297
  • 电机驱动:SI2302场效应管
  • 外部接口:标准mircoUSB接口
  • 电机:Coreless高速电机 3W转/分钟
  • 桨叶:46mm黑色正反桨
  • 电池:3.7v动力锂电池

主控和Crazepony相同,STM32程序大框架可以直接使用;

去掉了电子罗盘,电子罗盘作用主要体现在yaw角,实测温漂一分钟也只有几度,在可接受范围;

RF使用国产芯片,仅需一块多,性能相比NRF24L01并不差;

去掉CP2102,作为玩具是不需要的,如果作为学习可以考虑留串口接口,使用CH340做电平转换,留下的串口接口也方便以后外置蓝牙、WiFi等模块;

原理图解析

最小系统

STM32的最小系统一般包括:复位电路,外部时钟电路,启动模式选择电路,电源退偶电路等

 复位

查阅意法半导的官方手册可以知道,STM32系列单片机都是低电平复位。于是采用如图的主流复位电路作为主控的复位电路。

外部时钟

外部时钟我们采用的是8M无源晶振。单片机内部做倍频,系统时钟最高可达到72M。

启动模式

STM32的启动模式分为三种,可以下面的表格给出:

电源退偶

不仅是主控最小系统需要对电源退偶,所有的数字电路和模拟电路共存的系统,都需要对电源退偶。电源退偶,说直接一点就是将电源上的噪声电压引入到地平面,让电源电压保持在一个稳定的值,这样系统才可能稳定工作。怎么做呢?用一个大电容并联一个小电容。

我们都知道,电容对频率越高的信号,呈现低阻特性,对直流呈现高阻特性。那么电源上的噪声对地平面而言,就是一个交流信号,交流信号就能通过电容到达地平面,而电源是一个直流,电容对他呈现出无限大的阻力,无法通过。这样,我们用示波器就可以看到,加了退偶电容的电源会比没加退偶电容的电源,波形要稳定得多。

系统电源

市面上所有的航模动力电池,都是3.7V的标称值,比此电压高的电池,都是几个3.7V的电池串联起来的。

没错,电源就只有一个稳压,没有升压,充电有外置充电线,成本和重量进一步减少,但是稳压到3.3V是不行的,关键就是稳压到2.8V,往下往上都有可能造成不稳定,这样即使四个空心杯转起来也不会造成死机。

姿态传感器

采用的是最常用的MPU6050陀螺仪加速度计一体芯片,对小四轴来说,它的精度和性能绰绰有余了,气压计FBM320用于定高,实际可以不使用。

电机驱动

每个场效应管接一个大电阻下拉,目的是为了防止在单片机没接手电机的控制权时,电机由于PWM信号不稳定开始猛转。接一个下拉电阻,保证了场管输入信号要么是高,要么是低,没有不确定的第三种状态。那么电机也只有两种状态,要么转,要么不转。主控输出的是PWM波形,用于控制场效应管的关闭和导通,从而控制电机的转动速度。

2.4G 通信

 相比Crazepony的NRF24L01,XN297价格低很多

LED灯

作为小孩子使用的无人机,LED当然少不了,除了一个电源指示灯,还有四个灯分别代表四个马达,甚至可以在飞行中做个流水灯效果 。

软件框架解析

遥控器及通讯协议

项目的遥控器使用的是JJ的一款遥控器,价格不到十块钱,但是通讯协议未知,拿到样品之后,用逻辑分析仪解析通讯协议,具体方法《一个无线遥控通讯协议破解实例》,拿下了这个遥控器。

遥控器的RF芯片是SPI通讯,当时做的时候截了两张图

 

取出通讯协议如下,连同配置方式也一起取出来 

20 0C            //使能CRC
21 00            //信号设置 增强型    
22 01            // Enable Pipe0
23 03            // address witdth is 5 bytes    
24 00            //信号设置 增强型
25 00            //初始化时的频率通道DEFAULT_CHANNEL    
26 3F            //发射功率 通信速率
28 00            //传输状态寄存器
29 00            //数据读取寄存器    
31 0F            //数据宽度PAYLOAD_WIDTH    
3C 00            //DYNPD配置
3D 20            //FEATURE配置 byte模式
50 73
39 01            //载波通讯设置Dem_cal_data
3A 45 21 EF 2C 5A 50    //载波通讯设置RF_cal2_data
3B 0B DF 02        //载波通讯设置Dem_cal2_data
3E F6 37 5D        //载波通讯设置RF_cal_data
3F 0A 6D 67 9C 46    //载波通讯设置BB_cal_data
2A 00 00 00 00 00    //ID设置TX_ADDRESS_DEF
30 00 00 00 00 00    //ID设置TX_ADDRESS_DEF
FD 00

20 8C    //不使能IC,设置为发送端

27 70    //置位状态    
E1 00    // CLEAR TXFIFO
20 8E    //设置为发送端
A0 A4 72 53 41 0B 11 3C 49 1B 31 86 BB C9 AE 4F        //数据发送

07 FF    //置位状态
27 FF    //置位状态
E1 00    // CLEAR TXFIFO

07 2E    //置位状态
27 2E    //置位状态
E1 00    // CLEAR TXFIFO
A0   A4    72 53 41 0B 11     3C 49 1B 31    86 BB C9 AE 00
   |包头| |       ID地址      | |    通道    | |
A0     00   72 53 41 0B 11     3C 49 1B 31    86 BB C9 AE 00

30 72 53 41 0B 11    //ID设置TX_ADDRESS_DEF

07 2E    //置位状态
27 2E    //置位状态
25 3C    //使用的频率通道DEFAULT_CHANNEL    
E1 00    // CLEAR TXFIFO
A0 A5 F7 00 00 7E 03 7D FA 7C 0E 7E 0D C9 AE 20
\A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0D C9 AE 16

07 2E    //置位状态
27 2E    //置位状态
25 49    //使用的频率通道DEFAULT_CHANNEL    
E1 00    // CLEAR TXFIFO
A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0D C9 AE 16

07 2E    //置位状态
27 2E    //置位状态
25 1B    //使用的频率通道DEFAULT_CHANNEL    
E1 00    // CLEAR TXFIFO
A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0D C9 AE 16

07 2E    //置位状态
27 2E    //置位状态
25 31    //使用的频率通道DEFAULT_CHANNEL    
E1 00    // CLEAR TXFIFO
A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0D C9 AE 16

A0 A5 F7 00 00 7E 03 7D FA 7C 03 7E 0D C9 AE 15
A0 A5 F7 00 00 7E 03 7D FA 7C 03 7E 08 C9 AE 10
A0 A5 F7 00 00 7E 03 7D FA 7C 03 7E 0B C9 AE 13
A0 A5 F7 00 00 7E 03 7D FA 7C 03 7E 0C C9 AE 14
A0 A5 F7 00 00 7E 03 7D FA 7C 10 7E 0E C9 AE 23
A0 A5 F7 00 00 7E 03 7D FA 7C 0A 7E 0E C9 AE 1D
A0 A5 F7 00 00 7E 03 7D FA 7C 07 7E 0E C9 AE 1A
A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0D C9 AE 16

A0 A5 F7 00 00 7E 03 7D FA 7F FC 7E 0D C9 AE 11    //油门 31744->7C00 +1023 2^15=32767->7FFF
                            ̄ ̄ ̄
A0 A5 F7 00 00 7E 03 7D FA 7C 04 7F FE C9 AE 08 
A0 A5 F7 00 00 7E 03 7D FA 7C 03 7C 00 C9 AE 06 //油门左右31744->7C00 +512 32256->7E00 +1023 32767->7FFF
                                  ̄ ̄ ̄
A0 A5 F7 00 00 7C 00 7D F9 7C 03 7E 0E C9 AE 10
A0 A5 F7 00 00 7F FE 7D F9 7C 03 7E 0E C9 AE 11 //方向左右 31744->7C00 +512 32256->7E00 +1023 32767->7FFF
                ̄ ̄ ̄
A0 A5 F7 00 00 7E 03 7F FC 7C 04 7E 0E C9 AE 1B
A0 A5 F7 00 00 7E 03 7C 00 7C 04 7E 0E C9 AE 1C //方向上下 31744->7C00 +512 32256->7E00 +1023 32767->7FFF
                      ̄ ̄ ̄
A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0E C9 AE 17
A0 A5 F7 00 00 7E 38 7F FC 7C 04 7E 0E C9 AE 50 //方向按键
                                              ̄
A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0E C9 AE 17
A0 A5 F7 01 00 7E 03 7D FA 7C 04 7E 0D C9 AE 17 //油门按键
          ̄
以下按键非点动
//A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0E C9 AE 17 
A0 A5 FA 00 00 7E 03 7D FA 7C 04 7E 0E C9 AE 1A //k1    灵敏度
        
//A0 A5 FA 00 00 7E 03 7D FA 7C 03 7E 0E C9 AE 19 
A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0E C9 AE 17 //k2    灵敏度
        
A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0E C9 AE 17 
A0 A5 F7 00 00 7E 03 91 FA 7C 04 7E 0E C9 AE 2B //k3    前
                      ̄ ̄ ̄                      ̄    
A0 A5 F7 00 00 7E 03 7D FA 7C 04 7E 0E C9 AE 17 
A0 A5 F7 00 00 7E 03 69 FA 7C 04 7E 0E C9 AE 03 //k4    后
                      ̄ ̄ ̄                      ̄    
A0 A5 FA 00 00 7E 03 7D FA 7C 04 7E 0E C9 AE 1A 
A0 A5 FA 00 00 66 03 7D FA 7C 03 7E 0E C9 AE 01 //k5    左
                ̄ ̄ ̄                           ̄                         
A0 A5 F7 00 00 AE 03 7D FA 7C 03 7E 0E C9 AE 46 
A0 A5 F7 00 00 CA 03 7D FA 7C 04 7E 0E C9 AE 63 //k6    右

遥控器在配对上采用先ID  0广播,再发送遥控器ID进行配对,在后面编写的时候也使用相同方式。

飞控软件流程图

软件流程如下图所示:

主控使用的是STM32芯片,没有上实时操作系统,依靠中断嵌套来完成整体功能。程序核心就是通过定时器,在主循环中通过不断查询判断各个条件,这样就产生了几个大小不一样的时间段,我们根据需要就可以完成以多大的频率扫描一次遥控器指令、多久更新一次传感器数据、多久更新一次控制等等飞控需要实现的功能,尽可能的利用主控的资源。

初始化

进入主函数之后就是STM32处理器及各个部分的初始化。

接下来就是进入主循环while(1)之中了,主循环也就是整个程序功能实现的关键,程序进入这里面就循环在里面运行了,当然中断会打断去运行中断服务程序运行完之后再回到这里运行。

主循环-100Hz循环

主循环体中首先有if(loop100HzCnt >= 10){}这个结构,其中loop100HzCnt这个变量是在TIM4中断服务程序中累加的,1ms累加一次,也就是说定时每10ms就去完成一次其中的工作。

那么100Hz需要做一次的工作是什么呢?读取mpu6050数据,气压计数据并进行整合。因为采用软解姿态,读取的数据为加速度计和陀螺仪的AD值,将数据进行标定、滤波、校正后通过四元素融合得到三轴欧拉角度。如下图。

加速度传感器采集数据容易失真,造成姿态解算出来的欧拉角错误,只用角度单环情况下,使系统很难稳定运行,因此可以加入角速度作为内环,角速度由陀螺仪采集数据输出,采集值一般不存在受外界影响情况,抗干扰能力强,并且角速度变化灵敏,当受外界干扰时回复迅速增强了系统的鲁棒性。

采用双闭环PID控制,如下图所示。

角度作为外环,角速度作为内环,进行姿态双环PID控制。角度环的输出值作为角速度环的输入建立自稳系统。

主循环-50Hz循环

if(loop50HzFlag){}进入50Hz(20ms执行一次)循环。loop50HzFlag标志位是在TIM4中断中每20ms置位一次的,这里解析了收到的遥控器无线发送过来的指令,结合当前的姿态计算更新这些控数据给核心控制算法输出控制飞控,我们就可以控制飞控前进后退,上升下降等等操作了。如下图。

主循环-10Hz循环

同样的思路if(loop10HzFlag){}也就是以10Hz的频率去执行下面功能。在这里可以通过蓝牙向我们的手机APP传送一些飞控的姿态信息,然后查询飞控的电量没有足够的话就让飞控降落下来,查询高度啊超出可控范围也把飞控降下来,查询是否和遥控器失联啊,失联就降下飞控等等安全飞行的控制。如下图

最后就是if(pcCmdFlag)这个了,这是一个与上位机调试有关的东西,主循环查询这个标志位,标志位是由上位机发送过来的指令置位的,它主要是处理pc机发送过来的指令,PID参数读取,修改等等。

RF接收由ucRF_DumpRxData函数处理,在100Hz循环中

其他的也继承了crazepony的起飞降落粘滞性、油门曲线。

定高资料可参考crazepony,原程序已实现定高可以直接使用。

姿态算法也保留crazepony的算法,上位机也可以直接使用。

PID调试

程序有了接下来就是调PID,所谓的PID。P是比例系数。说通俗点就是知道误差后用怎样的程度去减小误差。此值越大系统误差越小。 I 是积分时间。是对误差的累加时间。此值越小。累加越快,积分作用越大。系统误差越小。 D 是微分时间。是提高系统的响应。用来稳定系统的。可以放在反馈和误差的通道里。这样3种同时作用。就可以实现闭环反馈控制。消除误差。

具体方法是:先整定内环PID,再整定外环P。

内环P:从小到大,拉动四轴越来越困难,越来越感觉到四轴在抵抗你的拉动;到比较大的数值时,四轴自己会高频震动,肉眼可见,此时拉扯它,它会快速的振荡几下,过几秒钟后稳定;继续增大,不用加人为干扰,自己发散翻机。

特别注意:只有内环P的时候,四轴会缓慢的往一个方向下掉,这属于正常现象。这就是系统角速度静差。

内环I:前述PID原理可以看出,积分只是用来消除静差,因此积分项系数个人觉得没必要弄的很大,因为这样做会降低系统稳定性。从小到大,四轴会定在一个位置不动,不再往下掉;继续增加I的值,四轴会不稳定,拉扯一下会自己发散。

特别注意:增加I的值,四轴的定角度能力很强,拉动他比较困难,似乎像是在钉钉子一样,但是一旦有强干扰,它就会发散。这是由于积分项太大,拉动一下积分速度快,给  的补偿非常大,因此很难拉动,给人一种很稳定的错觉。

内环D:这里的微分项D为标准的PID原理下的微分项,即本次误差-上次误差。在角速度环中的微分就是角加速度,原本四轴的震动就比较强烈,引起陀螺的值变化较大,此时做微分就更容易引入噪声。因此一般在这里可以适当做一些滑动滤波或者IIR滤波。从小到大,飞机的性能没有多大改变,只是回中的时候更加平稳;继续增加D的值,可以肉眼看到四轴在平衡位置高频震动(或者听到电机发出滋滋的声音)。前述已经说明D项属于辅助性项,因此如果机架的震动较大,D项可以忽略不加。

外环P:当内环PID全部整定完成后,飞机已经可以稳定在某一位置而不动了。此时内环P,从小到大,可以明显看到飞机从倾斜位置慢慢回中,用手拉扯它然后放手,它会慢速回中,达到平衡位置;继续增大P的值,用遥控器给不同的角度给定,可以看到飞机跟踪的速度和响应越来越快;继续增加P的值,飞机变得十分敏感,机动性能越来越强,有发散的趋势。

这部分可以参考《四轴PID讲解_recode123的博客-CSDN博客》

还有文章

玩无人机必备!PID调节经验_eagle11235的博客-CSDN博客_无人机pid控制

X型小四轴双闭环PID调节_dmffrank的博客-CSDN博客

以及crazepony的调试方法

飞行器平衡调试 | Crazepony开源四轴飞行器

但是调试方法其实不固定,合适的PID也不只有一组,只要最后能稳定就是最好的。

融合scratch3.0

虽然硬件低成本,但是软件很丰富,定位教学的话scratch必不可少,crazepony的基础上,增加了使用串口的方式与scratch通讯部分,与市场上无线通讯不同,可以不使用遥控器直接电脑控制无人机,甚至可以当做开发板来使用,在主程序中PD_CONTROL可以选择使用crazepony上位机或scratch。

软件框架中,添加ProgramData文件,和arduino一样,串口传输程序且不会BootLoader抹掉,但是也不一样,这里的BootLoader是无人机程序,是一个完整的飞控,scratch软件中,可以直接在积木块选择运行scratch还是运行预制的飞控,而运行scratch的时候,飞控的保护仍然处于运行状态,保护无人机和用户。

scratch发送的程序存储在EEPROM中,关机后重启仍然保留,在scratch中,你设置可以规划无人机路线,实现全自动飞行。

最后大概统计一下,硬件成本包括遥控器、电机等全部总价能做到25以内,支持悬停、翻滚、微调、无头模式等,软件支持crazepony上位机或scratch3.0,项目的硬件PCB、STM32程序等已全部完成。

此项目只有我一个人做,难免出现错误,欢迎评论指正,也可以加我QQ一起交流进步,CSDN不能上传无人机项目资源,需要可以加我QQ。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32小四轴超低成本方案开源项目 的相关文章

  • STM32与C#上位机串口通信示例

    1 概述 串口通信是一种非常常用的通信方式 xff0c 本文首先介绍了串口硬件和协议的相关内容 xff0c 然后给出一个STM32与C 上位机通过串口通信的示例 2 串口介绍 参考这份文档 3 通信协议 为了方便数据传输 xff0c 定义了
  • 【转】23个常用的VSCode快捷键(动图演示)

    尽管我们经常使用 VS Code中的许多快捷方式 xff0c 但是我们有可能会忘记它们 这里用可视化制作了一些GIF xff0c 以便更好地记住它们 xff0c 希望对你有所帮助 VSCode中的每个命令也可以通过使用CTRL 43 SHI
  • HI3531编码h.264文件播放偏慢分析随笔

    现象 xff1a 编码h 264文件播放时 xff0c 无论帧率是30fps还是60fps xff0c 播放器显示帧率为25 fps 探索过程 xff1a cat proc umap venc 显示得知 xff0c 编码的的确是30fps和
  • C++ const用法详解

    const 是C 43 43 中常用的类型修饰符 常类型是指使用类型修饰符const说明的类型 xff0c 常类型的变量或对象的值是不能被更新的 目录 一 const的作用 二 const修饰普通类型的变量 三 const修饰指针变量 四
  • Source Insight 4.0打开一会就闪退 解决方法

    遇到Source Insight 4 0打开直接闪退 xff0c 请不要着急卸载 xff0c 在Source Insight 4 0快捷键上 xff0c 点击属性 xff0c 选择兼容性如下 xff1a
  • secureCRT连接ubuntu18.04

    1 安装ssh服务器 sudo apt get install openssh server 2 ssh服务器安装失败 错误提示 xff1a 下列软件包有未满足的依赖关系 xff1a openssh server 原因 xff1a 系统预置
  • STM32——USART串口通信与串口重定向

    简介 UART 通用异步收发传输器 xff08 Universal Asynchronous Receiver Transmitter xff0c 通常称 作 UART 它将要传输的资料在串行通信与并行通信之间加以转换 作为把并行输入信 号
  • 海思文件系统缺少文件himm 、i2c_read 、i2c_write 、ssp_read 、ssp_write

    原因 xff1a 海思根文件默认没有把himm i2c read i2c write ssp read ssp write工具集成在bin里 xff0c 但是在sdk中 解决办法 xff1a cd osdrv tools board reg
  • Ubuntu 18.04 Samba服务器的安装和配置(详解)

    具体步骤 xff1a 1 设置为静态IP xff1a 点击静态IP设置链接 2 更新当前软件 sudo apt get upgrade sudo apt get update sudo apt get dist upgrade 3 安装sa
  • C52单片机(AT89C52)—流水灯

    本文重点 xff1a C52流水灯代码编写 xff0c keil如何生存hex文件和proteus如何导入hex文件 1 打开keil xff0c 建立工程 xff0c 编写如下代码 include lt reg52 h gt includ
  • Hi3516EV200图像调优

    一 平台搭建 1 将Hi3516EV200 PQ V1 0 0 3 tgz放到nfs挂载目录下解压 xff0c 进入Hi3516EV200 PQ V1 0 0 3 执行StartControl sh 2 执行HiPQTools exe xf
  • Qt低延时/可集成嵌入的网络播放器 –soundTouch的使用

    背景 在观看直播的过程中 xff0c 保不齐网络出现卡的现象 xff0c 可能导致音频数据包累积了好几秒的数据 xff0c 这时候要么丢直接播放新的 xff0c 要么直接播放基音 xff0c soundTouch可以加速播放并不要变调 主要
  • 超低延时直播rtmp推流

    项目起源 xff1a 改项目主要是基于类qt av的模式 xff0c 快速集成 xff0c 将ffmpeg融入到插件当中 xff0c 并提供本地的音频设备和视频设备的查找输出 xff0c 并可以采集各类虚拟摄像头 xff0c 酷狗直播助手
  • minio 使用aws c++ 多线程下载

    C 43 43 下载 Minio 文件 下载 aws sdk cpp git clone recurse submodules GitHub aws aws sdk cpp AWS SDK for C 43 43 麒麟上编译AWS cmak
  • 拉流推流服务器设计

    背景 该服务器也是基于一个客户的需求产生的 客户那边使用的是腾讯的直播sdk xff0c 将不同终端的流推到腾讯云平台 xff0c 但是又想推到其他平台 xff0c 基于此需求 xff0c 该产品产生了 该产品通讯协议使用的是WebSock
  • 开发实现C++ RTMP直播推流sdk

    前言 rtmp即Real Time Messaging Protocol xff08 实时消息传输协议 xff09 的首字母缩写 xff0c 它是由Adobe公司提出的一种应用层的协议 xff0c 用来解决多媒体数据传输流的多路复用 xff
  • 开发实现C++ RTMP直播拉流播放器

    背景 该直播播放器的背景是来源于 拉流推流服务器设计 的一个分支 xff0c 它的重点是把拉下来的流进行解码显示播放 设计点 要实现跨平台 xff0c 目前支持的平台linux和windows要模块化和结构化可以拉各个平台的直播流要音视频同
  • 校验和计算原理

    校验和思路 首先 xff0c IP ICMP UDP和TCP报文头都有检验和字段 xff0c 大小都是16bit xff0c 算法基本上也是一样的 在发送数据时 xff0c 为了计算数据包的检验和 应该按如下步骤 xff1a 1 把校验和字
  • gb 28181的20位编码简介

    图解Python数据结构与算法 实战篇 举例 xff1a 36030000042000000003 设备的20位编码组成 国标编码由中心编码 xff08 8位 xff09 行业编码 xff08 2位 xff09 类型编码 xff08 3位
  • 继承的构造析构函数&&父类子类同名函数,变量的调用

    include lt iostream gt include 34 string 34 using namespace std class Base public int m A int m B 61 20 Base m A 61 100

随机推荐