北京工业大学电子信息工程课程设计结题报告含有代码.docx
《北京工业大学电子信息工程课程设计结题报告含有代码.docx》由会员分享,可在线阅读,更多相关《北京工业大学电子信息工程课程设计结题报告含有代码.docx(20页珍藏版)》请在冰豆网上搜索。
![北京工业大学电子信息工程课程设计结题报告含有代码.docx](https://file1.bdocx.com/fileroot1/2023-1/26/20ca5e85-5390-4c86-b9c2-da8df5ae8873/20ca5e85-5390-4c86-b9c2-da8df5ae88731.gif)
北京工业大学电子信息工程课程设计结题报告含有代码
北京工业大学
专业课程设计
研发课题结题报告
院、系(所)电子信息与控制工程学院
专业名称电子信息工程
姓名(学号)吕祎12021027
同组参与者周鸿宇12021031
指导教师徐小平
北京工业大学通信电路实验室
二0一五年九月
论文题目
基于超声波测距技术的智能避障小车设计
课题的目的,国内外研究现状和发展趋势:
本课题的目的是研究超声波测距技术的应用,研究该技术的原理,应用范围,利用超声波测距时的优缺点。
由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量,如测距仪和物位测量仪等都可以通过超声波来实现。
利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制,并且在测量精度方面能达到工业实用的要求,因此在移动机器人研制上也得到了广泛的应用。
研究现状:
目前为了研究和利用超声波,人们已经设计和制成了许多超声波发生器。
总体上讲,超声波发生器可以分为两大类:
一类是用电气方式产生超声波,一类是用机械方式产生超声波。
电气方式包括压电型、磁致伸缩型和电动型等;机械方式有加尔统笛、液哨和气流旋笛等。
它们所产生的超声波的频率、功率和声波特性各不相同,因而用途也各不相同。
目前较为常用的是压电式超声波发生器。
超声波测距的原理是利用超声波在空气中的传播速度为已知,测量声波在发射后遇到障碍物反射回来的时间,根据发射和接收的时间差计算出发射点到障碍物的实际距离。
由此可见,超声波测距原理与雷达原理是一样的。
测距的公式表示为:
L=C×T
式中L为测量的距离长度;C为超声波在空气中的传播速度;T为测量距离传播的时间差(T为发射到接收时间数值的一半)。
发展趋势:
超声波测距主要应用于倒车提醒、建筑工地、工业现场等的距离测量,虽然目前的测距量程上能达到百米,但测量的精度往往只能达到厘米数量级。
篇幅不够可加页
研究设计方案、预期结果:
1、选择合适的超声波发生模块,和其他硬件如舵机、电机等,开发平台采用Arduino.超声波模块使用HC-SRO4
2、设计系统原理图和流程图
初步设计的原理图如下:
初步设计的系统流程图如下:
3、开发平台的调试,基础循迹模块可以对车前目标作出反应
开发平台使用ArduinoIDE。
循迹模块是开发平台订购好的,测试即可。
但是需要调试循迹距离
4、完成系统的硬件电路连接图的设计和电路实物的连接
硬件包括车体组装,AVR单片机的安装,两个减速电机的安装,舵机安装
五、开发平台Arduino对各个部分的控制
第一阶段预期可以实现控制小车前进,停止
第二阶段在安装舵机后,实现控制舵机转动
第三阶段完成超声模块的调试
六、系统整体调试
基础功能是通过车体上的红外接收头进行普通的循迹,最后课题目标是在舵机控制超声模块转动的前提下,小车可以扫描周围障碍搜索前进。
实验内容
1、主要部分设计
(1)、电机驱动部分
电机驱动原理图如下所示
L293D根据网上查到的芯片手册有如下的功能
L293和L293D四倍高电流H桥驱动程序。
L293是提供双向驱动电流高达1A,电压
是从4.5V至36V的;L293D提供双向驱动电流高达600毫安,电压是从4.5V至36V的。
两个设备是专为驱动等感性负载继电器,电磁阀,直流双极步进和马达,也可以给其他高电流/高电压提供电源负载。
兼容所有的TTL输入。
每个输出都是推拉式驱动电路,与达林顿三极管和伪达林源。
启用1,2EN驱动器和3,4EN驱动器。
当使能输入为高电平时,相关联的驱动器被启用和他们的
输出处于活动状态,并在其输入端的同相。
当使能输入为低,这些驱动器被禁用
其输出关闭,在高阻抗状态。
【PS:
1,2EN为1和2的使能端(高电平使能);3,4EN同理】用适当的数据输入端,每对驱动程序的形式一个完整的H桥可逆驱动器适用于电磁阀或电机应用。
L293,外部输出为高速钳位二极管,应使用电感的瞬态抑制。
VCC1和VCC2分开,提供逻辑输入,以尽量减少设备功耗。
L293和L293D的工作温度是从0°C至70°C
由此设计的电机驱动电路如下:
真值表为
输入
输出
电机转动方向
A1
EN1
A2
EN2
Y1
Y2
*****
1
1
0
1
1
0
正转
0
1
1
1
0
1
反转
1
1
1
1
1
1
停
0
1
0
1
0
0
停
X
0
X
0
Z
Z
停
注:
EN1,EN2出现低电平无论A1,A2是什么电平都是高阻
(2)红外循迹模块的设计
红外循迹需要分成两部分设计,一部分是红外检测,一部分是发送接收。
首先应由红外发送接收部分把是否检测到前方有物体转换成模拟信号,再送给红外检测部分判断出是否前方有物体
红外发送接收部分原理图:
图中的RPR220是反光型光电探测器:
其中发射器是一个红外二极管,接收器是一个硅平面光电三极管。
内部电路图如下:
当得到上一个模块的电平信号后,需要到红外检测模块检测,原理图如下、
其中LM324芯片是一个电压比较器,由于比较简单,不再附加芯片资料。
原理图中还应注意OUT1、2、3、4除了接到LED灯还接到了单片机的8、9、10、11数字管脚。
(3)超声波避障模块设计
超声波避障模块采用的是HC-SR04超声波传感器它的工作原理是:
基本工作原理:
(1)采用IO口TRIG触发测距,给最少10us的高电平信呈。
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。
测试距离=(高电平时间*声速(340M/S))/2
2、电路搭接
由于是网上购买的套件,采用的是面包板杜邦线插接,所以不需要焊接。
基本接线结果如下
面包板上是一个按键开关和蜂鸣器,按键是放置程序烧录完小车自主运动,蜂鸣器是用于检测程序是不是已经启动,比较简单不再赘述其设计。
3、程序设计
附录中有完全的程序代码。
编译环境使用的是基于JAVA开发环境的IDE,语言逻辑和C语言基本一样。
程序设计流程图因为开始设计的太简易所以我重新设计了一下。
流程解释:
因为自己加了一个按键启动,所以首先要按键扫描判断是否有按键按下,启动后会听到蜂鸣器的启动音。
之后小车自主前进,首先第一级避障是红外避障。
之所以把红外避障选为第一级是因为红外避障反应速度快,收到信号以后直接就能反应。
而超声需要获取左右两边的距离然后比较。
但是红外避障死角比较多,而且由于小车有一定的速度红外经常来不及反应,最重要的一点就是红外避障受外界光线,地面的反光灯影响准确性不可靠。
红外避障的下移级判断就是超声避障:
刚才上面已经说过超声波避障其实就是测量物体到小车的距离。
人为的给它一个距离值,小于这个值就回避。
至于如何回避,像哪里回避就需要舵机带着它转动,分别测量左、右、中三个距离数值然后作比较,车头转向距离较大的一侧。
如果左右距离都小于规定值,则后退。
实验结果:
实验结果小车完整达成目标。
(见展示视频)
附完整程序代码:
//智能小车超声波避障实验
//=============================================================================
//#include
intEcho=A1;//Echo回声脚(P2.0)
intTrig=A0;//Trig触发脚(P2.1)
intFront_Distance=0;//
intLeft_Distance=0;
intRight_Distance=0;
intLeft_motor_back=8;//左电机后退(IN1)
intLeft_motor_go=9;//左电机前进(IN2)
intRight_motor_go=10;//右电机前进(IN3)
intRight_motor_back=11;//右电机后退(IN4)
intkey=12;//定义按键A2接口
intbeep=13;//定义蜂鸣器A3接口
constintSensorRight=3;//右循迹红外传感器(P3.2OUT1)
constintSensorLeft=4;//左循迹红外传感器(P3.3OUT2)
constintHongLeft=5;
constintHongRight=6;
intSL;//左循迹红外传感器状态
intSR;//右循迹红外传感器状态
intSL1;
intSR1;
intservopin=2;//设置舵机驱动脚到数字口2
intmyangle;//定义角度变量
intpulsewidth;//定义脉宽变量
intval;
voidsetup()
{
Serial.begin(9600);//初始化串口
//初始化电机驱动IO为输出方式
pinMode(Left_motor_go,OUTPUT);//PIN8(PWM)
pinMode(Left_motor_back,OUTPUT);//PIN9(PWM)
pinMode(Right_motor_go,OUTPUT);//PIN10(PWM)
pinMode(Right_motor_back,OUTPUT);//PIN11(PWM)
pinMode(key,INPUT);//定义按键接口为输入接口
pinMode(beep,OUTPUT);
pinMode(SensorRight,INPUT);//定义右循迹红外传感器为输入
pinMode(SensorLeft,INPUT);//定义左循迹红外传感器为输入
pinMode(HongLeft,INPUT);
pinMode(HongRight,INPUT);
//初始化超声波引脚
pinMode(Echo,INPUT);//定义超声波输入脚
pinMode(Trig,OUTPUT);//定义超声波输出脚
pinMode(servopin,OUTPUT);//设定舵机接口为输出接口
}
//=======================智能小车的基本动作=========================
voidstart()
{
inti;
for(i=0;i<80;i++)//输出一个频率的声音
{
digitalWrite(beep,HIGH);//发声音
delay
(1);//延时1ms
digitalWrite(beep,LOW);//不发声音
delay
(1);//延时ms
}
for(i=0;i<100;i++)//输出另一个频率的声音
{
digitalWrite(beep,HIGH);//发声音
delay
(2);//延时2ms
digitalWrite(beep,LOW);//不发声音
delay
(2);//延时2ms
}
for(i=0;i<100;i++)//输出另一个频率的声音
{
digitalWrite(beep,HIGH);//发声音
delay(3);//延时2ms
digitalWrite(beep,LOW);//不发声音
delay(3);//延时2ms
}
for(i=0;i<100;i++)//输出另一个频率的声音
{
digitalWrite(beep,HIGH);//发声音
delay(4);//延时2ms
digitalWrite(beep,LOW);//不发声音
delay(4);//延时2ms
}
}
voidrun()//前进
{
digitalWrite(Right_motor_go,HIGH);//右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,100);//PWM比例0~255调速,左右轮差异略增减
analogWrite(Right_motor_back,0);
digitalWrite(Left_motor_go,HIGH);//左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,97);//PWM比例0~255调速,左右轮差异略增减
analogWrite(Left_motor_back,0);
//delay(time*100);//执行时间,可以调整
}
voidbrake(inttime)//刹车,停车
{
digitalWrite(Right_motor_go,LOW);
digitalWrite(Right_motor_back,LOW);
digitalWrite(Left_motor_go,LOW);
digitalWrite(Left_motor_back,LOW);
delay(time*100);//执行时间,可以调整
}
voidleft(inttime)//左转(左轮不动,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);//右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,200);
analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);//左轮后退
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time*100);//执行时间,可以调整
}
voidspin_left(inttime)//左转(左轮后退,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);//右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,150);
analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);//左轮后退
digitalWrite(Left_motor_back,HIGH);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,150);//PWM比例0~255调速
delay(time*100);//执行时间,可以调整
}
voidright(inttime)
{
digitalWrite(Right_motor_go,LOW);//右电机后退
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH);//左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,200);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time*100);//执行时间,可以调整
}
voidspin_right(inttime)//右转(右轮后退,左轮前进)
{
digitalWrite(Right_motor_go,LOW);//右电机后退
digitalWrite(Right_motor_back,HIGH);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,150);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH);//左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,150);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time*100);//执行时间,可以调整
}
voidback(inttime)//后退
{
digitalWrite(Right_motor_go,LOW);//右轮后退
digitalWrite(Right_motor_back,HIGH);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,200);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);//左轮后退
digitalWrite(Left_motor_back,HIGH);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,200);//PWM比例0~255调速
delay(time*100);//执行时间,可以调整
}
//==========================================================
voidkeysacn()//按键扫描
{
intval;
val=digitalRead(key);//读取数字7口电平值赋给val
while(!
digitalRead(key))//当按键没被按下时,一直循环
{
val=digitalRead(key);//此句可省略,可让循环跑空
}
while(digitalRead(key))//当按键被按下时
{
delay(10);//延时10ms
val=digitalRead(key);//读取数字7口电平值赋给val
if(val==HIGH)//第二次判断按键是否被按下
{
digitalWrite(beep,HIGH);//蜂鸣器响
while(!
digitalRead(key))//判断按键是否被松开
digitalWrite(beep,LOW);//蜂鸣器停止
}
else
digitalWrite(beep,LOW);//蜂鸣器停止
}
}
floatDistance_test()//量出前方距离
{
digitalWrite(Trig,LOW);//给触发脚低电平2μs
delayMicroseconds
(2);
digitalWrite(Trig,HIGH);//给触发脚高电平10μs,这里至少是10μs
delayMicroseconds(10);
digitalWrite(Trig,LOW);//持续给触发脚低电
floatFdistance=pulseIn(Echo,HIGH);//读取高电平时间(单位:
微秒)
Fdistance=Fdistance/58;//为什么除以58等于厘米,Y米=(X秒*344)/2
//X秒=(2*Y米)/344==》X秒=0.0058*Y米==》厘米=微秒/58
returnFdistance;
}
voidservopulse(intservopin,intmyangle)/*定义一个脉冲函数,用来模拟方式产生PWM值*/
{
pulsewidth=(myangle*11)+500;//将角度转化为500-2480的脉宽值
digitalWrite(servopin,HIGH);//将舵机接口电平置高
delayMicroseconds(pulsewidth);//延时脉宽值的微秒数
digitalWrite(servopin,LOW);//将舵机接口电平置低
delay(20-pulsewidth/1000);//延时周期内剩余时间
}
voidfront_detection()
{
//此处循环次数减少,为了增加小车遇到障碍物的反应速度
for(inti=0;i<=5;i++)//产生PWM个数,等效延时以保证能转到响应角度
{
servopulse(servopin,90);//模拟产生PWM
}
Front_Distance=Distance_test();
}
voidleft_detection()//测试左侧距离
{
for(inti=0;i<=15;i++)//产生PWM个数,等效延时以保证能转到响应角度
{
servopulse(servopin,175);//模拟产生PWM
}
Left_Distance=Distance_test();
}
voidright_detection()
{
for(inti=0;i<=15;i++)//产生PWM个数,等效延时以保证能转到响应角度
{
servopulse(servopin,5);//模拟产生PWM
}
Right_Distance=Distance_test();
}
//===========================================================
voidloop()
{
start();
keysacn();//调用按键扫描函数
while
(1)
{SR=digitalRead(SensorRight);//有信号表明在白色区域,车子底板上L3亮;没信号表明压在黑线上,车子底板上L3灭
SL=digitalRead(SensorLeft);
SR1=digitalRead(HongRight);
SL1=digitalRead(HongLeft);
if(SL==LOW&&SR==LOW&&SL1==HIGH&&SR1==HIGH){
front_detection();//测量前方距离
if(Front_Distance<32)//当遇到障碍物时
{
back
(2);//后退减速
brake
(2);//停下来做测距
left_dete