智能避障小车论文
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
“神戎”杯山东大学信息学院光电设计大赛基于光电导航的智能移动测量小车
简介
竞赛说明:
设计一辆具有光电导航功能的智能车,要求从线路的指定点出发,沿轨道上铺设的“8”字形导航条走完全程。
在行走进程中,利用光电技术测量、记录沿途所通过隧道的数量、各段隧道的长度及沿途路边树木的棵数。
目录
第1章引言 (4)
第2章整体方案 (5)
需求分析 (5)
整体分析 (5)
方案确信 (5)
第3章硬件方案 (7)
车体设计 (7)
主操纵器模块 (7)
电源模块 (7)
电机驱动模块 (7)
电机模块 (8)
循迹模块 (8)
测量显示 (8)
最终方案 (8)
第4章硬件实现及单元电路设计 (9)
主控模块 (9)
电源设计 (9)
驱动电路 (9)
循迹设计 (10)
测量显示 (10)
第5章系统软件设计方案 (11)
第6章系统的安装及调试 (12)
安装步骤 (12)
电路的调试 (12)
第7章心得与总结 (12)
经费预算 (14)
附录 (15)
第一章引言
随着汽车工业的快速进展,关于汽车的研究也愈来愈受到人们的关注。
智能汽车概念的提出给汽车产业带来机缘也带了挑战。
汽车的智能化必将是以后汽车产业进展的趋势,在如此的背景下,咱们开展了基于超声波和红外线的智能小车的避障研究。
针对一种基于红别传感器的循迹小车,通过对整体方案、电路、算法、调试、车辆参数的介绍,详尽地论述小车通过传感器系统感知外界环境和自身状态, 在复杂的环境中自主移动并完成相应的任务。
红别传感器以其特有的特点而被青睐。
该智能小车系统涉及直流电机操纵技术、途径识别、传感技术、电子设计、程序设计等多个学科,考验咱们的知识融合和实践动手能力的培育。
摘要:智能作为现代的新发明,是以后的进展方向,他能够依照预先设定的模式在一个环境里自动的运作,不需要人为的治理,可应用于科学勘探用途。
本设计中智能小车采纳STC89C52单片机作为检测和操纵的核心,实现智能小车的智能操纵。
驱动电机采纳直流减速电机。
关键词智能小车;单片机;红外线;循迹
第二章 整体方案
本章要紧简腹地介绍系统整体方案的选定和整体设计思路,在后面的章节中将整个系统分为机械结构、操纵模块、操纵算法等三部份对智能车操纵系统进行深切的介绍分析。
需求分析
设计一种基于红外循迹的小车移动平台,借助红别传感器的利用知足在必然的复杂的环境中自主循迹任务,使小车能够按轨道行走。
整体设计
通过学习和研究相关技术资料了解到,红外模块是系统的关键模块之一,方案的好坏,直接关系到最终性能的好坏,因此确信模块的方式是决定系统整体方案的关键。
循迹模块采纳红别传感器的优势是价钱相对廉价,在知足系统的要求下具有较高的精度,能专门好的循迹。
方案确信
系统采纳STC89C52单片机作为核心操纵单元用于智能车系统的操纵,小车车头正中间红别传感器检测前方障碍物,用于判定是不是需要转弯。
系统整体的设计方框图如图1所示。
依照系统方案设计,系统包括以下模块:STC89C52主控模块、L9110电机驱动模块、电源模块、循迹模块、显示模块、测速测树木模块等。
各模块的作用如下:STC89C52主控模块,作为整个智能小车的“大脑”,将发送搜集红外等传感器的信号,依照操纵算法做出操纵决策,驱动直流电机等等完成对智能车的操纵。
电源模块,为整个系统提供适合而又稳固的电源;
电机驱动模块,驱动直流电机完成智能车的加减速操纵和转向操纵;
红外循迹模块,那么能够达到循迹功能。
显示模块,将测量结果显示。
测速测树木模块,准确测量树木数量,隧道长度。
第三章硬件方案
依照整体方案设计,对硬件结构的要求是:简单而高效,在不断的尝试后确信了以下的设计方案:
车体设计
买现成的车模。
通过反复考虑论证,咱们制定了买左右两轮别离驱动,后万向轮转向的车模方案。
即左右轮别离用两个转速和力矩大体完全相同的直流减速电机进行驱动,后装一个万向轮。
如此,当两个直流电机转向相反同时转速相同时就能够够实现电动车的原地旋转,由此能够轻松的实现小车坐标不变的90度和180度的转弯。
主操纵器模块
采纳STC89C52单片机作为整个系统的核心,用其操纵行进中的小车,以实现其既定的性能指标。
充分分析咱们的系统,其关键在于实现小车的自动操纵,而在这一点上,单片机就显现出来它的优势——操纵简单、方便、快捷。
如此一来,单片机就能够够充分发挥其资源丰硕、有较为壮大的操纵功能及可位寻址操作功能、价钱低廉等优势。
51单片机具有功能壮大的位操作指令,I/O口都可按位寻址,程序空间多达8K,关于本设计也绰绰有余,更宝贵的是51单片机价钱超级低廉。
电源模块
采纳锂电池做电源,后为单片机,传感器供电。
通过实验验证小车工作时,单片机、传感器的工作电压稳固能够知足系统的要求,而且电池改换方便。
电机驱动模块
采纳功率三极管作为功率放大器的输出操纵直流电机。
线性型驱动的电路结构和原理简单,加速能力强,采纳由达林顿管组成的 H型桥式电路。
用单片机操纵达林顿管使之工作在占空比可调的开关状态下,精准调整电动机转速。
这种电路效率超级高,H型桥式电路保证了简单的实现转速和方向的操纵,是一种普遍采纳的 PWM调速技术。
现市面上有很多此种芯片,我选用L9110,一片L9110能够别离操纵一个直流电机,而且还带有操纵使能端。
用该芯片作为电机驱动,操作方便,稳固性好,性能优良。
电机模块
本系统为智能电动车,关于电动车来讲,其驱动轮的驱动电机的选择就显得十分重要。
因此我采纳直流减速电机。
直流减速电机转动力矩大,体积小,重量轻,装配简单,利用方便。
由于其内部由高速电动机提供原始动力,带动变速(减速)齿轮组,能够产生大扭力。
能够较好的知足系统的要求。
循迹模块
采纳红别传感器负责循迹功能的实现。
考虑到本系统需要检测线路,为了利用方便、系统稳固性、便于操作和调试。
测量显示模块
用红外对管进行速度及距离测量,和数量测量,用1602显示屏进行结果显示
最终方案
通过反复论证,咱们最终确信了如下方案:
1、车模用两驱车模
2、采纳STC89C52单片机作为主操纵器。
考虑到89C52单片机运行速度比较慢,若是采纳一片单片机可能会显现误差(如测速模块)因此用两片单片机。
3、用锂电池供电。
电池能为电机提供更高的功率。
4、用红别传感进行测量树木数量。
左右各一路红外传感器,由于小车速度比较慢,所以不需要利用外部中断直接在检测到返回的低电平后数量加一,然后延时一段时间,直到小车绕过树木,防止数量重复相加。
5、L9110作为直流电机的驱动芯片。
结构简单,重量较轻,能够为电机提供稳固、大功率的电压。
6、红外对管进行测量隧道长度。
利用一路红外探头位于小车上方检测隧道有无。
进入隧道后用红外测速模块计算小车行进的距离。
7、红外探测器进循迹。
考虑到轨道要紧以直线为主,中间有直角钝角转弯和中间交叉路口直行三种特殊情形,共采纳七路循迹模块,其中五路(从左往右第二、三、四、五、六)检测直道,再用三路处置三种特殊情形(三路循迹探头为从左往右第一、四、七)。
八、1602显示器显示数据。
考虑到要显示的内容比较简单,只是字母和数字,因此1602就能够知足要求,而且1602结构简单,价钱廉价,容易把握。
第四章硬件实现及单元电路设计主操纵模块
主操纵最小系统电路如图4所示。
图 4
电源设计
为了节约本钱,咱们的电源采纳了锂电池电池作为单片机的供电电源。
驱动电路
通过单片机给予L9110电路PWM信号来操纵小车的速度,起停。
循迹模块
测量显示模块
第5章系统软件设计方案
该方案的编程思路是先确信主程序,以后依照各硬件电路功能来设计子程序模块,最后再将各模块嵌入主程序中。
如此编程结构简单,由于子程序模块与硬件电路一一对应,因此调试起来十分方便。
本设计软件方框图如图9示。
图9
第六章系统的安装与调试
安装步骤
1.检查元件的好坏
按电路图买好元件后第一检查买回元件的好坏,按各元件的检测方式别离进行检测,必然要认真认真。
而且要认真查对原理图是不是一致,在检查好后才可上件、焊件,避免显现错误焊件后不便更正。
2.放置、焊接各元件
按原理图的位置放置各元件,在放置进程中要先放置、焊接较低的元件,后焊较高的和要求较高的元件。
专门是容易损坏的元件要后焊,在焊集成芯片时持续焊接时刻不要超过10s,注意芯片的安装方向。
电路的调试
第一烧入电机操纵小程序,操纵电机正反转,停止均正常。
说明电机及驱动电路无误。
然后加入循迹子程序,小车运转正常时,达到理想成效。
在调试程序时,发觉有的指令用的不正确,致使电路功能不能完全实现,另外软件程序中的延时有的太长、有的太短。
类似的现象还有很多就不一一列举了。
第7章心得与总结
本智能小车电路在硬件上采纳红外循迹传感器来循迹。
由于采纳了锂电池电池供电使系统的抗干扰性取得增强。
在软件上,充分利用了STC89C52的系统资源,使智能小车实现了隧道测量、树木检测、循迹的功能。
本设计结构简单,调试方便,系统反映快速灵活,硬件电路由可拆卸模块拼接而成有专门大的扩展空间。
经实验测试,该智能小车设计方案正确、可行,各项指标稳固、靠得住。
尽管智能小车系统有很多优势,但在设计当中也存在着一些不足。
一是由于咱们都是做出的小车较简单;再者确实是在制作进程中显现了较多问题:
1.小车在行驶进程中左右摇晃,容易冲出轨道,转弯不稳固,轨道两旁树木会被重复检测,中间交叉处不能直行,要紧缘故是左右轮转速不完全一致,能够利用四轮小车同时将循迹探头往前放。
2.程序存在缺点,行进进程中有时会停止。
通过这次对作品的制作,使我学到许多东西,不管软件方面仍是硬件方面都需要把握,还有合作和谐方面,动手能力,调试时候注意事项,都有着专门大的要求,是我收成颇丰。
经费预算
1.飞思卡尔小车底盘+驱动模块:280
2.电池+充电器:60
3.九路循迹+支架:70
4.红外探头4个:80
5.测速模块两个(左右轮):30
6.1602显示器1个:20
7.L9110电机驱动模块:15
8.三轮小车底盘+两个电机:40
9.STC89C52单片机两个:15
10.STC89C52最小系统两个:20 共计: 630
附录:(源代码)
循迹:
#include<>
#define uint unsigned int
#define uchar unsigned char
sbit r1=P0^0;
sbit r2=P0^1;
sbit l1=P0^2;
sbit l2=P0^3;
sbit look=P2^4;
sbit look1=P1^0;
sbit look2=P1^1;
sbit look3=P1^2;
sbit look4=P1^3;
sbit look5=P1^4;
sbit look6=P1^5;
sbit look7=P1^6;
sbit get=P1^7;
void go();
void back();
void turn_right();
void turn_left();
void delay1ms(int);
void stop();
void turnright(uint);
void turnleft(uint);
void go_strait(uchar);
void main()
{
get=1;
if(get==0) stop();
else
{if(look1==1&&look2==1&&look3==0&&look4==1&&look5==1&&look6==1&&look 7==1)//直行
{ go();
}
else
if((look1==0||look2==0)&&look4==1&&look5==1&&look6==1&&look7==1)//在轨道上右偏
{
do{turn_left();}while(look3==1);
}
else
if(look1==1&&look2==1&&(look4==0||look5==0)&&look6==1&&look7==1)//在轨道上左偏
{
do{turn_right();}while(look3==1) ;
}
else if(look6==0)
{
go_strait(1);
if(look7==0)
{
go_strait(10);
}
else
{
do{turn_right();}while(look3==1);
}
}
else if(look7==0)
{
go_strait(1);
if(look6==0)
{
go_strait(10);
}
else
{
do{turn_left();}while(look3==0);
}
}
else stop();
} }
void go()
{
r1=0;r2=1;
l1=0;l2=1;
delay1ms(5);
stop();
delay1ms(10);
}
void go_strait(uchar x) { while(x--){
r1=0;r2=1;
l1=0;l2=1;
delay1ms(3);
stop();
delay1ms(10);}
}
void back()
{
r1=1;r2=0;
l1=1;l2=0;
delay1ms(10);
stop();
delay1ms(10);
}
void turn_right()
{
{r1=0;r2=0;
l1=0;l2=1;
delay1ms(5);
stop();
delay1ms(15);}
}
void turnright(uint z) {
while(z--)
turn_right();
}
void turn_left()
{
r1=0;r2=1;
l1=0;l2=0;
delay1ms(5);
stop();
delay1ms(15);// } }
void turnleft(uint z)
{
while(z--)
turn_left();
}
void stop()
{
r1=0;r2=0;
l1=0;l2=0;
}
void delay1ms(int x)
{
int i,j;
for(i=1;i<x;i++)
for(j=1;j<120;j++);
}
检测:
/07/lcd模块
#include<>
#define LCDP P0
#define uint unsigned int
#define uchar unsigned char
sbit RS=P1^7; //寄放区选择位
sbit RW=P1^6; //设置读写位
sbit E=P2^4; //使能位(0:禁止,1:使能)
sbit BF=P0^7; //忙碌检查位
sbit lookleft=P2^0;
sbit lookright=P2^1;
sbit lookup=P3^3;
sbit speed=P3^2;
sbit stop=P1^1;//小车停止标志
sbit send=P1^0;
char amount_tree=0,amount_bri=0;//树的个数,隧道的个数
uint length_bri[4]; //桥的长度
char line1[]="Count of Tree:";
char line2[]="Count of Bri:";
char line3[]="Length of Bri: "; //显示的字符
char line4[]="";
uint temp=0;//测速模块反映次数
void init_LCM(void);//初始化设置函数
void write_inst(char);//写入指令函数
void write_char(char);//写入字符数据函数
void check_BF(void);//检查是不是忙碌函数
void delay1ms (int);//延迟函数
void display1();
//void display_char(char line,loca,character);//写入指定位置void blank_line(char line);//写入空白行
void main()
{
send=1;
while(1){
if(stop==0) //遇到终止信号时
{
send=0;
display1();
}
else//没有碰到终止信号
{
if(lookup==1)//没有桥
{
if(lookright==0&&lookleft==1) //右边有树 {
amount_tree=amount_tree+1;
delay1ms(200);
}
if(lookright==1&&lookleft==0) //左侧有树 {
amount_tree=amount_tree+1;
delay1ms(200);
}
if(lookright==0&&lookleft==0)
{
amount_tree=amount_tree+2;
delay1ms(200);
}
}
else //有桥
{
amount_bri=amount_bri+1;
temp=0;
while(lookup==0)
{ IE=0x81;
TCON=0x01;
//if(speed==1)
// {
// temp=temp+1;
// delay1ms(5);
// }
}
length_bri[amount_bri]=temp/5;
}
}
}
}
void speed_INT(void) interrupt 0
{
temp=temp+1;
}
//--------LCD显示—-----------
void display1()
{
char i,j;
char length[5];
char count_tree[2],count_bri[2]; //用sac码显示数量
count_tree[0]=amount_tree/10+0x30; //树的个数,十位数
count_tree[1]=amount_tree%10+0x30; //树的个数,个位数
count_bri[0]=amount_bri/10+0x30; //桥,十位数
count_bri[1]=amount_bri%10+0x30; //桥,个位数
init_LCM();//初始化设置
while(1)
{
write_inst(0x80);//第一行起始地址,显示字符串1 ,树的棵数
for(i=0;i<14;i++)
write_char(line1[i]);
write_inst(0x8e); //显示数字的地址
for(i=0;i<2;i++)
write_char(count_tree[i]);
write_inst(0xc0); //第二行起始地址,显示字符串2 ,桥的数量for(i=0;i<14;i++)
write_char(line2[i]);
write_inst(0xce); //显示数字的地址
for(i=0;i<2;i++)
write_char(count_bri[i]);
delay1ms(2500);
write_inst(0x01);//清除显示屏
delay1ms(1000);
//===各个桥的长度
for(j=0;j<amount_bri;j++)
{
char dis[3],x=j+1;
uint y;
length[0]=length_bri[x]/10000+0x30;
y=length_bri[x]%10000;
length[1]=y/1000+0x30;
y=y%1000;
length[2]=y/100+0x30;
y=y%100;
length[3]=y/10+0x30;
y=y%10;
length[4]=y%10+0x30;
if(x<10)
{ dis[0]=' ';
dis[1]=x+0x30;
dis[2]=':';}
else{dis[0]=x/10+0x30;
dis[1]=x%10+0x30;
dis[2]=':';}
write_inst(0x80);
for(i=0;i<16;i++)
write_char(line3[i]); //第一行显示字符串
write_inst(0xc1); //第二行起始地址为第二个位置
for(i=0;i<3;i++)
write_char(dis[i]);
write_inst(0xc5);
for(i=0;i<5;i++)
write_char(length[i]) ;
write_inst(0xcb);
write_char('c');
write_inst(0xcd);
write_char('m');
delay1ms(2000);
}
}
}
//=========初始化设置函数(八位传输模式)=========
void init_LCM(void)
{
write_inst(0x30);//设置功能
write_inst(0x30);
write_inst(0x30);//兼容设置
write_inst(0x38);//设置
write_inst(0x08);//关闭显示功能
write_inst(0x01);//清除显示屏
write_inst(0x06);//设置输入模式
write_inst (0x0c);//设置显示功能,开启显示屏,不显示光标,光标所在字符不反白
}
//=========写入指令函数=====
void write_inst(char inst)
{
check_BF(); //检查是否忙碌
LCDP=inst; //LCM读入MPU指令
RS=0; RW=0; E=1; //写指令至LCM check_BF();
}
//========检查忙碌函数========
void check_BF(void)
{
E=0;//禁止读写
do
{
BF=1;
RS=0;RW=1;E=1;
}while(BF==1);
}
//=====写入字符数据函数====
void write_char(char chardate)
{
check_BF();
LCDP=chardate;
RS=1;RW=0;E=1;
check_BF();
}
//=====延迟函数=====
void delay1ms(int x)
{
int i,j;
for(i=1;i<x;i++)
for(j=1;j<120;j++);
}
//=======空白行=====
void blank_line(char line) { char i;
check_BF();
RS=0;RW=0;E=1;
if(line=0)
P0=0x80;
if(line=1)
P0=0xc0;
check_BF();
for(i=0;i<16;i++)
write_char(' ');
}。