智能小车2-循迹小车

TCRT5000

TCRT5000传感器的红外发射二级管可以不断发射红外线

当发射出的红外线 没有 被反射回来或被反射回来但强度不够大时, 红外接收管一直处于关断状态,此时 模块的输出端为高电平 ,指示二极管一直处于 熄灭状态
被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,红外接收管饱和,
此时 模块的输出端为低电平 ,指示 二极管被点亮
总结就是:  反射的强度不够时,DO为高,开关指示灯不亮;反之DO为低,开关指示灯亮

 

 接线方式:

VCC -> 电源正

GND -> 电源负

DO -> TTL开关信号输出0或1

AO -> 模拟信号输出(不同距离输出不同的电压,此脚可以不接)

循迹小车原理

根据上述模块了解可知,TCRT5000的DO和灯会根据红外线的反射强度而变化,而查阅资料可知: 由于黑色具有较强的吸收能力,当循迹模块发射的红外线照射到 黑线 时,红外线将会被黑线吸收,导致循迹模块上光敏三极管处于关闭状态, DO输出高电平且 模块上一个LED熄灭。在没有检测到黑线时,模块上两个LED常亮。
总结就是一句话,有感应到黑线,D0输出高电平 ,灭灯。
将传感器固定在小车上后编写代码:

循迹小车的编程实现

main.c

#include "reg52.h"
#include <intrins.h>
#include <delay.h>
#include <motor.h>

sbit Left_Sensor = P2^4;
sbit Right_Sensor = P2^5;

sbit led2 = P3^6;//根据原理图(电路图),设备变量led2指向P3组IO口的第6口


void main()
{
	while(1)
		{
//			
//			下方小车两个模块都能反射回来红外,输出低电平,灯亮,直走
//			上方小车左模块遇到黑线,红外被吸收,左模块输出高电平,右模块输出低电平,左转,反之右转
			if(Left_Sensor == 0 && Right_Sensor == 0)
			{
				Motor_front();//前
			}
			Delay1000ms();
			if(Left_Sensor == 1 && Right_Sensor == 0)
			{
				Motor_Left();//左转
			}
			Delay1000ms();
			if(Left_Sensor == 0 && Right_Sensor == 1)
			{
				Motor_Right();//右转 
			}
			Delay1000ms();
			if(Left_Sensor == 1 && Right_Sensor == 1)
			{
				Motor_Stop();
			}

		}

}

1. 由于我的桌面是黑色的,所以如果不用白纸,那么就模拟了不在轨道上轮子不会动

2. 当白纸遮挡了左边传感器,就相当于右侧检测到黑线,模拟了小车向左偏离了轨道,需要右转修正,因此只有左轮动;

3.  当白纸遮挡了右边传感器,就相当于左侧检测到黑线,模拟了小车向右偏离了轨道,需要左转修正,因此只有右轮动;

4. 当白纸同时遮挡了两个传感器,就相当于黑线在传感器之间,模拟了小车正常行驶,需要直行,所以左右轮一起转动;

实际循迹中的问题

这样乍一看似乎已经成功实现了,然而其实有些问题:当我在轨道上试运行的时候,小车还是会经常性的跑离轨道,这就是小车的速度和灵敏度的配合问题了:用螺丝刀调整传感器的灵敏度(顺时针变灵敏逆时针变迟钝)并使用之前两轮分别进行调速的代码对左右轮进行微调,我修改代码让两个定时器分别控制左右轮

timer.c

#include <motor.h>
#include "reg52.h"


char speedLeft;
char cntLeft = 0;

char speedRight;
char cntRight = 0;

void Time0Init()
{
	//1.配置定时器0工作模式为16位计时
	TMOD &= 0xF0;
	TMOD |= 0x01;
	//2.给初值,定一个500us=0.5ms出来
	TL0 = 0x33;				//设置定时初始值
	TH0 = 0xFE;	
	//3、开始计时
	TR0 = 1;
	TF0 = 0;	
	//4.打开定时器0中断 ET0
	ET0 = 1;
	//5.打开总中断EA
	EA = 1;
}

void Time1Init()
{
	//1.配置定时器1工作模式为16位计时
	TMOD &= 0x0F;
	TMOD |= 0x10;
	//2.给初值,定一个500us=0.5ms出来
	TL1 = 0x33;				//设置定时初始值
	TH1 = 0xFE;	
	//3、开始计时
	TR1 = 1;
	TF1 = 0;	
	//4.打开定时器1中断 ET0
	ET1 = 1;
	//5.打开总中断EA
	EA = 1;
}




void Time1_Handler() interrupt 3
{

	cntRight++;//统计爆表的次数
	//重新给初值
	TL1 = 0x33;			
	TH1 = 0xFE;	
	
	//控制pwm波形
	if(cntRight < speedRight)
	{
		//右前进
		Motor_forward_right();
	}
	else
	{
		//右停止
		Motor_stop_right();
	}
	
	if(cntRight == 40)//爆表40次,经过了20ms
	{
		cntRight = 0;//当40次表示20ms,重新让cnt从0开始,计算下一次的20ms
 		
	}

	
}


void Time0_Handler() interrupt 1
{
	/*
//	if(TF0 == 1)//当爆表的时候,硬件会修改bit5(TF0)位上面的数据,改成1(置1),向cpu请求中断
//		{
//			TF0 = 0;//不用中断,我们代码清零
	使用了中断,直接清零了的*/
	cntLeft++;//统计爆表的次数
	//重新给初值
	TL0 = 0x33;			
	TH0 = 0xFE;	
	
	//控制pwm波形
	if(cntLeft < speedLeft)
	{
		//左前进
		Motor_forward_left();
	}
	else
	{
		//左停止
		Motor_stop_left();
	}
	
	if(cntLeft == 40)//爆表40次,经过了20ms
	{
		cntLeft = 0;//当40次表示20ms,重新让cnt从0开始,计算下一次的20ms
 		
	}
//}
	
	
}

main.c

#include "reg52.h"
#include <delay.h>
#include <motor.h>
#include <uart.h>
#include <Timer.h>

sbit led2 = P3^6;//根据原理图(电路图),设备变量led2指向P3组IO口的第6口
sbit Left_Sensor = P2^4;
sbit Right_Sensor = P2^5;

extern char speedLeft;
extern char speedRight;
void main()
{
	Time0Init();
	Time1Init();
	UartInit();
	while(1)
		{
			if(Left_Sensor == 0 && Right_Sensor == 0)
			{
				speedLeft = 40;
				speedRight = 40;
			}
			Delay1000ms();
			if(Left_Sensor == 1 && Right_Sensor == 0)
			{
				speedLeft = 10;//10份单位时间全速运行,30份停止,所以慢,20ms是40份的500us
				speedRight = 40;
			}
			Delay1000ms();
			if(Left_Sensor == 0 && Right_Sensor == 1)
			{
				speedLeft = 40;
				speedRight = 10;
			}
			Delay1000ms();
			if(Left_Sensor == 1 && Right_Sensor == 1)
			{
				speedLeft = 0;
				speedRight = 0;
			}

			
		}

} 

 PS:可以看到,经过调整过后小车行驶过程中其实还是不太平滑,那么其实细化平滑的方法也不难,方法之一就是细化PWM波,现在调整PWM波的最小单位是0.5ms,如果减小这个时间,理论上就可以更加细化的调整速度。

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值