机电一体化08实验八.docx
《机电一体化08实验八.docx》由会员分享,可在线阅读,更多相关《机电一体化08实验八.docx(39页珍藏版)》请在冰豆网上搜索。
机电一体化08实验八
实验八、C51输入/输出接口与红外导航
一、实验要求
了解红外传感器的工作原理,动手搭建红外电路,能够探测和避开障碍物;
改进程序,实现更可靠的壁障功能,可以尝试避开“悬崖”或者循线的功能;
对试验中出现的问题或现象进行总结,给出解释。
二、实验概要
1.搭建并测试IR发射和探测器对
了解红外发射与接收器的工作原理,搭建合适的电路,编写程序,对IR发射与探测器进行测试。
2.探测和避开障碍物
IR检测器没有检测到红外光时输出为高电平,这与触须的作用很类似。
那么,可以利用红外光的反射,检测有没有从障碍物反射回来的光线,就可以判断前方有无障碍物。
修改触须导航的程序,实现以上功能,要求能够检测到一定范围内的较大的障碍物,并避开。
3.高性能的IR导航
红外干扰测试,以及探测距离调整;
适当的修改程序,使小车行走过程更加流畅。
4.俯视的探测器可以做什么事情
原理同上,俯视的探测器可以探测前下方或者下方有无物体,这怎么用?
可以反着用——我要探测“没有物体”这种情况。
比如,小车在桌子边缘,为了不掉下去,就需要这做。
实验中用黑色绝缘带模拟这一种情况。
小车检测到绝缘带即表示到了桌子边缘,然后应该后退,以避免掉下去。
三、实验内容
如今最热门的产品看起来都有一个共性:
无线通信。
比如私人用户可以把数据无线传输到便携电脑,我们可以通过遥控自由选择频道。
许多远程控制和PDA使用频率低于可见光的红外线进行信号通信。
使用一些便宜且应用广泛的部件,MCS-51微控制器也可以收发红外光信号。
使用红外线前灯探测道路
不接触探测物体并不需要任何就像机器视觉那
样复杂的东西。
许多机器人使用雷达(RADAR)
或者声纳(SONAR)。
一个更简单的系统是使用红外
光来照射机器人的路线,然后确定何时有光线从目标
反射回来。
由于红外远程控制技术的发展,红外线
发射器和探测器已经很普及并且价格便宜。
红外前灯
我们在宝贝车机器人上建立的红外物体探测系统
在许多方面就像汽车的前灯。
当汽车前灯的射出的光
从障碍物体反射回来时,你的眼睛发现障碍物体,然后
你的大脑处理这些信息,并据此控制你的身体引导汽车。
宝贝车机器人使用红外线两极管LED作为前灯,如图8-1
所示。
他们发射红外光,在一些情况下,红外线从物体
反射从机器人前进的方向折回。
宝贝车机器人的眼睛是
红外检测器。
红外检测器发出信号来表明它们是否检测图8-1用红外光探测障碍物
到从物体反射回的红外线。
宝贝车机器人的大脑,MCS-51
微控制器据此做出判断并基于这个传感器的输入控制伺服IR检测器
电机。
IR(红外线)检测器有内置的光滤波器,除了需要IRLED
我们用它的内部的光敏二极管传感器检测的980nm红外
线,它几乎不允许其它光通过。
红外检测器也有一个电子
滤波器,它只允许大约38.5kHz的信号通过。
换句话说,
检测器只寻找每秒闪烁38,500次的红外光。
这就防
止了普通光源像太阳光和室内光对IR的干涉。
太阳光是
直流干涉(0Hz),室内光依赖于所在区域的主电源,闪烁IRLED套管
频率接近100或120Hz。
由于120Hz在电子滤波器的
38.5kHz通带频率之外,它完全被IR探测器忽略。
1.搭建并测试IR发射和探测器对图8-2本节需要的新部件
本实验中,你将搭建并测试红外线发射和检测器对。
元件清单:
(1)两个红外检测器
(2)两个IRLEDs
(3)两对IRLED套管
(4)两个220Ω电阻(红-红-棕)
(5)两个1kΩ电阻(棕-黑-红)
搭建红外线前灯
如图8−3所示,将红外LED插入套管。
图8−3将红外LED插入套管
d确保LED摁入到大的套管中。
d将小的套管套在LED上,并摁进大的圈里面。
电路板的每个角安装一个IR组(IRLED和检测器)。
图7-4所示是接线图。
d断开主板和伺服系统的电源。
d建立图8-4所示的电路,参考图7-4接线。
图8-4左侧和右侧IR组
1)测试红外发射探测器
本任务中,你要用P1_4发送持续1秒的38.5kHz的红外光,如果红外光被小车路径上的物体反射回来,红外检测器将给微控制器发送一个信号,让它知道已经检测到反射回的红外光。
让每个IRLED探测器组工作的关键是发送1ms频率为38.5kHz的红外信号,然后,立刻将IR探测器的输出存储到一个变量中。
下面是一个例子,它发送38.5kHz信号给连接到P1_4的IR发射器,然后用位变量irDetectLeft存储连接到P15的IR探测器的输出。
for(counter=0;counter<38;counter++)
{
P1_3=1;
delay_nus(13);
P1_3=0;
delay_nus(13);
}
irDetectLeft=P1_5state();
当没有IR信号返回时,探测器的输出状态为高。
当它探测到被物体反射的38500Hz和声时,它的输出为低。
当发送红外信号后,IR探测器的输出处于低状态不到1毫秒,因此当发送完后立即将IR探测器的输出存储到变量中是很重要的。
这些存储的值会显示在调试终端或被机器人用来导航。
例程:
TestLeftIrPair.c
d打开主板的电源。
d输入、保存并运行程序TestLeftIrPair.c。
#include
#include
intP1_6tate(void)
{
return(P1&0x40)?
1:
0;
}
intmain(void)
{
intirDetectLeft;
uart_Init();
printf("ProgramRunning!
");
for(counter=1;counter<=1000;counter++)//开始/复位信号
{
P1_3=1;
delay_nus(1000);
P1_3=0;
delay_nus(1000);
}
while
(1)
{
for(counter=0;counter<38;counter++)
{
P1_5=1;
delay_nus(13);
P1_5=0;
delay_nus(13);
}
irDetectLeft=P1_6state();
printf("irDetectLeft=%d\n",irDetectLeft);
delay_nms(100);
}
}
保持宝贝车机器人与串口电缆的连接,因为你将用调式终端来测试你的IR组。
放一个物体,比如手或一张纸,距离左侧IR组大约1英寸,参考图8-1。
验证当你放一个物体在IR组前时,调试终端是否会显示0,当你将物体移开时,它是否显示1。
如果调试终端显示的是预料的值,没发现物体显示1,发现物体显示0,你可以测试另一对红外。
如果调试终端显示的不是预料的值,试试排错部分里的步骤进行排错。
Tips:
排错
d如果调试终端显示的不是预料的值,检查电路和输入的程序。
d如果你总是得到0,甚至当没有物体在宝贝车前面时也是0,可能是附近的物体反射了红外线。
宝贝车前面的桌面是常见的始作俑者。
移动小车,使IRLED和探测器不可能受附近物体的影响。
d如果宝贝车前面没有物体时绝大多数时间读数是1,但是偶尔是0,这可能是附近
的荧光灯的干扰。
关掉附近的荧光灯,重新测试
2)函数延时的不精确性
如果你有数字示波器,或许到这里你已经注意到P1_4产生的方波的频率并不是125.5K,也就是说延时13us并不是真的延时了13us,而是更长。
这是为什么么呢,主要是由于函数调用过程产生了延时。
函数调用时,CPU会先进行一系列的堆栈操作,这些操作时需要时间的,至少几个us,而我们现在延时也是us级,这就造成了延时的不精确性。
怎么办呢,有没有更精确的方法呢?
这里介绍一种常用的延时方法,这在实际工程中用的非常广泛:
for(i=0;i<1;i++){;}
这是一个for空操作语句,它什么也不做,但能产生延时。
我们可以用示波器测量,它能产
生约12us延时。
for(i=0;i<2;i++){;}//延时25us
for(i=0;i<125;i++){;}//延时1ms左右
还有很多方法,比如使用中断,汇编等等,不过实现这个功能,不推荐使用中断,太浪费了,而且不理想。
因为假设用中断延时的话,在延时过程中,CPU什么也做不了。
中断通常用在实时操作RTOS(Real-TimeOperatingSystem)系统中。
3)右红外测试
d将程序TestLeftIrPair.c另存为TestRightIrPair.c。
更改名称和注释使适合于右侧IR组。
(即把注释for语句变成程序,而delay()变为注释)
还有其他一些变量需要修改,自己找出来。
2.探测和避开障碍物
有关IR检测器的一个有趣的事是它们的输出与触须的输出非常相象。
没有检测到物体时,输出为高,检测到物体时,输出为低。
本任务中,更改程序RoamingWithWhiskers.c使它适用于IR检测器。
下一个例子程序开始于RoamingWithWhiskers.c。
更改旁边的名称和描述,加入两个位变量来存储IR检测器的状态。
intirDetectLeft
intirDetectRight
调用一个函数IRLaunch()来读IR组的状态。
intIRLaunch(unsignedcharIR)
{
unsignedintcounter;
if(IR=='L')
for(counter=0;counter<1000;counter++)
{
LeftLaunch=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
LeftLaunch=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
else
for(counter=0;counter<1000;counter++)//右边发射
{
RightLaunch=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
RightLaunch=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
修改if…else语句检查存储IR检测信息的变量。
if((irDetectLeft==0)&&(irDetectRight==0))//两边同时接收到红外线
{
Backward();
Left_Turn();
Left_Turn();
}
elseif(irDetectLeft==0)//只有左边接收到红外线
{
Backward();
Right_Turn();
}
elseif(irDetectRight==0)//只有右边接收到红外线
{
Backward();
Left_Turn();
}
else
Forward();
例程――RoamingWithIr.c
d打开程序RoamingWithWhiskers.c。
d更改程序使它与下面程序相同。
d打开主板和伺服电机的电源。
d保存并运行程序。
d验证宝贝车的行为和运行程序RoamingWithWhiskers.c时除了不需接触是否非常相象。
#include
#include
#include
#defineLeftIRP1_6//左边红外接收连接到P15
#defineRightIRP2_3//右边红外接收连接到P36
#defineLeftLaunchP1_5//左边红外发射连接到P14
#defineRightLaunchP2_4//右边红外发射连接到P35
intIRLaunch(unsignedcharIR)
{
unsignedintcounter;
if(IR=='L')
for(counter=0;counter<1000;counter++)
{
LeftLaunch=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
LeftLaunch=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
else
for(counter=0;counter<1000;counter++)//右边发射
{
RightLaunch=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
RightLaunch=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
voidForward(void)//向前行走子程序
{
P1_1=1;
delay_nus(1700);
P1_1=0;
P1_0=1;
delay_nus(1300);
P1_0=0;
delay_nms(20);
}
voidLeft_Turn(void)//左转子程序
{
inti;
for(i=1;i<=26;i++)
{
P1_1=1;
delay_nus(1300);
P1_1=0;
P1_0=1;
delay_nus(1300);
P1_0=0;
delay_nms(20);
}
}
voidRight_Turn(void)//右转子程序
{
inti;
for(i=1;i<=26;i++)
{
P1_1=1;
delay_nus(1700);
P1_1=0;
P1_0=1;
delay_nus(1700);
P1_0=0;
delay_nms(20);
}
}
voidBackward(void)//向后行走子程序
{
inti;
for(i=1;i<=65;i++)
{
P1_1=1;
delay_nus(1300);
P1_1=0;
P1_0=1;
delay_nus(1700);
P1_0=0;
delay_nms(20);
}
}
intmain(void)
{
bitirDetectLeft,irDetectRight;
inti,counter;
uart_Init();
printf("ProgramRunning!
\n");
for(counter=1;counter<=1000;counter++)//开始/复位信号
{
P1_3=1;
delay_nus(1000);
P1_3=0;
delay_nus(1000);
}
while
(1)
{
IRLaunch('R');
irDetectRight=RightIR;//右边接收
IRLaunch('L');
irDetectLeft=LeftIR;//左边接收
if((irDetectLeft==0)&&(irDetectRight==0))//两边同时接收到红外线
{
Backward();
Left_Turn();
Left_Turn();
}
elseif(irDetectLeft==0)//只有左边接收到红外线
{
Backward();
Right_Turn();
}
elseif(irDetectRight==0)//只有右边接收到红外线
{
Backward();
Left_Turn();
}
else
Forward();
}
}
3.高性能的IR导航
1)物体检测状态显示
本实验中,你将制作并测试LED指示器,它将告诉你是否检测到物体,而不需要调试终端的帮助。
如果你不在电脑旁边,这将很方便,你可以用此来排除你的IR检测电路的故障。
你需要写一个程序来发现来自荧光灯的红外干涉。
许多荧光灯发射的信号类似你的IRLED发射的信号。
荧光灯内部控制电压的部件叫镇流器。
许多镇流器和你的IR探测器的工作在相同的频率范围,38.5kHz左右,这就会导致荧光灯发射同样频率的信号。
所以当你用集成的红外线探测器导航时,这些干扰可能导致许多奇异的宝贝车车行为!
重新搭建LED指示电路
这里用到的是和前面“胡须”中用到的同样的LED指示器。
元件清单:
(1)红色LEDs
(2)220Ω电阻(红-红-棕)
图8-5左侧和右侧LEDs指示电路
d
断开主板和伺服系统的电源。
d参考图8-5,建立接线电路
本系统包括许多元件,这就增加了接线错误的可能性。
因此有一个测试程序是很重要的。
测试程序告诉你红外检测器检测到什么。
从串口电缆上拔掉机器人测试其它障碍物体之前,你可以用这个程序来验证所有的电路是否正常工作。
例程――TestIrPairsAndIndicators.c
d接通主板的电源。
d输入、保存并运行程序TestIrPairsAndIndicators.c。
d可以加入输出语句“printf()”,用调试终端来验证当放一个物体在检测器前面时,微控制器是否仍然从每个IR检测器发出收到信号0。
d验证当检测器检测到物体时,每个检测器旁的LED是否会发光。
如果一个或两个
LED不能工作,检查接线和程序。
#include
#include
intP1_5state(void)
{
return(P1&0x20)?
1:
0;
}
intP3_6state(void)
{
return(P3&0x40)?
1:
0;
}
intmain(void)
{
intirDetectLeft,irDetectRight;
uart_Init();
printf("ProgramRunning!
");
for(counter=1;counter<=1000;counter++)//开始/复位信号
{
P1_3=1;
delay_nus(1000);
P1_3=0;
delay_nus(1000);
}
while
(1)
{
for(counter=0;counter<125;counter++)
{
P1_4=1;
P3_5=0;
for(i=0;i<1;i++){;}
P1_4=0;
P3_5=0;
for(i=0;i<1;i++){;}
}
irDetectLeft=P1_5state();
irDetectRight=P3_6state();
if(irDetectLeft==0)
P1_2=1;
else
P1_2=0;
if(irDetectRight==0)
P3_4=1;
else
P3_4=0;
delay_nms(100);
}
}
该你了――远程测试和范围测试
现在你可以用LED指示器,拿开你的宝贝车并用IR探测器来探测不在你的串口电缆长度范围之内的目标。
拔掉连接在宝贝车机器人上的串口电缆,将其放到几个不同的物体之前,以测试IR探测器的范围。
测试对不同颜色物体的探测范围,对什么颜色的物体探测的范围最远,什么颜色的物体探测的范围最近?
2)探测红外线干扰
如果你偶尔注意到即使检测范围内没有任何物体,你的宝贝车机器人指示探测到了物体,这说明附近的灯光正产生频率接近38.5kHz的红外光。
如果你想在这种灯光下进行机器人比赛或演示,你的红外系统可能会停止工作。
每个人最终的想法都是让自己的机器人在公开演示时不要出错,因此在动手做演示之前,用这个红外线干涉探测程序仔细检查任何要演示宝贝车的区域是有必要的。
程序的原理很简单,不用IRLED发送任何红外光,只是监控有没有检测到红外光,如果检测到红外光,用扬声器发出警报。
例程――IrInterferenceSniffer.c
d输入、保存并运行程序IrInterferenceSniffer.c。
d测试验证当机器人检测到IR干扰时,发出警报声。
你可以单独用一个宝贝车来运行程序TestIrPairsAndIndicators.c。
如果没有多余的宝贝车,就用TV、VCR、CD/DVD机或放映机的手持式遥控器对着宝贝车机器人按一个键。
如果宝贝车发出警报声,就可以知道宝贝车的探探器处于工作状态。
#include
#include
intP1_5state(void)
{
return(P1&0x20)?
1:
0;
}
intP3_6state(void)
{
return(P3&0x40)?
1:
0;
}
intmain(void)
{
uart_Init();
printf("ProgramRunning!
\n");
while
(1)
{
if((P1_5state()==0)||(P3_6state()==0))
{
for(counter=1;counter<=150;counter++)
{
P1_3=1;
delay_nus(1000);
P1_3=0;
delay_nus(1000);
}
}
delay_nms(30);;
}
}
该你了――测试荧光灯干扰
断开宝贝车和串口电缆的连接,将它指向附近任何荧光灯。
如果你听到频繁地警报,在准备使用IR物体检测器之前关掉荧光灯。
3)红外检测范围调整
(1)串联电阻与LED亮度
你可能已经注意到在环境很黑的时候,亮一些的汽车灯可以看到更远一些的物体。
通过使宝贝车的前灯更亮,你也可以增加它的检测范围。
更小的电阻使通过LED的电流更多。
更多的电流使LED更亮。
本任务中,你将检测LED和IRLED串不同电阻值的效果。
元件清单:
本节中需要一些特殊的部件: