电子设计大赛四旋翼设计报告最终版文档格式.docx
《电子设计大赛四旋翼设计报告最终版文档格式.docx》由会员分享,可在线阅读,更多相关《电子设计大赛四旋翼设计报告最终版文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
图2.0
其中微处理器MC9S12XS128模块的外围电路见附录一
2.1控制系统选择方案:
2.1.1方案一:
选择Coldfire系列芯片作为系统控制的主控板,因为在以往队员们做过飞思卡尔智能车竞赛,对此系列的芯片做的比较熟悉,芯片功能强大,但以往做的核心板较大,所需的电路较多,考虑到四轴飞行器的轻便,故而不太是一个很理想的选择。
2.1.2方案二:
主控板使用STM32。
STM32板子的I/O口很多,自带定时器和多路PWM,可以实现的功能较多,符合实验要求。
Stm32迷你板在体积和重量上也不是很大,对飞机的载重量要求不是很高。
综上所述,我们一致决定使用STM32MMC10作为此次大学生电子竞赛的主控板。
2.2飞行姿态的方案论证:
2.2.1方案一:
十字飞行方式。
四轴的四个电机以十字的方式排列,x轴和y轴成直角,调整俯仰角和翻滚角的时候分开调整,角度融合简单,适合初学者,能明确头尾,飞行时机体动作精准,飞控起来也容易。
2.2.2方案二:
X行飞行方式。
四轴的四个电机以X字的方式排列,灵活性和可调性较高,调整的时候应该相邻两个融合调节,融合复杂。
X型飞行方式非常自由灵活,旋转方式多样,可以花样飞行,也可以做出很多高难度动作,但是控制上相对比较困难。
综合以上两种方案鉴于我们是初次尝试,所以选择了方案一。
2.3
角度测量模块方案论证
2.3.1方案一:
光纤陀螺仪。
光纤陀螺仪是以光导纤维线圈为基础的敏感元件,
由激光二极管发射出的光线朝两个方向沿光导纤维传播。
光传播路径的变化,决定了敏感元件的角位移。
光纤陀螺仪寿命长,动态围大,瞬时启动,结构简单,尺寸小,重量轻,但是成本较高,鉴于我们这是初次尝试,需要多次实验,破坏较大。
2.3.2方案二:
MPU6050三轴陀螺仪。
MPU6050三轴陀螺仪就是可以在同一时间测量三个不同方向的加速度、角速度、角度。
单轴的话,就只可以测定一个方向的量,那么一个三轴陀螺就可以代替三个单轴陀螺。
它现在已经成为激光陀螺的发展趋向,具有可靠性很好、结构简单不复杂、重量很轻和体积很小等等特点,但是其输出数据需要大量的浮点预算才能保证较高的精度,这样会影响主控板对最终的姿态控制的响应速率。
综合以上两种方案,我们选择了方案二
2.4飞行器距地距离显示的方案论证:
2.4.1方案一:
选用LCD液晶显示:
LCD液晶显示在显示效果上较丰富,可以显示字母,数字等等需求,但在我们实际编写的时候发现驱动代码稍显复杂,显示效果在实际光线较亮的时候外界不容易清晰的看到LCD显示的容,尤其是当四轴飞行器在实际飞行的过程中,显示效果并不理想。
2.4.2方案二:
选用LED数码管显示:
实际的观察中,发现数码管的显示比较单一,但显示容清晰可辨认,实际使用中对系统的占用资源也比较少。
考虑比赛要求只要求看到实际的显示效果,因而我们决定使用数码管来显示四轴飞行器距离地面的距离。
2.5确定方案之后,针对题目要求,最终编写出合适算法,进行控制。
程序流程图如下(图2.1):
图2.1
2.6程序部分核心代码见附录二
三、设计实现:
3.1超声波测距模块:
由于竞赛要求需要四轴飞行器悬停在一个距离,因而在我们做的过程中,选用超声波传感器用于测量四轴飞行器距离地面的距离,测量误差实际保证在1cm一下,基本做到精确测量,在写超声波模块的
驱动时,开始我们只想通过在程序中写一个无限循环的延时程序来测量超声波往返的时间,这种方法在开始单步调试测距的时候表现正常,可以读到正确数据,但在单片机中加入中断优先级的程序时这种方法就不能胜任了。
最后经我们小组讨论决定利用单片机的pit中断实现超声波模块的测量往返时延,测量精确。
实验效果较好。
3.2显示报告飞行高度:
在我们的方案设计中小队决定使用数码管来显示四轴飞行器距离地面的高度,在我们做的过程中首先要解决的问题就是选用静态显示还是动态显示的问题,开始因为想的比较简单就想单纯的用I/O口置高与置低电平来控制LED数码管的亮暗,发现如果4位数码管显示的话所用到的I/O口就需要4*8=32个IO口,这对单片机有限的引脚来说是一个巨大的负担,在查找资料与请教老师后我们找到一种动态显示数码管的方法很好的解决了这个问题,所需引脚仅仅用11个,实际测试中,显示效果很好。
四、测试:
4.1硬件测试:
将四旋翼模型拆解,然后用物理法测量中心,使其重心维持在四轴飞行器的中心。
然后按顺序将电池,主控板,陀螺仪等机械硬件使其牢固的装在模型飞机上。
硬件测试使用了万能角度尺、示波器、万用表、压线钳、
电量测量仪等。
4.2软件测试:
为了保证PWM波输出的正确性,每次改动程序初始化之后用示波器测试波形的输出,保证其占空比和周期的正确性。
在正式算法程序之前,又用串口显示每个电机PWM输入,观察电机在各个PWM占空比的电机转速。
确保软件反应硬件是规律一致的。
软件测试最关键的是PID的参数调试,其中,p参数是调整整个四旋翼飞行器的反应速度和力度的,调节p参数以当整个模块反应迅速并且四旋翼振动频率四边偏差不大的时候即可完成,d参数在这之中的目的是一个抑制作用,当振荡幅度过大的时候能从任意角度一次直接返回平衡位置。
I参数是一个积分项,当哪一边反应过小时可以加一个i参数,这样就成了一个完整的PID参数调试了。
4.3硬件软件联合测试:
此步主要通过在STM32平台下进行编程,进行一系列的算法设计与调校,确认四旋翼飞行器是否能够飞行,通过大量的测试与实践,找出能刚刚使飞行器的电机占空比(PWM)值,当然,这一步可以通过联合超声波距离传感器设计一个动态PID调节,具体的调节方法依据能反应姿态的传感器联合作用。
五、完成情况:
在本小组所有队员这几天的努力调试下,本次完成情况如下,飞行器能够垂直起飞,起飞后能在50cm出悬停5s以上,然后飞行器可以继续垂直上升至100cm出,能悬停5s以上,在平稳回到原地的过程中,因为没有其他的传感器给飞行器提供路径的识别,所以回到原地的过程中,一切只能依靠软件与经验来模拟,故实际使用中发现做到这一步误差存在,在飞行器起飞至50~100cm的高度上,悬停5s以后,然后水平飞行200cm,这一步也是由于没有具体的识别方法,依靠软件实际测试得出的规律来确定200cm的大致飞行时间与速度,因而依然存在误差。
由于我们把数码管和超声波做好,因而显示飞行器距地距离很顺利。
总体比赛容大致完成。
六、总结:
本次参加电子设计大赛,我们将以往的一些经验杂糅成新,深刻认识到软硬件结合的重要性。
四旋翼的完成,硬件是基础,只有在能灵活熟练地使用硬件,才能更加方便的编写质量好的软件。
另外一个不可忽视的问题便是方案的选取。
一个项目的完成可能会有很多种方案,而且不同方案在实现之前不可预知其好坏以及是否适合本项目的完成,这就衍生出更多的实践测试,项目的完成不可一蹴而就,认真对待,在摸爬滚打中可积累更多的经验。
另外,基于软硬件的项目,其机械性能也会有不可小觑的影响。
起初我队在搭建机械的时候忽视了四旋翼的重心,认为机械重心的便宜可通过算法的自我调控来调节,事实证明,这种想法是错误的,好的机械性能更有利于算法的实现,机械搭建的好,便更容易调试软件。
在完成的过程中,我队深刻意识到在嵌入式的开发过程中,对软件质量的要求很高,所以在实际的编写过程中,优异的代码与思想或许尤为重要,而我们在这方面还多有不足,在此过程中,我们因为传感器的不足,有些想法不能做,但也正是缺少直接的东西,让我们可以很好的发现其他的解决方法,以后还需努力。
附录一:
附录二:
(部分核心代码)
/******************超声波模块**************************************/
intcsb(void){
intd=0;
PTT_PTT5=1;
delayus(10);
PTT_PTT5=0;
while(PTIT_PTIT3!
=1);
count=0;
while(PTIT_PTIT3==1);
d=count*17/10;
returnd;
}
/******************数码管显示模块**************************************/
voidshow123(x){
if(x==0){
PORTA_PA1=up;
PORTA_PA2=up;
PORTA_PA3=up;
PORTA_PA4=up;
PORTA_PA5=up;
PORTA_PA6=up;
PORTA_PA7=down;
}elseif(x==1){
PORTA_PA1=down;
PORTA_PA4=down;
PORTA_PA5=down;
PORTA_PA6=down;
}
elseif(x==2){
PORTA_PA3=down;
PORTA_PA7=up;
elseif(x==3){
elseif(x==4){
elseif(x==5){
PORTA_PA2=down;
elseif(x==6){
elseif(x==7){
elseif(x==8){
elseif(x==9){
}elseif(x==10){
}else{
/******************起飞模块**************************************/
voidstartfly(void){
PWMDTY2=25;
show_xt=10;
show_a=show_b=10;
show_c=0;
delayms(2000);
PWMDTY0=1185>
>
8;
PWMDTY1=1185;
PWMDTY3=19;
PWMDTY2=19;
voidmain(void)
{
inti=0;
intP=12,I=0,D=150;
PLL_Init();
PWM_Init();
DDRT_DDRT3=0;
DDRT_DDRT5=1;
DDRA=0xFF;
DDRT_DDRT2=1;
DDRT_DDRT4=1;
DDRT_DDRT6=1;
PIT_Init();
EnableInterrupts;
delayms(4000);
startfly();
/*GetDIPSwitch();
if(DIPSwitch_DIPS8==0){
bmkg=100;
}*/
while(s<
=14){
if(s>
=11)
want=350;
=12)
=14)
want=150;
delayms(40);
test=csb();
now_high=want-test;
PI+=I*now_high;
PWM3_ls=P*now_high+PI+D*(now_high-last_high);
PWM3=1160+PWM3_ls/100;
llst_high=last_high;
last_high=now_high;
if(PWM3>
1230)
PWM3=1230;
elseif(PWM3<
1100)
PWM3=1100;
PWMDTY4=PWM3>
PWMDTY5=PWM3;
test=test/10;
if(csb_count>
3000){
csb_count=0;
if(test<
10){
show_a=10;
show_b=10;
show_c=test;
}elseif(test<
100){
show_b=test/10;
show_c=test%10;
show_a=test/100;
show_b=test/10%10;
PWMDTY4=800>
PWMDTY5=800;
for(;
;
)
{
_FEED_COP();
}
}
/******************中断服务函数**************************************/
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
voidinterrupt66PIT0_ISR(void)
PITTF_PTF0=1;
//清中断标志位
if(count<
10000)
count++;
us++;
csb_count++;
if(us>
100){
us=0;
ms++;
if(ms>
1000){
ms=0;
s++;
show_xt=s%10;
15){
if(us==0){
if(xsq_count==1){
PORTA_PA0=0;
show123(show_xt);
PTT_PTT2=1;
}elseif(xsq_count==2){
PTT_PTT2=0;
show123(show_a);
PTT_PTT6=1;
}elseif(xsq_count==3){
PTT_PTT6=0;
show123(show_b);
PTT_PTT4=1;
}elseif(xsq_count==4){
PTT_PTT4=0;
show123(show_c);
PORTA_PA0=1;
xsq_count=0;
xsq_count++;